Spring框架:AOP编程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hlw521hxq/article/details/83448440

实现方法:动态代理设计模式

  • JDK 的动态代理:针对实现了接口的类产生代理。InvocationHandler接口
  • CGlib 的动态代理:针对没有实现接口的类产生代理,应用的是底层的字节码增强的技术 生成当前类的子类对象,MethodInterceptor接口

JDK动态代理

  1. 创建接口和实现类

  2. 创建代理类,实现InvocationHandler接口

     //创建被代理对象
        private UserDao dao;
        public  Agency(UserDao dao){
            this.dao=dao;
        }
        //创建代理对象
        public UserDao CreatAgency(){
            //        Proxy.newProxyInstance(类的加载器,对象实现的接口,调用者)
            UserDao userdao = (UserDao)Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), this);
            return userdao;
        }
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("一切之初");
            Object om = method.invoke(dao, args);
            System.out.println("终焉");
            return om;
        }
    ```
    
    
  3. 测试

  		//获取代理对象
       *//* UserDao u = new U();*//*
        //创建代理类对象
        Agency agency = new Agency(u);
        //创建代理对象
        UserDao um = agency.CreatAgency();
        //调用方法
        um.sing();
CGlib动态代理

实现接口MethodInterceptor,来自import org.springframework.cglib.proxy.MethodInterceptor;不要错误了

  1. 创建普通类:方法

  2. 创建代理器,实现MethodInterceptor接口

    代码与上一个相同,区别的地方时创建代理对象的方法

     //创建代理对象的方法
        public UsersDaoImpl createdaili(){
            Enhancer en=new Enhancer();//创建核心类
            en.setSuperclass(user.getClass());//为其设置父类
            en.setCallback(this);//设置回调
            return (UsersDaoImpl)en.create();
        }
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            执行方法之前语句块
            Object o1 = methodProxy.invokeSuper(o, objects);
            执行方法之后语句块
            return o1;
        }
    
  3. 测试:与JDK动态代理测试方法一致

AOP实现:以上两种方式代码自动判断实现

  1. 添加jar包
  2. 创建Aop增强类(本质普通类)
    1. 前置通知
    2. 返回通知
    3. 后置异常通知
    4. 后置最终通知
    5. 环绕通知:有返回值,必须返回,否则报错
	public  Object around(ProceedingJoinPoint point) throws Throwable{}
  1. xml文件添加命名空间aop
	xmlns:aop="http://www.springframework.org/schema/aop"
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
  1. 设置配置文件

       <!--创建目标类对象-->
        <bean name="userService" class="com.itqf.spring.service.UserServiceImpl" />
        <!--配置增强类对象-->
        <bean name="myAdvice" class="com.itqf.spring.aop.MyAdivce" />
        <!-- 配置将增强织入目标对象-->
        <aop:config>
            <aop:pointcut id="pc" expression="execution(* com.itqf.spring.service.*ServiceImpl.*(..))"/>
            <aop:aspect ref="myAdvice">
                     <aop:before method="before" pointcut-ref="pc" />
                     <aop:after-returning method="afterReturning" pointcut-ref="pc" />
                     <aop:around method="around" pointcut-ref="pc" />
                     <aop:after-throwing method="afterException" pointcut-ref="pc" />
                     <aop:after method="after" pointcut-ref="pc" />
            </aop:aspect>
        </aop:config>
    注意:(1)环绕增强需要使用ProceedingJoinPoint 作为参数(2)注意标签顺序
    
  2. 切入点匹配规则:

    public * addUser(com.pb.entity.User):“*”表示匹配所有类型的返回值。
      示例:public int addUser(User u);
           public String addUser(User u);
    public void *(com.pb.entity.User):“*”表示匹配所有方法名。
       示例:public void selectUser(User u);  
            public void a(User u);
    public void addUser (..):“..”表示匹配所有参数个数和类型。
       示例: public void addUser(int a)
             public void addUser(int b,int c)
    * com.pb.service.*.*(..):匹配com.pb.service 包下所有类的所有方法。
       示例:  public  void com.pb.service.A.a();
               public  String  com.pb.service.B.a();
    * com.pb.service..*(..):匹配com.pb.service 包及子包下所有类的所有方法
    
    获取切入点信息

    通过aop类,添加参数JoinPoint对象获取信息

    			"切入点对象:"+jp.getTarget().getClass().getSimpleName();
        		"切入点方法:"+jp.getSignature();
         		"切入点的参数:"+jp.getArgs()[0];
    

特殊增强——Advisor前置增强实现步骤

  1. 创建增强类,实现MethodBeforeAdvice接口
  2. 在配置文件,aop配置切入点后,加入
 <aop:advisor advice-ref="增强类对象的id" pointcut-ref="切入点对象的id"/>

注解实现Aop

  1. 启动aspectj注解

    		<aop:aspectj-autoproxy/> 
    
  2. 在切面类上添加@Aspect

  3. 定义切面方法(任意),添加切入点注解@Pointcut(“execution(切入路径)”)

  4. @Before 前置 @After 最终 @Around 环绕 @AfterReturning 后置 @AfterThrowing 异常

eg:		@Before("切入方法()")

猜你喜欢

转载自blog.csdn.net/hlw521hxq/article/details/83448440