java设计模式之动态代理模式
一、解释说明(jdk动态代理)
动态代理就是在静态代理的基础上,把代理类动态生成了。
二、案例代码
1、抽象角色代码案例如下
package 设计模式.动态代理;
//明星(抽象角色)
public interface Star {
//唱歌
public void sing() throws Throwable;
}
2、真实角色代码案例如下
package 设计模式.动态代理;
//周杰伦(真实角色)
public class SuperStar implements Star{
@Override
public void sing() {
System.out.println("周杰伦在唱歌");
}
}
3、角色处理器代码如下
package 设计模式.动态代理;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//明星处理器(总管大人)
public class StarHandler implements InvocationHandler {
private Star star;
//把被代理的对象注入进来
public StarHandler(Star star){
this.star = star;
}
//总控方法,所有方法的拦截器
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("调用前加的事件");
method.invoke(star,args);
System.out.println("调用后加的事件");
return null;
}
}
4、客户端代码如下
package 设计模式.动态代理;
import java.lang.reflect.Proxy;
//客户端
public class Client {
public static void main(String[] args) throws Throwable {
//创建真实角色
Star star = new SuperStar();
//把真实角色注册到处理器中
StarHandler starHandler = new StarHandler(star);
//动态生成代理对象,代理对象的所有方法都会调用starHandler的invoke方法,以此达到拦截效果
Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, starHandler);
//调用方法
proxy.sing();
}
}
原理说明:
模拟动态生成的代理类大概代码如下
package 设计模式.动态代理;
import java.lang.reflect.Method;
//模拟动态生成的代理类
public class StarProxy implements Star{
private StarHandler starHandler;
//把处理器注册进来
public StarProxy(StarHandler starHandler){
this.starHandler = starHandler;
}
//所有的方法都转为调用处理器的方法
@Override
public void sing() throws Throwable {
starHandler.invoke(this, Star.class.getMethods()[0],null);
}
}
客户端调用代码如下
package 设计模式.动态代理;
//模拟的客户端
public class ClientOne {
public static void main(String[] args) throws Throwable {
//创建真实对象
Star star = new SuperStar();
//把真实对象注册到处理器中
StarHandler starHandler = new StarHandler(star);
//把处理器注册到代理对象中
StarProxy starProxy = new StarProxy(starHandler);
//调用方法
starProxy.sing();
}
}
三、适用场景
1、struts2中拦截器的实现
2、数据库连接池关闭处理
3、Hibernate延迟加载的实现
4、mybatis中实现拦截器插件
5、AspectJ的实现
6、spring中AOP的实现(日志拦截,声明式事务处理)
7、web service
8、RMI远程调用
四、优缺点
与静态代理类似,只不过代码耦合度降低了。
还没有评论,来说两句吧...