zoukankan      html  css  js  c++  java
  • Spring AOP的使用

      使用一个非常简单的Demo来展示一下AOP达到的效果。即在某个需要关注的点触发的时候(服务调用,数据库调用,any way 就是切点),进行你的业务操作(before,after,around,throw 等)。

    package advice;
    
    public class addAdvice {
        public void beforeAdvice(){
            System.out.println("==添加操作==");
        }
    }
    package advice;
    
    public class deleteAdvice {
        public void beforeAdvice(){
            System.out.println("==删除操作==");
        }
    }

        在applicationContext.xml中加入

    <!-- 配置切面类-->
        <bean id="addAspect" class="advice.addAdvice"></bean>
        <!-- 配置切面类-->
        <bean id="deleteAspect" class="advice.deleteAdvice"></bean>
        <!-- 配置aop-->
        <aop:config>
            <!-- 配置切面-->
            <aop:aspect ref="addAspect">
                <!-- 切点表达式-->
                <aop:pointcut id="userAdvice1" expression="execution(* service.UserService.addService(..))"/>
                <aop:before method="beforeAdvice" pointcut-ref="userAdvice1"></aop:before>
            </aop:aspect>
        </aop:config>
        
        <aop:config>
            <!-- 配置切面-->
            <aop:aspect ref="deleteAspect">
                <!-- 切点表达式-->
                <aop:pointcut id="userAdvice2" expression="execution(* service.UserService.deleteService(..))"/>
                <aop:before method="beforeAdvice" pointcut-ref="userAdvice2"></aop:before>
            </aop:aspect>
        </aop:config>

        使用aop标签之前必须先加入dtd

    xmlns:aop="http://www.springframework.org/schema/aop"
    
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-2.0.xsd

        切面表示的是你要使用的那个通知类,通知类里面是对切点类的前后加入执行方法的类。切点类就是当这个类执行到指定方法的时候回执行切面类方法的类。

        切点表达式的第一个*表示任意返回值,可以把包后面的UserService改成*,这样就是对service下的所有方法执行切面方法。

        <aop:before/>是定义一个前置通知,还有其他三种方式就不介绍了。

    •  对AOP基本元素的总结

       

        To use it,we need Spring。废话,AOP就是Spring提供的一种开发模式(大胆定义)。you can image,在Spring的Bean代理框架中,所有的method都是Spring里面bean instance的invoke操作。所以Spring会关注你是否在invoke中定义了切面,如果定义了,那就如代理模式中所描述的一样,invoke你方法的前后执行你的切面。

        在最新的Spring中需要定义一个切面,不需要各种各样的配置,只需要告诉Spring 你是一个Bean,并且你是一个切面就好。

    /**
     * 对接服务日志参数打印
     */
    @Component
    @Aspect
    public class ClientLog 

        但是要确保,scan有把你的路径扫进去,不然不能叫“告诉”了Spring。

        这里将要提供两种比较简单的,立即可以上手编程的切面定义方法。

        1.对路径直接实施切面(这是我最早使用的一种方案,seems stupid)

        //日志切面
        @Pointcut("execution(* com.timevale.*.common.service.integration.*.client.UserAccountIdentifyClient.*(..))")
        private void clientLogPointCut(){}

        这个切点表达式非常的简便,并且易于理解。

        第一个*,表示他的返回值泛型,最后的(..)表示方法入参的随意性,最后,IDEA会告诉你你的切点表达式是否有效果(当你按着ctrl点击最后那个*的时候,他会显示被切点作用到的方法名称)。

        这个方法stupid,因为他非常不灵活,如果你要在一个类中某些方法不被切到,那你在定义切点表达式时候,需要用同样的后缀或者前缀或者公共子段进行方法命名,比如*.client.UserAccountIdentifyClient.*Demo(..)。

        2.Annotation切点(非常灵活)

        只需要在你需要关注的方法上定义一个注解,那么你的方法就会进入切面了,是目前最优美的方案了。

        @Pointcut("@annotation(com.timevale.*.core.service.*.annotation.Billing)")
        private void needBillingAspect() {
        }

        只要带有@Biiling这个注解的方法,都会进行切面操作。

    •  方案应用

        AOP适合什么样的场景?一般来说,就是common的场景,譬如日志操作,计费操作,通知操作(都是我做过的方案)。

        1.对于日志操作,思路简单,需要把这个切点的入参出参打印出来,或者做数据埋点等等操作。

        2.对于计费操作,很明显,我们在提供open service接口的时候,需要进行计费。而业务成功后计费如果嵌入到业务代码中,显得有点disgusting。那我们可以around一下,在入参中定义一个基类,里面有计费的type,每次切到的结果,即使子类不一样(因为不同的业务参数入参不一样),但是始终能转化为父类并拿到计费基本参数。

        3.至于通知,我们使用的是消息投递的方式(way is not important),在关心的那个事件发生的时候,发送通知,不同的子业务,通常有一个业务流程,这个流程失败的时候,所触发的动作是一样的(更新库失败)

  • 相关阅读:
    第12-13周总结
    排球比赛计分规则
    我与计算机
    排球比赛计分规则-三层架构
    怎样成为一个高手 观后感
    最后一周冲刺
    本周psp(观众页面)
    本周psp(观众页面)
    本周工作计量
    本周总结
  • 原文地址:https://www.cnblogs.com/chentingk/p/5993973.html
Copyright © 2011-2022 走看看