分类
JDK 动态代理
在 JDK 动态代理中,要实现代理逻辑类必须去实现 java.lang.reflect.InvocationHandler
接口
必须提供接口和实现
接口
1 2 3
| public interface Hello { void say(); }
|
实现类
1 2 3 4 5 6 7
| public class HelloImpl implements Hello{
@Override public void say() { System.out.println("hello world!"); } }
|
代理对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class HelloProxy implements InvocationHandler {
private Object target = null;
public Object bind(Object target) { this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ System.out.println("进入代理逻辑方法"); System.out.println("在调度真实对象之前的服务"); Object obj = method.invoke(target, args); System.out.println("在调度真实对象之后的服务"); return obj; } }
|
Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this)
- 第一个参数是类加载器
- 第二个参数是把生成的动态代理对象挂在那些接口下
- 第三个参数是定义实现方法逻辑的代理类,这里是当前对象,必须实现 InvocationHandler 的 invoke 方法
测试
1 2 3 4 5 6 7
| public class Test { public static void main(String[] args) throws Exception{ HelloProxy helloProxy = new HelloProxy(); Hello proxy = (Hello) helloProxy.bind(new HelloImpl()); proxy.say(); } }
|
结果
1 2 3 4
| 进入代理逻辑方法 在调度真实对象之前的服务 hello world! 在调度真实对象之后的服务
|
CGLIB动态代理
优势在于不需要提供接口,只要一个非抽象类就能实现动态代理
被代理类
1 2 3 4 5 6
| public class HelloImpl2 {
public void say() { System.out.println("hello world!"); } }
|
代理类
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
| public class CglibProxy implements MethodInterceptor {
public Object getProxy(Class clazz) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); }
@Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("调用真实对象前"); Object result = methodProxy.invokeSuper(proxy, args); System.out.println("调用真实对象后"); return result; } }
|
测试
1 2 3 4 5 6 7
| public class Test { public static void main(String[] args) throws Exception{ CglibProxy proxy = new CglibProxy(); HelloImpl2 obj = (HelloImpl2) proxy.getProxy(HelloImpl2.class); obj.say(); } }
|
结果
1 2 3
| 调用真实对象前 hello world! 调用真实对象后
|