动态代理
相对于静态代理,动态代理在创建代理对象上更加的灵活,动态代理类的字节码在程序运行时,由java反射机制动态产生。它会根据需要,通过反射机制在程序运行期,动态的为目标对象创建代理对象,无需手动编写源代码。动态代理简化了编程工作,提高了软件系统的可扩展性,因为反射机制可以生成任意类型的动态代理。代理的行为可以代理多个方法,即满足生产需要的同时又达到代码通用的目的。
动态代理的两种实现方式:
1. JDK 动态代理
2. CGLIB动态代理
-
动态代理的特点
- 目标对象不固定
- 在应用程序执行时动态创建目标对象
- 代理对象会增强目标对象的行为
JDK 动态代理
注:JDK 动态代理的目标对象必须有接口实现
-
JDK 动态代理
- 定义接口
public interface RentHouse {
public String toRentHouse(String name);
}
- 目标对象
public class ZuKe implements RentHouse{
@Override
public String toRentHouse(String name) {
System.out.println("我要租房,预算5000");
return "签名:"+name;
}
}
- 代理对象
public class JdkProxy {
//目标对象
private Object object;
//构造注入
public JdkProxy(Object object) {
this.object = object;
}
/**
* 通过调用proxy代理类中的newProxyInstance(),得到代理对象
* @return
*/
public Object getProxy(){
//定义ClassLoader类加载器
ClassLoader loader = this.getClass().getClassLoader();
//要代理的对象提供的接口数组
Class<?>[] interfaces = object.getClass().getInterfaces();
//一个InvocationHandler接口,表示代理实例的调用处理程序实现的接口。
InvocationHandler invocationHandler = new InvocationHandler() {
/**
* 当代理对象调用方法时,invoke方法就会被执行一次(InvocationHandler接口中的invoke方法)
* @param proxy 代理对象
* @param method 目标方法
* @param args 目标方法所需要的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("方法执行前。。。。");
//调用目标对象中的方法 通过反射中的invoke方法,调用指定对象的指定方法
/**
* 反射invoke方法
* 方法名.invoke(对象,方法所需参数);
*/
Object s = method.invoke(object,args);
System.out.println("方法执行后。。。。");
//return的是方法的返回值(目标对象里面的方法)
return s;
}
};
//调用方法,得到代理对象
Object instance = Proxy.newProxyInstance(loader, interfaces, invocationHandler);
return instance;
}
- 测试
public class App {
public static void main( String[] args ) {
//目标对象
RentHouse rentHouse = new ZuKe();
//得到代理对象
JdkProxy proxy = new JdkProxy(rentHouse);
//通过代理对象得到方法
RentHouse rentHouseProxy = (RentHouse)proxy.getProxy();
String name = "小明";
String s = rentHouseProxy.toRentHouse(name);
System.out.println(s);
}
}
网友评论