SpringAOP 的三种实现方式

互联网 20-7-21

引入aop相关的jar包

<dependency>   <groupId>org.springframework</groupId>   <artifactId>spring-aop</artifactId>   <version>5.1.12.RELEASE</version> </dependency>  <dependency>   <groupId>org.aspectj</groupId>   <artifactId>aspectjweaver</artifactId>   <version>1.9.4</version> </dependency>

TransferServiceImpl.java文件:

package com.lagou.edu.service.impl; import com.lagou.edu.dao.AccountDao; import com.lagou.edu.pojo.Account; import com.lagou.edu.service.TransferService; import com.lagou.edu.utils.ConnectionUtils; import com.lagou.edu.utils.TransactionManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.ImportResource; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; /**  * @author 应癫  */ @Service("transferService") public class TransferServiceImpl implements TransferService {   // 最佳状态   // @Autowired 按照类型注入 ,如果按照类型无法唯一锁定对象,可以结合@Qualifier指定具体的id   @Autowired   @Qualifier("accountDao")   private AccountDao accountDao;    @Override   public void transfer(String fromCardNo, String toCardNo, int money) throws Exception {     /*try{       // 开启事务(关闭事务的自动提交)       TransactionManager.getInstance().beginTransaction();*/       System.out.println("执行转账业务逻辑");       Account from = accountDao.queryAccountByCardNo(fromCardNo);       Account to = accountDao.queryAccountByCardNo(toCardNo);       from.setMoney(from.getMoney()-money);       to.setMoney(to.getMoney()+money);       accountDao.updateAccountByCardNo(to);       //int c = 1/0;       accountDao.updateAccountByCardNo(from);   } }

打印日志Util:

package com.lagou.edu.utils;  /**  * @author 应癫  */  public class LogUtils {    /**    * 业务逻辑开始之前执行    */      public void beforeMethod(JoinPoint joinPoint) {      Object[] args = joinPoint.getArgs();     for (int i = 0; i < args.length; i++) {       Object arg = args[i];       System.out.println(arg);     }     System.out.println("业务逻辑开始执行之前执行.......");   }     /**    * 业务逻辑结束时执行(无论异常与否)    */    public void afterMethod() {     System.out.println("业务逻辑结束时执行,无论异常与否都执行.......");   }    /**    * 异常时时执行    */   public void exceptionMethod() {     System.out.println("异常时执行.......");   }    /**    * 业务逻辑正常时执行    */    public void successMethod(Object retVal) {     System.out.println("业务逻辑正常时执行.......");   }  }  public Object arroundMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {     System.out.println("环绕通知中的beforemethod....");      Object result = null;     try{       // 控制原有业务逻辑是否执行       // result = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());     }catch(Exception e) {       System.out.println("环绕通知中的exceptionmethod....");     }finally {       System.out.println("环绕通知中的after method....");     }      return result;   }

applicationContext.xml

<!--进行aop相关的xml配置,配置aop的过程其实就是把aop相关术语落地-->   <!--横切逻辑bean--> <bean id="logUtils" class="com.lagou.edu.utils.LogUtils"></bean>   <!--使用config标签表明开始aop配置,在内部配置切面aspect-->    <!--aspect  =  切入点(锁定方法) + 方位点(锁定方法中的特殊时机)+ 横切逻辑 -->   <aop:config>     <aop:aspect id="logAspect" ref="logUtils">        <!--切入点锁定我们感兴趣的方法,使用aspectj语法表达式-->       <!--..参数中的两个点表示可以有参数,也可以没有参数,有的话也可以是任意类型,参数中的 *表示参数可以是任意类型,但必须有参数。 -->       <!--包名中的..两个点表示中间可以是任意层-->       <!--<aop:pointcut id="pt1" expression="execution(* *..*.*(..))"/>-->      <aop:pointcut id="pt1" expression="execution(public void com.lagou.edu.service.impl.TransferServiceImpl.transfer(java.lang.String,java.lang.String,int))"/>  <!--      <aop:pointcut id="pt1" expression="execution(* com.lagou.edu.service.impl.TransferServiceImpl.*(..))"/> -->       <!--方位信息,pointcut-ref关联切入点-->       <!--aop:before前置通知/增强-->       <aop:before method="beforeMethod" pointcut-ref="pt1"/>       <!--aop:after,最终通知,无论如何都执行-->       <!--aop:after-returnning,正常执行通知,retValue是接受方法的返回值的-->       <aop:after-returning method="successMethod" returning="retValue"/>       <!--aop:after-throwing,异常通知-->        <aop:around method="arroundMethod" pointcut-ref="pt1"/>      </aop:aspect>   </aop:config>-->

测试:

 /**    * 测试xml aop    */   @Test   public void testXmlAop() throws Exception {     ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");     TransferService transferService = applicationContext.getBean(TransferService.class);     transferService.transfer("6029621011000","6029621011001",100);   }

环绕通知不和前置及后置通知一起使用,因为环绕通知可以实现前置和后置的功能,并且可以控制原有业务逻辑是否执行,非常强大。

XML+注解方式

package com.lagou.edu.utils;  import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component;  /**  * @author 应癫  */ @Component @Aspect public class LogUtils {     @Pointcut("execution(* com.lagou.edu.service.impl.TransferServiceImpl.*(..))")   public void pt1(){    }     /**    * 业务逻辑开始之前执行    */   @Before("pt1()")   public void beforeMethod(JoinPoint joinPoint) {     Object[] args = joinPoint.getArgs();     for (int i = 0; i < args.length; i++) {       Object arg = args[i];       System.out.println(arg);     }     System.out.println("业务逻辑开始执行之前执行.......");   }     /**    * 业务逻辑结束时执行(无论异常与否)    */   @After("pt1()")   public void afterMethod() {     System.out.println("业务逻辑结束时执行,无论异常与否都执行.......");   }     /**    * 异常时时执行    */   @AfterThrowing("pt1()")   public void exceptionMethod() {     System.out.println("异常时执行.......");   }     /**    * 业务逻辑正常时执行    */   @AfterReturning(value = "pt1()",returning = "retVal")   public void successMethod(Object retVal) {     System.out.println("业务逻辑正常时执行.......");   }     /**    * 环绕通知    *    */   /*@Around("pt1()")*/   public Object arroundMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {     System.out.println("环绕通知中的beforemethod....");      Object result = null;     try{       // 控制原有业务逻辑是否执行       // result = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());     }catch(Exception e) {       System.out.println("环绕通知中的exceptionmethod....");     }finally {       System.out.println("环绕通知中的after method....");     }      return result;   }  }

在application.xml中配置注解驱动:

 <!--开启aop注解驱动     proxy-target-class:true强制使用cglib    -->   <aop:aspectj-autoproxy/>

纯注解模式

 <!--开启aop注解驱动     proxy-target-class:true强制使用cglib    -->   <aop:aspectj-autoproxy/>

改为 @EnableAspectJAutoProxy //开启spring对注解AOP的⽀持,在项目中添加到任意个配置类上即可。

推荐教程:《Java教程》

以上就是SpringAOP 的三种实现方式的详细内容,更多内容请关注技术你好其它相关文章!

来源链接:
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
标签: SpringAOP
上一篇:php获取远程图片并下载保存到本地的方法分析 下一篇:Java Mybatis 中的 ${ } 和 #{ } 的区别

相关资讯