动态代理:
作用:在不改变源码的基础上,对已有方法增强(AOP思想的实现技术)
分类:
基于接口的动态代理:
要求:被代理类最少实现一个接口。
提供者:JDK官方
涉及类:Proxy
创建方法:newProxyInstance(ClassLoader,Class[],InvocationHandler)
ClassLoader:类加载器,和被代理类使用相同的加载器。(一般固定,ClassName.class)
Class[ ] :字节码数组,被代理类实现的接口,(代理对象和被代理对象具有相同的行为)
InvocationHandler:一个接口,用于增强代码的,一般写一个实现类,可也可不是匿名内部类。
Public Object invoke(Object proxy, Method method, Object args){ return null }
参数:Object proxy :代理对象的引用,不一定每次都会有
Method method: 当前执行的方法
Object args: 当前执行方法所需要的参数
返回值:当前方法的返回值
示例:
定义接口
package com.my.reflection01;
public interface HelloWorld {
public void SayHelloWorld();
}
接口 实现类
package com.my.reflection01;
public class HelloWorldImpl implements HelloWorld {
@Override
public void SayHelloWorld() {
// TODO 自动生成的方法存根
System.out.println("HelloWorld");
}
}
实现InvocationHandler接口,等同增强方法
package com.my.reflection01;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxyExample 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 {
// TODO 自动生成的方法存根
System.out.println("进入代理逻辑方法");
System.out.println("在调度真实对象之前得服务");
Object obj = method.invoke(target, args);
System.out.println("调度之后得服务");
return obj;
}
}
测试:
package com.my.reflection01;
public class TestJdkProxy {
public static void main(String args[]) {
JdkProxyExample jdk = new JdkProxyExample();
HelloWorld proxy = (HelloWorld)jdk.bind(new HelloWorldImpl());
proxy.SayHelloWorld();
}
}
二、基于子类的动态代理
要求:被代理类不能是最终类,不能被final修饰
提供者:第三方CGLIB
涉及类:Enhancer
创建代理对象的方法: create(Class , Callback)
参数:
Class:被代理对象的字节码
Callback: 如何代理。一个接口,一般是用MethodInterceptor 使用时也可或不创建匿名内部类。
但此种代理不多用。