为解决静态代理中,类多、维护难的问题,有了动态代理
动态代理有以下特点:
1、代理对象不需要实现接口
2、代理对象的生成,利用了JDK自带的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口类型)
3、动态代理也叫做JDK代理、接口代理
JDK中实现代理只需要使用Proxy.newProxyInstance方法
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
loader:指定当前目标对象使用类加载器,获取加载器的方法是固定的
interfaces:目标对象实现的接口的类型,使用泛型方式确认类型
h:事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入
代理示例:
在【JAVA代理模式详解】之静态代理基础上,增加一个代理工厂类ProxyFactory
public class ProxyFactory {
// 目标对象
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
// 生成代理对象
public Object getProxyInstance() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object getProxyInstance() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), (proxy, method, args) -> {
System.out.println("动态代理:我是经纪人,我去安排歌手唱歌。");
Object ret = method.invoke(target, args);
System.out.println("动态代理:唱完了,请付款。");
return ret;
});
}
}
测试类:
public class ProxyMain {
public static void main(String[] args) {
// 目标对象
Singer singer = new SingerImpl();
// 代理对象
Singer proxy = (Singer) new ProxyFactory(singer).getProxyInstance();
proxy.sing();
}
}
输出结果:
总结:
相对于静态代理,动态代理中代理对象不需要实现接口,但是目标对象一定要实现接口,否则不能用动态代理。
为了解决动态代理中的问题,请参考【JAVA设计模式】代理模式之Cglib代理