一、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代理(直接放上代码)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
我们将上述的代码提出一部分简单分析一下:
这里边使用了一个增强类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 }