java代理模式(23种设计模式之一)
静态代理角色分析:
1、抽象角色:一般使用接口或者抽象类来解决
2、真实角色:被代理的角色
3、代理角色:代理真实角色,代理真实角色后,我们会做一些附属操作
4、客户:访问代理对象的 人
代理模式好处:
1、可以使真实角色的操作更加纯粹,不用去关注一些公共的业务
2、公共业务交给代理角色,实现业务分工!
3、公共业务发生拓展时,方便集中管理
缺点:
一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率会变低。
动态代理:
1、动态代理和静态代理角色一样
2、动态代理的代理类是动态生成的,不是我们写好的。
3、动态代理分为两大类:基于接口或者类的动态代理
基于接口的动态代理:JDK动态代理
基于类的动态代理:cglib
java字节码实现:javasist
动态代理好处:
1、可以使真实角色的操作更加纯粹,不用去关注一些公共的业务!
2、公共业务交给了代理角色,实现了业务的分工!
3、公共业务发生拓展时,方便集中管理
4、一个动态代理类代理的是一个接口,一般就是对应一类业务
5、一个动态代理类可以代理多个类,只要是实现了同一个接口即可
使用JDK动态代理:
用到的类与接口:Proxy类、InvocationHandler接口
UserService接口:
public interface UserService { public void add(); public void del(); public void alt(); public void sel(); }
UserServiceImpl类,实现了UserService接口:
public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("增加一个用户"); } @Override public void del() { System.out.println("删除一个用户"); } @Override public void alt() { System.out.println("修改一个用户"); } @Override public void sel() { System.out.println("查询一个用户"); } }
生存动态代理类的处理程序:
public class MyProxyInvocationHandler 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); } //处理代理实例并返回结果 @Override public Object invoke(Object proxy,Method method,Object[] args) throws InvocationTargetException, IllegalAccessException { log(method.getName()); //调用增加的业务逻辑 Object result = method.invoke(target,args); return result; } public void log(String msg){ //增加的业务逻辑 System.out.println("执行了:"+msg+"方法"); } }
客户Client测试类:
public class Client { @Test public void test(){ UserServiceImpl userService = new UserServiceImpl(); //真实角色 MyProxyInvocationHandler myProxyInvocationHandler = new MyProxyInvocationHandler(); //创建自己写的处理程序用来生成代理角色 myProxyInvocationHandler.setTarget(userService); //设置要代理的对象 UserService proxy = (UserService) myProxyInvocationHandler.getProxy(); //动态生成代理对象 proxy.add(); } }