两种代理原理
jdk动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
spring对代理的选择
- 如果目标类
实现了接口
,默认情况下会采用JDK的动态代理实现AOP
- 如果目标类
实现了接口
,可以强制使用CGLIB实现AOP
- 如果目标类
没有实现了接口
,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
JDK动态代理和CGLIB字节码生成的区别?
- JDK动态代理需要目标类
实现接口
- CGLIB是针对类实现代理,主要是对指定的类
生成子类
,覆盖其中的方法
因为是继承,所以该类或方法最好不要声明成final
- CGLIB性能更好
JDK动态代理实现
定义目标类的接口
1
2
3
|
public interface business {
void execute();
}
|
目标类实现接口
1
2
3
4
5
|
public class businessIml implements business {
public void execute() {
System.out.println("业务处理");
}
}
|
代理类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class businessInvacationHandler implements InvocationHandler {
private Object target;
//proxy指代理的对象,method指代理对象的某个方法,args指该方法接受的参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("业务处理前");
Object result = method.invoke(target, args);
System.out.println("业务处理后");
return result;
}
/* loader: 一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
interfaces: 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,
如果我提供了一组接口给它,
那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
h: 一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上*/
public Object getProxy(Object object) {
this.target=object;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
}
|
1
2
3
4
5
|
public static void main(String[] args) {
businessIml businessIml = new businessIml();
business proxy = (business)new businessInvacationHandler().getProxy(businessIml);
proxy.execute();
}
|
CGLIB 代理实现
引入依赖
1
2
3
4
5
|
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.4</version>
</dependency>
|
代理类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class BusinessProxy implements MethodInterceptor {
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("业务处理前");
Object result = methodProxy.invokeSuper(o, args);
System.out.println("业务处理后");
return result;
}
public Object getProxy(Class<?> clazz) {
Enhancer enhancer = new Enhancer();//用于创建子类
enhancer.setSuperclass(clazz);//设置父类
enhancer.setCallback(this);//回调方法的参数为代理类对象BusinessProxy
// ,最后增强目标类调用的是代理类对象BusinessProxy中的intercept方法
return enhancer.create();
}
}
|
1
2
3
4
5
|
public static void main(String[] args) {
businessIml proxy = (businessIml) new BusinessProxy().
getProxy(businessIml.class);
proxy.execute();
}
|