手写spring框架自定义注解
不多说:上图-->
1.在pom.xml中引入依赖关系:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xuyuedu</groupId>
<artifactId>xuyuedu_day_01_springAop</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- 引入Spring-AOP等相关Jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1_2</version>
</dependency>
<modelVersion>4.0.0</modelVersion>
<groupId>com.xuyuedu</groupId>
<artifactId>xuyuedu_day_01_springAop</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- 引入Spring-AOP等相关Jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1_2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
</dependencies>
</project>
2.配置spring:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="xuyuedu.service"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy> <!-- 开启事物注解 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy> <!-- 开启事物注解 -->
<!-- 1. 数据源对象: C3P0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!-- 2. JdbcTemplate工具类实例 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 3.配置事务 -->
<bean id="dataSourceTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开启原生注解事务 -->
<!-- <tx:annotation-driven transaction-manager="dataSourceTransactionManager" /> -->
<bean id="dataSourceTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开启原生注解事务 -->
<!-- <tx:annotation-driven transaction-manager="dataSourceTransactionManager" /> -->
</beans>
3.Service和Dao:
4.自定义注解:
package xuyuedu.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//事务注解 设置传播行为
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface XuyuTransaction {
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface XuyuTransaction {
}
5.在aop中实现自定义注解具体实现:
package xuyuedu.aop;
import java.lang.reflect.Method;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import xuyuedu.annotation.XuyuTransaction;
import xuyuedu.transaction.TransactionUtils;
import xuyuedu.transaction.TransactionUtils;
//自定义事务注解具体的实现
@Aspect//定义切面
@Component//注入到spring容器中去
public class AopXuyuTransaction {
@Autowired
private TransactionUtils transactionUtils;
//使用异常通知进行回滚事务
@AfterThrowing("execution(* xuyuedu.Service.*.*.*(..))")
public void afterThrowing(ProceedingJoinPoint pjp) throws Exception, SecurityException{
System.out.println("回滚事务");
//获取当前事务,直接回滚
//判断异常方法是否有事务注解
XuyuTransaction xuyu = getMethodXuyuTransaction(pjp);
TransactionStatus begin = begin(xuyu);
//没有事务就返回
if(begin==null){
return;
}
//如果有就回滚
transactionUtils.rollback();
}
//环绕通知
@Around("execution(* xuyuedu.Service.*.*.*(..))")//环绕通知,在方法之前和之后处理事情
public void around(ProceedingJoinPoint pjp) throws Throwable{
//1.获取到代理对象的方法
XuyuTransaction xuyu = getMethodXuyuTransaction(pjp);
//2.获取该方法上是否加上注解
TransactionStatus transactionStatus = begin(xuyu);
//4.调用目标代理对象方法
pjp.proceed();
//5.判断该方法上是否加上注解
commit(transactionStatus);
}
private TransactionStatus begin(XuyuTransaction xuyu){
if(xuyu==null){
return null;
}
//3.如果有事务注解,开启事务
return transactionUtils.begin();
}
private void commit(TransactionStatus transactionStatus){
if(transactionStatus!=null){
transactionUtils.commit(transactionStatus);
}
}
private XuyuTransaction getMethodXuyuTransaction(ProceedingJoinPoint pjp) throws NoSuchMethodException, SecurityException{
//1.获取到代理对象的方法
String methodName = pjp.getSignature().getName();
// 获取目标对象
Class<?> classTarget = pjp.getTarget().getClass();
// 获取目标对象类型
Class<?>[] par = ((MethodSignature) pjp.getSignature()).getParameterTypes();
// 获取目标对象方法
Method objMethod = classTarget.getMethod(methodName, par);
XuyuTransaction xuyu = objMethod.getAnnotation(XuyuTransaction.class);
@Aspect//定义切面
@Component//注入到spring容器中去
public class AopXuyuTransaction {
@Autowired
private TransactionUtils transactionUtils;
//使用异常通知进行回滚事务
@AfterThrowing("execution(* xuyuedu.Service.*.*.*(..))")
public void afterThrowing(ProceedingJoinPoint pjp) throws Exception, SecurityException{
System.out.println("回滚事务");
//获取当前事务,直接回滚
//判断异常方法是否有事务注解
XuyuTransaction xuyu = getMethodXuyuTransaction(pjp);
TransactionStatus begin = begin(xuyu);
//没有事务就返回
if(begin==null){
return;
}
//如果有就回滚
transactionUtils.rollback();
}
//环绕通知
@Around("execution(* xuyuedu.Service.*.*.*(..))")//环绕通知,在方法之前和之后处理事情
public void around(ProceedingJoinPoint pjp) throws Throwable{
//1.获取到代理对象的方法
XuyuTransaction xuyu = getMethodXuyuTransaction(pjp);
//2.获取该方法上是否加上注解
TransactionStatus transactionStatus = begin(xuyu);
//4.调用目标代理对象方法
pjp.proceed();
//5.判断该方法上是否加上注解
commit(transactionStatus);
}
private TransactionStatus begin(XuyuTransaction xuyu){
if(xuyu==null){
return null;
}
//3.如果有事务注解,开启事务
return transactionUtils.begin();
}
private void commit(TransactionStatus transactionStatus){
if(transactionStatus!=null){
transactionUtils.commit(transactionStatus);
}
}
private XuyuTransaction getMethodXuyuTransaction(ProceedingJoinPoint pjp) throws NoSuchMethodException, SecurityException{
//1.获取到代理对象的方法
String methodName = pjp.getSignature().getName();
// 获取目标对象
Class<?> classTarget = pjp.getTarget().getClass();
// 获取目标对象类型
Class<?>[] par = ((MethodSignature) pjp.getSignature()).getParameterTypes();
// 获取目标对象方法
Method objMethod = classTarget.getMethod(methodName, par);
XuyuTransaction xuyu = objMethod.getAnnotation(XuyuTransaction.class);
return xuyu;
}
}
}
}
6.在transaction中配置spring事务处理机制:
package xuyuedu.transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
//编程事务
@Component//注入到springbean容器中
@Scope("Prototype")//设置原型的,那么每个事务就是新的实例 目的是为了解决线程安全问题 多例的
public class TransactionUtils {
@Component//注入到springbean容器中
@Scope("Prototype")//设置原型的,那么每个事务就是新的实例 目的是为了解决线程安全问题 多例的
public class TransactionUtils {
//定义全局标志,
private TransactionStatus transactionStatus;
//获取数据源
@Autowired
private DataSourceTransactionManager dataSourceTransactionManager;
//开启事务
public TransactionStatus begin(){
System.out.println("开启事务");
TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
return transaction;
}
//提交事务
public void commit(TransactionStatus transaction){
System.out.println("提交事务");
dataSourceTransactionManager.commit(transaction);
}
//回滚事务
public void rollback(){
System.out.println("回滚事务");
dataSourceTransactionManager.rollback(transactionStatus);
}
}
private TransactionStatus transactionStatus;
//获取数据源
@Autowired
private DataSourceTransactionManager dataSourceTransactionManager;
//开启事务
public TransactionStatus begin(){
System.out.println("开启事务");
TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
return transaction;
}
//提交事务
public void commit(TransactionStatus transaction){
System.out.println("提交事务");
dataSourceTransactionManager.commit(transaction);
}
//回滚事务
public void rollback(){
System.out.println("回滚事务");
dataSourceTransactionManager.rollback(transactionStatus);
}
}