zoukankan      html  css  js  c++  java
  • spring AOP的两种配置方式

      连接点(JoinPoint) ,就是spring允许你是通知(Advice)的地方,那可就真多了,基本每个方法的前、后(两者都有也行),或抛出异常是时都可以是连接点,spring只支持方法连接点。其他如AspectJ还可以让你在构造器或属性注入时都行,不过那不是咱们关注的,只要记住,和方法有关的前前后后都是连接点。

    方式一:xml方式配置

    1.配置xml文件

        <bean id="dataSourceExchange" class="com.ooper.www.datasource.DataSourceExchange"/> <!--辅助功能bean-->
        <aop:config>
            <aop:pointcut id="dataSourcePointcut" expression="execution(* com.ooper.www.service.Impl.AccountServiceImpl.*(..))"/> <!-- 指定核心业务功能 -->
            <aop:aspect ref="dataSourceExchange"> <!--指定辅助功能  -->
                <aop:before pointcut-ref="dataSourcePointcut" method="before"/><!-- 执行核心任务之前执行 -->
                <aop:after pointcut-ref="dataSourcePointcut" method="after"/><!-- 执行核心任务之后执行 -->
            </aop:aspect>
        </aop:config>

    2. 辅助功能java代码

    package com.ooper.www.datasource;
    import org.aspectj.lang.JoinPoint;
    
    public class DataSourceExchange {
    
        public void before(JoinPoint point) {
    
            //获取目标对象的类类型
            Class<?> aClass = point.getTarget().getClass();
            String c = aClass.getName();
            String[] ss = c.split("\.");
            //获取包名用于区分不同数据源
            String methodName = ss[5];
    
            if ("AccountServiceImpl".equals(methodName)) {
                DataSourceHolder.setDbType(DataSourceEnum.DS2.getKey());
                System.out.println("数据源:"+DataSourceEnum.DS2.getKey());
            } else {
                DataSourceHolder.setDbType(DataSourceEnum.DS1.getKey());
                System.out.println("数据源:"+DataSourceEnum.DS1.getKey());
            }
        }
    
        /**
         * 执行后将数据源置为空
         */
        public void after(JoinPoint point) {
          System.out.println("point:" + point);
          DataSourceHolder.setDbType(null);
        }
    }

    方式二:注解方式

    1.xml配置文件

          <!-- 注解方式实现AOP -->
      
          <!-- 激活自动代理功能   --> 
          <!-- 代理方式1:采用JDK代理 -->
            <aop:aspectj-autoproxy/> 
            <!--     代理方式2:cglib代理 -->
            <!--     <aop:aspectj-autoproxy proxy-target-class="true"/>   -->
            <!-- 找到被注解了的切面类,进行切面配置 -->
            <context:component-scan base-package="com.how2java.aspect"/>
            <context:component-scan base-package="com.how2java.controller"/>

    2.注解配置切面代码

    package com.how2java.aspect;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    /**spring AOP
    此段小代码演示了spring aop中@Around @Before @After三个注解的区别
     * @Before是在所拦截方法执行之前执行一段逻辑。@After 是在所拦截方法执行之后执行一段逻辑。@Around是可以同时在所拦截方法的前后执行一段逻辑。
     * @author Administrator
     * 通过aop拦截后执行具体操作
     */
    @Aspect
    @Component
    public class LogIntercept {
    
    //    @Pointcut("execution(* com.how2java.controller..*.*(..))")
        public void recordLog(){}
    
        @Before("execution(* com.how2java.controller..*.*(..))")
    //    @Before("recordLog()")
        public void before() {
            this.printLog("已经记录下操作日志@Before 方法执行前");
        }
    
        @Around("execution(* com.how2java.controller..*.*(..))")
    //    @Around("recordLog()")
        public Object around(ProceedingJoinPoint pjp) throws Throwable{
            this.printLog("已经记录下操作日志@Around 方法执行前");
            Object obj = pjp.proceed();
            this.printLog("已经记录下操作日志@Around 方法执行后");
            return obj;
        }
    
         @After("execution(* com.how2java.controller..*.*(..))")
    //    @After("recordLog()")
        public void after() {
            this.printLog("已经记录下操作日志@After 方法执行后");
        }
    
        private void printLog(String str){
            System.out.println(str);
        }
    }
    package com.how2java.aspect;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.stereotype.Component;
     
    @Aspect    // 注解表示这是一个切面
    @Component //表示这是一个bean,由Spring进行管理,使用注解时一定要使用@component或者@Repository、@Controller、@Service中一个去声明,将切面类放入到spring容器中,不然就去xml中显式写一个bean,不然的话就会报错,无法实现切面功能。
    
    public class LoggerAspect { 
        @Around(value = "execution(* com.how2java.controller..*.*(..))") 
      //表示对com.how2java.controller 这个包中的所有方法进行切面操作
        /*    AOP(execution表达式)
         * 
         * execution(* com.how2java.controller..*.*(..))
            解释如下:
            符号                                                                           含义
            execution()                        表达式的主体;
            第一个”*“符号                                  表示返回值的类型任意;
            com.how2java.controller        AOP所切的服务的包名,即,我们的业务部分
            包名后面的”..“                                               表示当前包及子包
            第二个”*“                                                         表示类名,*即所有类。此处可以自定义,下文有举例
            .*(..)                                                         表示任何方法名,括号表示参数,两个点表示任何参数类型
            
            */
        public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
            System.out.println("start log:" + joinPoint.getSignature().getName());
            Object object = joinPoint.proceed();//就是将来与某个核心功能编织之后,用于执行核心功能的代码
            System.out.println("end log:" + joinPoint.getSignature().getName());
            return object;
        }
    }
  • 相关阅读:
    机器学习中规则化和模型选择知识
    关于arcengine权限的设置
    arcengine 实现调用arctoolbox中的dissolove
    基于手机令牌的屏保软件设计与实现
    RelativeLayout中最底的View一个View.layout_marginBottom无效
    Citrus Engine简单Demo
    Java菜鸟学习笔记(23)--继承篇(二):继承与组合
    uva 579 ClockHands 几何初接触 求时针与分针的夹角
    OpenCV中GPU函数
    html监听,键盘事件
  • 原文地址:https://www.cnblogs.com/thiaoqueen/p/8359443.html
Copyright © 2011-2022 走看看