JDK动态代理和CGLIB代理

JDK代理

参考

https://www.cnblogs.com/MOBIN/p/5597215.html


JDK动态代理和CGLIB代理

通过实现接口实现

通过动态代理,给普通的对象生成代理对象,对其中的方法进行前置和后置的处理

例如spring的事务


使用动态代理的五大步骤

1.通过实现InvocationHandler接口来自定义自己的InvocationHandler;

2.通过Proxy.getProxyClass获得动态代理类

3.通过反射机制获得代理类的构造方法,方法签名为getConstructor(InvocationHandler.class)

4.通过构造函数获得代理对象并将自定义的InvocationHandler实例对象传为参数传入

5.通过代理对象调用目标方法


//接口
public interface MyBuyInterface {
void buy(String goods);
}
//实现这这个接口,也就是后面需要代理的对象
public class MyBuyClass implements MyBuyInterface {
@Override
public void buy(String goods) {

System.out.println("我买了 " + goods);
}
}
//实现自己的InvocationHandler
//实现InvocationHander接口
public class MyInvocationHandler implements InvocationHandler{
//需要被代理的对象
private Object target;
public MyInvocationHandler(Object target) {
super();
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//前置处理
System.out.println(new Date());
//这里是实际调用实际的方法
Object res = method.invoke(target, args);
//后置处理
System.out.println("买完了");
return res;
}
}
//进行实际的调用
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//方法一
//获取代理类
Class> proxyClass = Proxy.getProxyClass(MyBuyInterface.class.getClassLoader(), MyBuyInterface.class);
//获取代理类的构造方法,传入InvocationHandler接口
Constructor> constructor = proxyClass.getConstructor(InvocationHandler.class);
//通过构造方法创建代理对象,传入自定义invocationHandler
MyBuyInterface obj = (MyBuyInterface) constructor.newInstance(new MyInvocationHandler(new MyBuyClass()));
//调用方法,此时会调用自定义invocationHandler的invoke方法
obj.buy("苹果");
//方法二
//上面的几步可以通过下面这个方法合并为一步
MyBuyInterface oobbjj = (MyBuyInterface) Proxy.newProxyInstance(MyBuyInterface.class.getClassLoader(), new Class[] {MyBuyInterface.class}, new MyInvocationHandler(new MyBuyClass()));

oobbjj.buy("梨子");
}
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

运行结果

Tue Aug 28 12:15:37 CST 2018
我买了 苹果
买完了
Tue Aug 28 12:15:37 CST 2018
我买了 梨子
买完了
1
2
3
4
5
6
7

CGLIB代理

CGLIB会让生成的代理类继承被代理类,并在代理类中对代理方法进行强化处理(前置处理、后置处理等)。在CGLIB底层,其实是借助了ASM这个非常强大的Java字节码生成框架。

//自定义方法拦截器,实现MethodInterceptor 接口 

public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable {
System.out.println(new Date());
Object res = proxy.invokeSuper(obj, arg);
System.out.println("买完了");
return res;
}
}
//进行调用
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
//设置父类
enhancer.setSuperclass(MyBuyClass.class);
//设置方法拦截器
enhancer.setCallback(new MyMethodInterceptor());
//生成代理类
MyBuyClass myBuyClass = (MyBuyClass)enhancer.create();
myBuyClass.buy("梨子");
}
//运行结果
Tue Aug 28 13:37:38 CST 2018
我买了 梨子
买完了
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

代理类将委托类作为自己的父类并为其中的非final委托方法创建两个方法,一个是与委托方法签名相同的方法,它在方法中会通过super调用委托方法;另一个是代理类独有的方法。在代理方法中,它会判断是否存在实现了MethodInterceptor接口的对象,若存在则将调用intercept方法对委托方法进行代理


分享到:


相關文章: