CGLib 动态代理

CGLib全称是Code Generation Library(https://github.com/cglib),是一个第三方开源的代码生成包,功能很强大,性能很优越,许多开源框架如Spring、Hibernate、EasyMock都使用了这个包来实现动态代理。


Java提供的动态代理是通过实现业务接口来生成一个新的代理类,所以需要定义接口,没有业务接口就没办法生成代理类;CGLib动态代理可以解决这个问题,它不需要业务接口,它直接以委托类(目标类)为父类生成一个增强的子类(代理类),所以这种方式不需要接口,但有一个前提是目标类不能被final修饰,即目标类必须是可继承的。


除了动态生成代理类这能力之外,CGLib还能干很多事情,比如过滤目标类的某些方法不被代理等;另外在最新版本的CGLib库中也提供InvocationHandler接口和Proxy类,即CGLib同时提供了与Java动态代理一样的功能。


MethodInterceptor接口:调用业务方法可以使用Method参数或者MethodProxy参数,建议使用MethodProxy参数,性能比较快。

1
public  Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, MethodProxy proxy)  throws  Throwable;


简单代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package  com.stevex.app.delegate;
 
public  class  SalaryService {
 
     public  void  raise(){
         System.out.println( "raise someone's salary" );
     }
     
     public  void  query(){
         System.out.println( "query someone's salary" );
     }
}
 
package  com.stevex.app.delegate;
 
import  java.lang.reflect.Method;
 
import  net.sf.cglib.proxy.Callback;
import  net.sf.cglib.proxy.CallbackFilter;
import  net.sf.cglib.proxy.Enhancer;
import  net.sf.cglib.proxy.MethodInterceptor;
import  net.sf.cglib.proxy.MethodProxy;
import  net.sf.cglib.proxy.NoOp;
 
public  class  CglibDynamicProxy  implements  MethodInterceptor {
     public  Enhancer enhancer =  new  Enhancer();
     private  String name;
 
     public  CglibDynamicProxy(String name) {
         this .name = name;
     }
 
     public  Object newProxyInstance(Class cls) {
         enhancer.setSuperclass(cls);
         //设置回调实例
         enhancer.setCallbacks( new  Callback[]{ this , NoOp.INSTANCE});
         //设置回调过滤器
         enhancer.setCallbackFilter( new  CallbackFilter(){
             public  int  accept(Method method) {
                 return  "query" .equalsIgnoreCase(method.getName()) ?  1  0 ;            
             }          
         });
         return  enhancer.create();
     }
 
     public  Object intercept(Object object, Method method, Object[] args,
             MethodProxy methodProxy)  throws  Throwable {
         if  (! "HR" .equals(name)) {
             System.out.println(name +  ", 没有权限进行此操作!" );
             return  null ;
         }
 
         Object result = methodProxy.invokeSuper(object, args);
 
         return  result;
     }
}
 
package  com.stevex.app.delegate;
 
import  net.sf.cglib.proxy.Proxy;
 
public  class  CGLibProxyTest {
 
     public  static  void  main(String[] args) {
         test( "HR" );
         test( "Steve" );
     }
 
     private  static  void  test(String name) {
         SalaryService s1 = getSalaryService(name);
         s1.raise();
         s1.query();
     }
 
     private  static  SalaryService getSalaryService(String name) {
         CglibDynamicProxy proxy =  new  CglibDynamicProxy(name);
         return  (SalaryService) proxy.newProxyInstance(SalaryService. class );
     }
 
}



     本文转自sarchitect 51CTO博客,原文链接:http://blog.51cto.com/stevex/1577645,如需转载请自行联系原作者



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值