动态代理:为其它对象提供一种代理以控制对这个对象的访问。
在程序运行期间,通过反射创建出来的代理类。
JDK动态代理,顾名思义是jdk为我们提供的。jdk动态代理中必须了解的一个类和一个接口:Proxy类和InvocationHandler接口:
先看InvocationHandler接口:
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
该接口只有一个invoke方法,有三个参数:
proxy:代理类对象
method:被代理方法
args:被代理方法的参数列表
而Proxy类我们用到的方法便是newProxyInstance方法:
public class Proxy implements java.io.Serializable {
...
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
...
}
也是有三个参数:
loader:类加载器
interfaces:代理类实现的所有接口
h:InvocationHandler接口的一个实例,此类中必须存在InvocationHandler接口实现类的引用
例如:
/**
* Engineer:类加载器,是一个接口
* handler:代理实例的代理程序
*/
Engineer proxy = (Engineer) Proxy.newProxyInstance(Engineer.class.getClassLoader(), new Class[]{Engineer.class}, handler);
通过Proxy的newProxyInstance方法创建出代理对象,再有代理对象的执行方法。
jdk动态代理只支持委托类和代理类实现共同的接口的方式。如果实现共同的父类的情况,不能使用jdk动态代理,可以使用cglib动态代理。
cglib动态代理:
1.定义一个被代理的目标类(cglib不需要定义接口)
public class HelloService {
public void sayHello(){
System.out.println("hello heyifeng");
}
}
2.定义Proxy类,需要继承MethodInterceptor,实现intercept方法(MethodInterceptor类中只有intercept一个方法):
该代理的目的实在被代理目标类方法前后加入切面方法。
public class HelloMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("Before:"+method.getName());
//目标类执行的方法
Object object = methodProxy.invokeSuper(o, objects);
System.out.println("After:"+method.getName());
return object;
}
}
3.Client测试:
public class Client {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(HelloService.class); //继承被代理类
enhancer.setCallback(new HelloMethodInterceptor()); //设置回调
HelloService helloService = (HelloService) enhancer.create(); //增强的目标类,生成代理对象
helloService.sayHello();
}
}