Java动态代理

参考:http://www.360doc.com/content/14/0618/11/454045_387708106.shtml

   http://blog.csdn.net/heyutao007/article/details/49738887

推荐:http://paddy-w.iteye.com/blog/841798

JAVA的动态代理 
代理模式 
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。 
按照代理的创建时期,代理类可以分为两种。 
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 
动态代理:在程序运行时,运用反射机制动态创建而成。 

 

动态代理的两种实现:

1.JDK动态代理。

2.CGLIB动态代理。

 

两种实现比较:

jdk动态代理是由Java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。由此可以看出,jdk动态代理有一定的局限性,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。

 

1.JDK动态代理demo

1 package proxy;
2 
3 public interface UserService {
4     
5     public String getName(int name);
6     
7     public Integer getAge(int age);
8 
9 }
 1 package proxy;
 2 
 3 public class UserServiceImpl implements UserService {
 4 
 5     @Override
 6     public String getName(int name) {
 7         // TODO Auto-generated method stub
 8         System.out.println("----- getName  -----");
 9         return "Tom";
10     }
11 
12     @Override
13     public Integer getAge(int age) {
14         // TODO Auto-generated method stub
15         System.out.println("----- getAge  -----");
16         return 10;
17     }
18 }
 1 package proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 
 6 public class MyInvocationHandler implements InvocationHandler {
 7     
 8     private Object target;
 9     
10     public MyInvocationHandler() {
11         // TODO Auto-generated constructor stub
12         super();
13     }
14     
15     public MyInvocationHandler(Object target) {
16         this.target = target;
17     }
18 
19     @Override
20     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
21         // TODO Auto-generated method stub
22         if("getName".equals(method.getName())) {
23             System.out.println("+++++ before " + method.getName() + " +++++");
24             Object result = method.invoke(target, args);
25             System.out.println("+++++ after " + method.getName() + " +++++");
26             return result;
27         } else {
28             Object result = method.invoke(target, args);
29             return result;
30         }
31     }
32 
33 }
 1 package proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Proxy;
 5 
 6 public class Main1 {
 7     
 8     public static void main(String[] args) {
 9         UserService userService = new UserServiceImpl();
10         InvocationHandler invocationHandler = new MyInvocationHandler(userService);
11         UserService userServiceProxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), invocationHandler);
12         System.out.println(userServiceProxy.getName(1));
13         System.out.println(userServiceProxy.getAge(1));
14     }
15 
16 }

2.CGLIB动态代理demo

 1 package proxy;
 2 
 3 import java.lang.reflect.Method;
 4 
 5 import net.sf.cglib.proxy.MethodInterceptor;
 6 import net.sf.cglib.proxy.MethodProxy;
 7 
 8 public class CglibProxy implements MethodInterceptor {
 9 
10     @Override
11     public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
12         System.out.println("++++++before " + methodProxy.getSuperName() + "++++++");
13         System.out.println(method.getName());
14         Object o1 = methodProxy.invokeSuper(o, args);
15         System.out.println("++++++before " + methodProxy.getSuperName() + "++++++");
16         return o1;
17     }
18 }
 1 package proxy;
 2 
 3 import net.sf.cglib.proxy.Enhancer;
 4 
 5 public class Main2 {
 6     
 7     public static void main(String[] args) {  
 8         CglibProxy cglibProxy = new CglibProxy();  
 9   
10         Enhancer enhancer = new Enhancer();  
11         enhancer.setSuperclass(UserServiceImpl.class);  
12         enhancer.setCallback(cglibProxy);  
13   
14         UserService o = (UserService)enhancer.create();  
15         o.getName(1);  
16         o.getAge(1);  
17     }  
18 
19 }

参数:Object为由CGLib动态生成的代理类实例,Method为上文中实体类所调用的被代理的方法引用,Object[]为参数值列表,MethodProxy为生成的代理类对方法的代理引用。

 

参考:https://segmentfault.com/q/1010000002652067 

为什么cglib不能拦截静态方法是因为Cglib的实现方式:生成的代理类继承自被代理类/目标类,请求时,执行自己织入的增强,然后再执行目标方法,因而使用继承方式创建代理类不能代理任何final方法和类,以及静态方法。

 

posted @ 2017-01-19 15:43  MicroCat  阅读(235)  评论(0编辑  收藏  举报