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,如需转载请自行联系原作者