limuma

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一、aop思想介绍

  

  1、这里,以三个例子来说明:

    (1)Filter过滤器,将每次都要在servlet里写的解决乱码的代码提取出来,放在一个过滤器Filter中,使得在客户端请求到达servlet(servlet响应到达客户端页面)之前,先经过过滤器,处理编码问题;

    

    (2)事务管理(动态代理中使用aop,体现了aop思想):之前在service层,都要写事物的开启、提交(回滚等),运用aop思想之后,将之前service里的事务管理的代码提取出来,放到InvocationHandler里,然后通过动态代理的方式,将InvocationHandler动态的添加到所有的service层的类当中,形成代理对象;    

         

    (3)struts2中的action赋值操作放在拦截器中进行;

    

二、spring中的aop思想

  1、spring中的aop思想指的是:spring能够为容器中所存放的对象生成动态代理对象;之前我们使用aop思想时,比如上述一中的InvocationHandler事务管理,需要我们自己手动写代码(proxy.newProxyInstanse(classload,interface[] arr,InvocationHandler  handler)),创建并生成代理对象,而现在,spring会为我们做这些事(通过xml配置或注解的方式),生成代理对象,在生成动态代理这个过程中会给每个service里的方法添加事务管理的代码;

  2、spring实现aop的原理:

    依赖于两种代理技术:

    (1)动态代理:要求被代理对象必须要实现接口,才能产生代理对象,如果没有接口,将不能使用动态代理的技术;

    (2)cglib代理:第三方代理技术,可以对任何类生成代理对象,代理原理是对目标对象进行继承代理;比如,我要给UserService(的对象userService)生成一个代理对象,实际上生成的这个UserService的代理对象是UserService对象的子类,即它会对被代理对象进行继承(对被代理对象进行继承代理),所以如果目标对象(目标类)被final修饰,那么该类无法cglib代理;

    结论:以上两种代理技术的区别:从代理对象和被代理对象的角度来说;动态代理中,代理对象和被代理对象之间没有继承关系,只是实现了同一个接口比如UserviceImpl实现了Uservice接口,代理对象生成时,第二个参数就是被代理对象的接口UserServiceImpl.class.getInterfaces(),即也实现了Uservice接口;cglib代理中,代理对象和被代理对象是继承关系,即代理对象是被代理对象的子类;

  结论:spring中会混合使用上述两种代理技术实现aop,优先使用动态代理的技术(1),如果没有接口的话,再使用cglib代理技术(2);

  3、这里我们说一下手动实现以上两种代理的代码(仅做了解,以后开发中spring会帮我们实现):

   (1)动态代理:

    首先来看这个方法:proxy.newProxyInstanse(classload,interface[] arr,InvocationHandler  handler)

    上述这个函数,用于我们手动利用动态代理技术生成代理对象,这个方法定义在代理工厂类里,比如UserServiceProxyFactory里,里边的三个参数:

      classload:UserServiceProxyFactory.class.getClassLoader(),

      interface [] arr:被代理对象的接口,UserServiceImpl.class.getInterfaces(),

      handler:第三个参数,决定了本次代理到底要怎么增强我们的目标方法,增强的内容;

            这是一个接口InvocationHandler的对象,接口是不能创建对象的,但这里这么写成对象,必须要实现接口里的方法(接口回调),如下:

 1 package cn.itcast.c_proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
 6 
 7 import cn.itcast.service.UserService;
 8 import cn.itcast.service.UserServiceImpl;
 9 //观光代码=>动态代理
10 public class UserServiceProxyFactory implements InvocationHandler {
11     
12     public UserServiceProxyFactory(UserService us) {
13         super();
14         this.us = us;
15     }
16 
17     private UserService us;
18     
19     public UserService getUserServiceProxy(){
20         //生成动态代理
21         UserService usProxy = (UserService) Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(),
22                                     UserServiceImpl.class.getInterfaces(), 
23                                     this);
24         //返回
25         return usProxy;
26         
27     }
28 
29     @Override
30     public Object invoke(Object arg0, Method method, Object[] arg2) throws Throwable {
31         System.out.println("打开事务!");
32         Object invoke = method.invoke(us, arg2);
33         System.out.println("提交事务!");
34         return invoke;
35     }//这部分代码就是为了proxy.newProxyInstanse(classload,interface[] arr,InvocationHandler  handler)中第三个参数写的,实现接口
    //InvocationHandler中的方法incoke(),只不过,直接在UserServiceProxyFactory基础上实现接口,参数用this来代替; 
36 
37 }

  然后写一个测试类,来测试上述的代码:

    

  (2)cglib代理(直接放上代码)

    
 1 package cn.itcast.c_proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
 6 
 7 import org.springframework.cglib.proxy.Callback;
 8 import org.springframework.cglib.proxy.Enhancer;
 9 import org.springframework.cglib.proxy.MethodInterceptor;
10 import org.springframework.cglib.proxy.MethodProxy;
11 
12 import cn.itcast.service.UserService;
13 import cn.itcast.service.UserServiceImpl;
14 
15 //观光代码=>cglib代理
16 public class UserServiceProxyFactory2 implements MethodInterceptor {
17     
18 
19     public UserService getUserServiceProxy(){
20         
21         Enhancer en = new Enhancer();//帮我们生成代理对象
22         
23         en.setSuperclass(UserServiceImpl.class);//设置对谁进行代理
24         
25         en.setCallback(this);//代理要做什么
26         
27         UserService us = (UserService) en.create();//创建代理对象
28         
29         return us;
30     }
31 
32     @Override
33     public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
34         //打开事务
35         System.out.println("打开事务!");
36         //调用原有方法
37         Object returnValue = methodProxy.invokeSuper(prxoyobj, arg);
38         //提交事务
39         System.out.println("提交事务!");
40         
41         return returnValue;
42     }
43 
44 
45 }
手动实现cglib代理

  我们将上述的代码提出一部分简单分析一下:

    这里边使用了一个增强类Enhancer类,帮助我们生成代理对象,以增强目标方法(除了我们本身的方法,还有额外的方法)

 1 public UserService getUserServiceProxy(){
 2         
 3         Enhancer en = new Enhancer();//帮我们生成代理对象
 4         
 5         en.setSuperclass(UserServiceImpl.class);//设置对谁进行代理
 6         
 7         en.setCallback(this);//代理要做什么,Callback是一个接口,也要实现这个接口,就像动态代理中的InvocationHandler,
 8         
 9         UserService us = (UserService) en.create();//创建代理对象
10         
11         return us;
12 }

 

posted on 2018-02-23 22:26  limuma  阅读(138)  评论(0编辑  收藏  举报