zoukankan      html  css  js  c++  java
  • Spring 注解@AspectJ方式实现AOP

    1. Spring AOP介绍

    Spring 提供了很多的实现AOP的方式,有Spring 接口方式,schema配置方式和注解的三种,从Spring 2.0开始,可以使用基于schema及@AspectJ的方式来实现AOP,本文以一个简单的实例介绍了如何以@AspectJ方式在Spring中实现AOP。由于@Aspect是基于注解的,因此要求支持注解的5.0版本以上的JDK。

    2.Spring AOP环境

    要在项目中使用Spring AOP 则需要在项目中导入除了spring jar包之外,还有aspectjweaver.jar,aspectjrt.jar 和cglib.jar 。

    在Spring MVC基本上只需另外加上aspectjweaver.jar和cglib.jar就可以了。如下:

     <!-- AspectJ AOP -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>${aspectj.version}</version>
    </dependency>
    
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>${cglib.version}</version>
    </dependency>

    3. 实例

    这个实例是利用AOP实现对执行方法的执行后增强,即在执行目标方法后执行一段我们写好的方法,对相关数据进行处理。

    a.spring.xml配置

     <!-- 启用AspectJ AOP注解 -->
     <aop:aspectj-autoproxy/>

    b.目标方法代码

    public ResponseMsg submitResult(int task_id, long batch, byte result) {
            try {
                if (result < 0 || result > 1){
                    log.info("result参数非法,result:" + result);
                    return new ResponseMsg(ARGUMENT);
                }
                taskDao.updateTaskRes(task_id,batch,(byte)5,null,result);
                return new ResponseMsg(SUCCESS);
            } catch (Exception e){
                e.printStackTrace();
                log.error(e.getMessage());
                return new ResponseMsg(FAILURE);
            }
        }

    c.环绕增强的@AspectJ代码

    @Aspect
    @Component
    public class QualityCheckInterceptor {
    
        private static final Logger log = LoggerFactory.getLogger(QualityCheckInterceptor.class);
    
       @AfterReturning(pointcut = "execution(* com.iflytek.service.Impl.QualityCheckServiceImpl.submitResult(..)) && args(*,batch,..)")
        public void checkState(long batch){
            try {
                Integer count = taskDao.getCount(null,null,batch,(byte) 4,null);
                if (count > 0){return;
                }
                Integer correct = taskDao.getCount(null,null,batch,null,(byte)1);
                Integer incorrect = taskDao.getCount(null,null,batch,null,(byte)0);
                taskSamplingDao.updateSampling(batch,correct,incorrect,(byte)1);
                int correct_rate = correct * 100 / (correct + incorrect);
                if (correct_rate >= THRESHOLD){
                    communiteResult(batch,null);
                }else {
                    batchDao.updateBatch(batch,null,(byte)4);
                    taskDao.init(batch);
                }
            } catch (Exception e){
                e.printStackTrace();
                log.error(e.getMessage());
            }
        }
    
    }

    这样就实现了所需的功能 ,AOP的优点就是对目标方法代码不做任何改动,就可以实现前后处理,另外在c中也可以用@Before,@After等其它注解来实现不同的功能。

    4. @AspectJ的详细用法

    在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指示符如下:

    一些常见的切入点的例子 
    execution(public * * (. .))    任意公共方法被执行时,执行切入点函数。 
    execution( * set* (. .))   任何以一个“set”开始的方法被执行时,执行切入点函数。 
    execution( * com.demo.service.AccountService.* (. .))  当接口AccountService 中的任意方法被执行时,执行切入点函数。 
    execution( * com.demo.service.*.* (. .))  当service 包中的任意方法被执行时,执行切入点函数。 within(com.demo.service.*)  在service 包里的任意连接点。 within(com.demo.service. .*)  在service 包或子包的任意连接点。
    this(com.demo.service.AccountService) 实现了AccountService 接口的代理对象的任意连接点。 
    target(com.demo.service.AccountService) 实现了AccountService 接口的目标对象的任意连接点。 
    args(java.io.Serializable)  任何一个只接受一个参数,且在运行时传入参数实现了 Serializable 接口的连接点

    增强的方式:

    @Before:方法前执行

    @AfterReturning:运行方法后执行

    @AfterThrowing:Throw后执行

    @After:无论方法以何种方式结束,都会执行(类似于finally)

    @Around:环绕执行

  • 相关阅读:
    【前端】
    Ember.js 应用入口
    Apache 反向代理实现为http添加https的外衣
    OAuth2.0 四种授权模式
    MongoDB查询重复记录并保存到文件csv
    8000用户同时在线的服务器需求分析
    Bootstrap杂记
    Virtual Box 杂记
    RESTful API你怎么看?
    使用 ASP.NET Core 作为 mediasoup 的信令服务器
  • 原文地址:https://www.cnblogs.com/java-chanjuan/p/7832610.html
Copyright © 2011-2022 走看看