一、静态代理模式
所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了
举例理解:以租房为例,房东只需要处理自己的房子交给中介即可,其余的都是由中介充当代理进行租客签协议,带租客看房子,等等。
1.静态代理需要满足三点
1、需要有真实角色 2、需要有一个代理角色 3、这两个角色之间必须实现相同的接口
2.静态代理类优缺点
优点:真实角色也就是业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。 缺点: 1)代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。 2)如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。
3.代码详解
1.生成一个接口
Rent.class
public interface Rent {
void rent();
}
2.房东实现接口
Host…class
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房东出租房子");
}
}
3.一个代理
Proxy.class
public class Proxy {
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
public void rent(){
host.rent();
see();
}
public void see(){
System.out.println("带租赁看房子");
}
}
4.实现租房
public class Client {
public static void main(String[] args) {
Host host = new Host();
Proxy proxy = new Proxy(host);
proxy.rent();
}
}
二、动态代理模式
代理类在程序运行时创建的代理方式被成为动态代理。动态代理,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。相比于静态代理, 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类中的方法。
动态代理的实现
在java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过这个类和这个接口可以生成JDK动态代理类和动态代理对象。
public class ProxyInvocationHandler implements InvocationHandler {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
public static void log(String message){
System.out.println("执行了"+message+"方法");
}
@Override
public java.lang.Object invoke(java.lang.Object proxy, Method method, java.lang.Object[] args) throws Throwable {
log(method.getName());
java.lang.Object result = method.invoke(target, args);
return result;
}
}
上面的代码就是一个万能的动态代理的代码,使用上面的代码就可以实现动态代理了 下面就是演示如何的使用动态的代理模式还是使用上面静态上面写的接口以及房东(Host)
public class Client {
public static void main(String[] args) {
Host host = new Host();
ProxyInvocationHandler pip = new ProxyInvocationHandler();
pip.setTarget(host);
Rent proxy = (Rent) pip.getProxy();
proxy.rent();
}
}
|