• 20_AOP_Advice增强1(前置、后置、环绕)


    【增强的类型】

    1.前置增强org.springframework.aop.BeforeAdvice

    由于Spring只支持方法级别的增强,所以MethodBeforeAdvice是目前可用的前置增强,表示在目标方法执行前执行前置增强,BeforeAdvice是为了将来版本扩展需要而定义的。

    2.后置增强org.springframework.aop.AfterReturningAdvice

    表示在目标方法执行后执行增强。

    3.环绕增强org.aopalliance.intercept.MethodInterceptor

    表示在目标方法执行前后执行增强。

    4.异常抛出增强org.springframework.aop.ThrowsAdvice

    表示在目标方法抛出异常时执行增强。

    5.引介增强org.springframework.aop.IntroductionInterceptor

    在目标类中添加一些新的属性和方法。

    【前置、后置、环绕增强整个工程】

    【车子接口 Car.java】

    package com.Higgin.part1;
    
    /**
     * 车子接口
     */
    public interface Car {
        public void drive();
    }

    【具体奔驰车类:BenzCar.java】

    package com.Higgin.part1;
    
    /**
     * 奔驰车类
     * 我们希望测试奔驰车在执行drive()方法前、后、前后增强的情况
     */
    public class BenzCar implements Car{
    
        @Override
        public void drive() {
            System.out.println("【业务方法】奔驰车在行驶....");
        }
    
    }

    【前置增强类】

    package com.Higgin.part1;
    
    import java.lang.reflect.Method;
    import org.springframework.aop.MethodBeforeAdvice;
    
    /**
     * 前置增强类
     * 实现的是:MethodBeforeAdvice接口
     */
    public class DriveBeforeAdvice implements MethodBeforeAdvice{
    
        /**
         * method:目标类的方法
         *   args:目标类方法的参数
         *    obj:目标类的实例
         */
        @Override
        public void before(Method method, Object[] args, Object obj)throws Throwable {
            System.out.println("【前置增强】开车前自动放音乐~~~");
        }
    }

    【测试前置增强类1:TestBeforeAdvice】

    package com.Higgin.part1.Test;
    
    import org.springframework.aop.BeforeAdvice;
    import org.springframework.aop.framework.ProxyFactory;
    import com.Higgin.part1.BenzCar;
    import com.Higgin.part1.Car;
    import com.Higgin.part1.DriveBeforeAdvice;
    
    /**
     * 测试 前置增强
     */
    public class TestBeforeAdvice{
        public static void main(String[] args) {
            Car benz=new BenzCar();        //目标对象
            BeforeAdvice driveBeforeAdvice=new DriveBeforeAdvice(); //前置增强
            
            ProxyFactory pf=new ProxyFactory();  //1.Spring代理工厂
            
            pf.setTarget(benz);                  //2.设置代理目标对象
            
            pf.addAdvice(driveBeforeAdvice);     //3.为代理对象添加增强
            
            Car carProxy=(Car) pf.getProxy();    //4.生成代理实例
            
            carProxy.drive();
            
        }
    }

    [ 运行结果 ]

    【测试前置增强类2:用Spring的xml配置文件方式:TestBeforeAdviceXml.java】

    package com.Higgin.part1.Test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import com.Higgin.part1.Car;
    
    public class TestBeforeAdviceXml {
        public static void main(String[] args) {
            ApplicationContext context=new ClassPathXmlApplicationContext("part1.xml");
            Car car=(Car) context.getBean("benzCar1");
            car.drive();
        }
    }

    【测试前置增强类2:用Spring的xml配置文件方式的配置文件:part1.xml】

    <?xml version="1.0" encoding="UTF-8"?>  
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
        xmlns:cache="http://www.springframework.org/schema/cache"  
        xsi:schemaLocation="  
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context.xsd  
        http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans.xsd  
        http://www.springframework.org/schema/tx  
        http://www.springframework.org/schema/tx/spring-tx.xsd  
        http://www.springframework.org/schema/jdbc  
        http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd  
        http://www.springframework.org/schema/cache  
        http://www.springframework.org/schema/cache/spring-cache-3.1.xsd  
        http://www.springframework.org/schema/aop  
        http://www.springframework.org/schema/aop/spring-aop.xsd  
        http://www.springframework.org/schema/util  
        http://www.springframework.org/schema/util/spring-util.xsd">
        
        <!-- 要增强的目标对象 -->
        <bean id="target" class="com.Higgin.part1.BenzCar"/>
        
        <!-- 前置增强的类 -->
        <bean id="driveBeforeAdvice" class="com.Higgin.part1.DriveBeforeAdvice" />
     
        <!-- Spring代理工厂的成员变量配置(前置增强)-->
        <bean id="benzCar1" class="org.springframework.aop.framework.ProxyFactoryBean"
            p:proxyInterfaces="com.Higgin.part1.Car" 
            p:interceptorNames="driveBeforeAdvice"
            p:target-ref="target"
        />
          
    </beans>

    [ 运行结果 ]

     【后置增强类:DriveAfterAdvice.java】

    package com.Higgin.part1;
    
    import java.lang.reflect.Method;
    
    import org.springframework.aop.AfterReturningAdvice;
    
    /**
     * 后置增强类
     * 实现的是:AfterReturningAdvice
     */
    public class DriveAfterAdvice implements AfterReturningAdvice{
    
        @Override
        public void afterReturning(Object returnObj, Method method, Object[] args, Object obj) throws Throwable {
            System.out.println("【后置增强】停车后自动关闭音乐~~~");
        }
    }

    【测试后置增强类1:TestAfterAdvice.java】

    package com.Higgin.part1.Test;
    
    import org.springframework.aop.AfterReturningAdvice;
    import org.springframework.aop.BeforeAdvice;
    import org.springframework.aop.framework.ProxyFactory;
    
    import com.Higgin.part1.BenzCar;
    import com.Higgin.part1.Car;
    import com.Higgin.part1.DriveAfterAdvice;
    import com.Higgin.part1.DriveBeforeAdvice;
    
    public class TestAfterAdvice {
        public static void main(String[] args) {
            Car benz=new BenzCar();        //目标对象
            BeforeAdvice driveBeforeAdvice=new DriveBeforeAdvice();         //前置增强
            AfterReturningAdvice driveAfterAdvice=new DriveAfterAdvice();  //后置增强
            
            ProxyFactory pf=new ProxyFactory();  //1.Spring代理工厂
            
            pf.setTarget(benz);                  //2.设置代理目标
            
            pf.addAdvice(driveBeforeAdvice);     //3.为代理对象添加 前 置增强
            pf.addAdvice(driveAfterAdvice);      //3.为代理对象添加 后 置增强
            
            Car carProxy=(Car) pf.getProxy();    //4.生成代理实例
            
            carProxy.drive();
        }
    }

    【运行结果】

    【测试后置增强类2:用Spring的xml配置文件方式:TestAfterAdviceXml.java】

    package com.Higgin.part1.Test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.Higgin.part1.Car;
    
    public class TestAfterAdviceXml {
        public static void main(String[] args) {
            ApplicationContext context =new  ClassPathXmlApplicationContext("part1.xml");
            Car benz=(Car) context.getBean("benzCar2");
            benz.drive();
        }
    }

    【测试后置增强类2:用Spring的xml配置文件方式的配置文件:part1.xml】

    <?xml version="1.0" encoding="UTF-8"?>  
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
        xmlns:cache="http://www.springframework.org/schema/cache"  
        xsi:schemaLocation="  
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context.xsd  
        http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans.xsd  
        http://www.springframework.org/schema/tx  
        http://www.springframework.org/schema/tx/spring-tx.xsd  
        http://www.springframework.org/schema/jdbc  
        http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd  
        http://www.springframework.org/schema/cache  
        http://www.springframework.org/schema/cache/spring-cache-3.1.xsd  
        http://www.springframework.org/schema/aop  
        http://www.springframework.org/schema/aop/spring-aop.xsd  
        http://www.springframework.org/schema/util  
        http://www.springframework.org/schema/util/spring-util.xsd">
        
        <!-- 要增强的目标对象 -->
        <bean id="target" class="com.Higgin.part1.BenzCar"/>
        
        <!-- 前置增强的类 -->
        <bean id="driveBeforeAdvice" class="com.Higgin.part1.DriveBeforeAdvice" />
        <!-- 后置增强的类 -->
        <bean id="dirveAfterAdvice" class="com.Higgin.part1.DriveAfterAdvice" />
    
        <!-- Spring代理工厂的成员变量配置(后置增强+前置增强) -->
        <bean id="benzCar2" class="org.springframework.aop.framework.ProxyFactoryBean"
            p:proxyInterfaces="com.Higgin.part1.Car" 
            p:interceptorNames="driveBeforeAdvice,dirveAfterAdvice"
            p:target-ref="target"
        />
        
    </beans>

    [ 运行结果 ]

    【环绕增强类:DriveAroundAdvice.java】

    package com.Higgin.part1;
    
    import org.aopalliance.intercept.MethodInterceptor;
    import org.aopalliance.intercept.MethodInvocation;
    
    /**
     * 环绕增强
     * 实现的接口:MethodInterceptor
     * 注意:需要导入jar包:aopalliance-1.0.jar
     */
    public class DriveAroundAdvice implements MethodInterceptor{
    
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            System.out.println("【前置增强】开车前自动打开音乐~~~");
            Object obj=invocation.proceed();  //通过反射执行目标的业务方法
            System.out.println("【后置增强】停车后自动关闭音乐~~~");
            return obj;
        }
    
    }

    【环绕增强测试类1:TestAroundAdvice.java】

    package com.Higgin.part1.Test;
    
    import org.aopalliance.intercept.MethodInterceptor;
    import org.springframework.aop.framework.ProxyFactory;
    
    import com.Higgin.part1.BenzCar;
    import com.Higgin.part1.Car;
    import com.Higgin.part1.DriveAroundAdvice;
    
    public class TestAroundAdvice {
        public static void main(String[] args) {
            Car benzCar=new BenzCar();
            MethodInterceptor driveAroundAdvice=new DriveAroundAdvice();
            
            ProxyFactory pf=new ProxyFactory();
            
            pf.setTarget(benzCar);
            
            pf.addAdvice(driveAroundAdvice);
            
            Car carProxy=(Car) pf.getProxy();
            
            carProxy.drive();
        }
    }

    [ 运行结果 ]

    【测试环绕增强类2:用Spring的xml配置文件方式:TestAroundAdviceXml.java】

    package com.Higgin.part1.Test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.Higgin.part1.Car;
    
    public class TestAroundAdviceXml {
        public static void main(String[] args) {
            ApplicationContext context=new ClassPathXmlApplicationContext("part1.xml");
            Car car=(Car) context.getBean("benzCar3");
            car.drive();
        }
    }

    【测试环绕增强类2:用Spring的xml配置文件方式的配置文件:part1.xml】

    <?xml version="1.0" encoding="UTF-8"?>  
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
        xmlns:cache="http://www.springframework.org/schema/cache"  
        xsi:schemaLocation="  
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context.xsd  
        http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans.xsd  
        http://www.springframework.org/schema/tx  
        http://www.springframework.org/schema/tx/spring-tx.xsd  
        http://www.springframework.org/schema/jdbc  
        http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd  
        http://www.springframework.org/schema/cache  
        http://www.springframework.org/schema/cache/spring-cache-3.1.xsd  
        http://www.springframework.org/schema/aop  
        http://www.springframework.org/schema/aop/spring-aop.xsd  
        http://www.springframework.org/schema/util  
        http://www.springframework.org/schema/util/spring-util.xsd">
        
        <!-- 要增强的目标对象 -->
        <bean id="target" class="com.Higgin.part1.BenzCar"/>
        
        <!-- 环绕增强的类 -->
        <bean id="driveAroundAdvice" class="com.Higgin.part1.DriveAroundAdvice"/>
     
        <!-- Spring代理工厂的成员变量配置(环绕增强) -->
        <bean id="benzCar3" class="org.springframework.aop.framework.ProxyFactoryBean"
            p:proxyInterfaces="com.Higgin.part1.Car" 
            p:interceptorNames="driveAroundAdvice"
            p:target-ref="target"
        />
       
    </beans>

    [ 运行结果 ]

    【分析】

    1.关于spring的xml配置文件的分析

    其中的ProxyFactoryBean类是FactoryBean的实现类,

    FactoryBean负责实例化一个Bean,

    ProxyFactoryBean负责为其他Bean创建代理实例,它内部使用ProxyFactory来完成这一工作。

    ProxyFactoryBean的几个可配置属性(成员变量)

      target:代理的目标对象

      proxyInterfaces:代理需要实现的接口,可以是多个接口。该属性该有一个别名interfaces。

      interceptor:需要织入目标对象的Bean列表。采用Bean的名称指定。这些Bean必须是实现了org.aoplliance.interceptor.MethodInterceptor或者org.springframework.Advisor的Bean,配置中的顺序对应调用的顺序。

      singleton:返回的代理是否是单例,默认单例。

      optimize:为true时,强制使用Cglib代理,对于Singleton的代理,建议使用CGlib。对于其他作用域类型的代理,最好使用JDK代理。(CGLib创建代理时速度慢,而创建出来的代理对象运行效率高,JDK代理相反)

      proxyTargetClass:是否对类进行代理(而不是对接口进行代理),设置为true时,使用CGLib代理。

      

  • 相关阅读:
    android ioctl fuzz,android 本地提权漏洞 android root
    syscall 中断号
    EAT/IAT Hook
    VC中如何获取当前时间(精度达到毫秒级)
    Js表单验证控件-02 Ajax验证
    Js表单验证控件(使用方便,无需编码)-01使用说明
    字符串对比
    KindEditor编辑器For DotNet控件
    模板引擎开发(三)-自定义标签的处理
    Flash AS实现时钟效果(全脚本实现)
  • 原文地址:https://www.cnblogs.com/HigginCui/p/6309035.html
Copyright © 2020-2023  润新知