手写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>
  <!-- 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>
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">
 <context:component-scan base-package="xuyuedu.service"></context:component-scan>
 <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>
 <!-- 2. JdbcTemplate工具类实例 -->
 <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" /> -->

</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;
//事务注解 设置传播行为
@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 xuyuedu.annotation.XuyuTransaction;
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);

  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;
//编程事务
@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);
 }
}

猜你喜欢

转载自blog.csdn.net/qq_38357267/article/details/80377782