zoukankan      html  css  js  c++  java
  • Spring AOP中增强知识

    Spring中增强:包含横切代码和方位信息  ,增强继承关系如下图:

       

    Advice :其实就是一个增强的标志接口,没有实际的方法需要实现。

    前置增强(BeforeAdvice):Spring中只支持方法级别的增强操作,所以MethodBeforeAdvice是目前可用的前置增强,而BeforeAdvice是为了后面扩展。

    后置增强(AfterRetruningAdvice) :表示在目标方法执行后实施增强

    环绕增强(MethodInterceptor):表示在目标方法执行前后实施增强

    异常抛出增强(ThrowsAdvice) 表示在目标方法抛出异常后实施增强

    引介增强(IntroductionInterceptor)表示在目标类中添加一些新的方法和属性

    1.前置增强案例

           增强类代码如下:      

    /前置增强
    public class GreeetingBeforeAdvice implements MethodBeforeAdvice {
        @Override
        public void before(Method method, Object[] objects, Object o) throws Throwable {
            System.out.println(this.getClass().getName() + "." + method.getName());
            String name = (String) objects[0];
            System.out.println("How are you Mr " + name);
        }
    }

    通过硬编码的方式调用前置增强

    public static void textFactoryBean() {
            //目标类对象
            Waiter waiter = new NaviWaiter();
    //        前置增强
            GreeetingBeforeAdvice greeetingBeforeAdvice = new GreeetingBeforeAdvice();
    //        后置增强
            GreetingAfterAdvice greetingAfterAdvice = new GreetingAfterAdvice();
    //        代理工厂
            ProxyFactory factory = new ProxyFactory();
    //        设置目标类
            factory.setTarget(waiter);
    //        设置增强
            factory.addAdvice(greeetingBeforeAdvice);
    //        设置后置增强
            factory.addAdvice(greetingAfterAdvice);
    //        获取代理对象
            Waiter proxy = (Waiter) factory.getProxy();
            proxy.greetTo("zhang");
            proxy.serveTo("zhang");
        }

    通过Spring配置文件来设置 增强数据

     <!--设置前置代理-->

    代理对象 <bean id="target" class="com.example.AOP.BeforeAdvice.NaviWaiter"/>
      //增强Bean <bean id="beforehance" class="com.example.AOP.BeforeAdvice.GreeetingBeforeAdvice"/> <bean id="afterAdvice" class="com.example.AOP.BeforeAdvice.GreetingAfterAdvice"/> <bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean"//代理工厂Bean 是ProxyFactory的实现类 p:proxyInterfaces="com.example.AOP.BeforeAdvice.Waiter"//代理接口 p:interceptorNames="beforehance,afterAdvice"//织入的增强 p:target-ref="target"
    //其中 target表示代理目标类 proxyInterfaces表示代理所要实现的接口,可以是多个接口, interceptorNames:表示需要织入目标对象的Bean列表,
    optimize 当设置为True 强制使用CGLib动态代理, proxyTargetClass是否对类进行代理吗,设置为true表示使用CGLib代理
    interceptorNames 接收的是Bean的名称而非Bean类 />


     NaviWaiter实现Waiter接口后,自己写就行了

     2.后置增强案例

       后置增强是在目标方法调用完后执行,代码如下:

         

    //后置增强
    public class GreetingAfterAdvice implements AfterReturningAdvice {
        /*
        其中 Object object 表示目标方法的返回值
              Method method 表示目标方法
              objects 表示方法参数
              Object o1表示目标类实例
         */
        @Override
        public void afterReturning(Object object, Method method, Object[] objects, Object o1) throws Throwable {
            System.out.println("please enjoy youself");
        }
    }

         添加后置增强配置文件如上:

    3.环绕增强允许在方法前后加入横切逻辑代码。  Spring使用MethodInterceptor作为环绕增强的接口,

        

    //环绕增强
    public class GreetingInterceptor implements MethodInterceptor {
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
    //        获取目标方法参数
            Object[] arguments = invocation.getArguments();
            String clientName = (String) arguments[0];
            System.out.println("How are you Mr " + clientName + " !");
            Object proceed = invocation.proceed();
            System.out.println("bye bye " + clientName + " !");
            return proceed;
        }
    }

    环绕增强配置

     <!--环绕增强配置-->
        <bean id="NaviWaiter" class="com.example.AOP.BeforeAdvice.NaviWaiter"/>
        <bean id="GreetAround" class="com.example.AOP.BeforeAdvice.GreetingInterceptor"/>
        <bean id="wwwwss" class="org.springframework.aop.framework.ProxyFactoryBean" p:proxyTargetClass="true"
              p:interceptorNames="GreetAround" p:target-ref="NaviWaiter"/>

    4.异常抛出增强   通过实现ThrowsAdvice接口,并设置默认规定方法用于处理异常抛出后的问题。  此接口是一个标签接口,没有任何实际方法,但必须按如下格式处理异常抛出增强方法

       void  afterThrowing([Method method,Object[] object,Object target],Throwable)此方法的前面三个参数要么都不提供,要么都要提供,Throwable必须提供

      5.引介增强案例

         

    //引介增强
    public class ControllerPerformaceMonitor extends DelegatingIntroductionInterceptor implements Monitorable {
    
        private ThreadLocal<Boolean> local = new ThreadLocal<Boolean>();
    
        @Override
        public void setMonitorable(boolean active) {
            local.set(active);
        }
        @Override
        public Object invoke(MethodInvocation mi) throws Throwable {
            Object object = null;
            if (local.get() != null && local.get()) {
                PerFormanceMonitor.begin(mi.getClass().getName() + "." + mi.getMethod().getName());
                object = super.invoke(mi);
                PerFormanceMonitor.end();
            } else {
                object = super.invoke(mi);
            }
            return object;
        }

       配置文件

     <!--引介增强-->
        <bean id="Frumservice" class="com.example.AOP.ForumServiceImpl"/>
        <bean id="yicontro" class="com.example.AOP.introduceAdivice.ControllerPerformaceMonitor"/>
        <bean id="smtext" class="org.springframework.aop.framework.ProxyFactoryBean"
              <!--引介增强所要实现的接口-->
              p:interfaces="com.example.AOP.introduceAdivice.Monitorable"
              p:target-ref="Frumservice"
        <!--增强类-->
              p:interceptorNames="yicontro"
        <!--必须使用CGLib方式,因为引介增强需要创建子类-->
              p:proxyTargetClass="true"
        />

      

  • 相关阅读:
    流程控制值while 循环
    编程语言和变量
    计算机1&操作系统硬件
    使用 Cygwin 在 Windows 中使用 Linux 命令
    windows系统安装mysql及导库
    linux报错 OSError: [Errno 24] Too many open files
    python3报错ModuleNotFoundError: No module named 'Queue'
    mac版本intellij idea默认快捷键
    mysql初设密码及允许远程访问
    PyCharm 图标 c、m、F、f、v、p 分别代表什么含义?
  • 原文地址:https://www.cnblogs.com/09120912zhang/p/7806600.html
Copyright © 2011-2022 走看看