Spring-课题相关-代理模式
代理模式
为什么要学习代理模式?
因为这就是SpringAOP的底层
【SpringAOP和SpringMVC】
代理模式的分类:
- 静态代理
- 动态代理
1、静态代理
角色分析:
- 抽象角色:一般会使用接口或者抽象类来结局
- 真实角色:被代理的角色
- 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
- 客户:访问代理对象的人
代码步骤:
-
接口
public interface Rent { void rent(); } -
真实角色(被代理)
public class Host implements Rent{ @Override public void rent() { System.out.println("房东要出租房子"); } } -
代理角色
public class Proxy implements Rent{ private Host host; public Proxy() { } public Proxy(Host host) { this.host = host; } @Override public void rent() { host.rent(); seeHouse(); fee(); hetong(); } // 看房 public void seeHouse(){ System.out.println("中介带你看房"); } // 收中介费 public void fee(){ System.out.println("收费"); } // 签合同 public void hetong(){ System.out.println("签租赁合同"); } } -
客户端访问代理角色
public class Client { public static void main(String[] args) { // 房东要出租房子 Host host = new Host(); // 代理 中介要帮房东出租房子,但是代理角色一般会有一些附属操作 Proxy proxy = new Proxy(host); // 你不用面对房东,直接找中介租房即可 proxy.rent(); } }
代理模式的好处:
- 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务
- 公共业务就交给代理角色,实现了业务的分工
- 公共业务发生扩展的时候,方便集中管理
缺点:
- 一个真实角色就会缠身一个代理角色,代码量会翻倍,开发效率会变低
加深理解代理模式
-
抽象角色(需要完成的事项)
public interface UserService { void add(); void delete(); void update(); void query(); } -
真实角色(需要完成事项的人)
// 真实对象 public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("增加了一个用户"); } @Override public void delete() { System.out.println("删除了一个用户"); } @Override public void update() { System.out.println("更新了一个用户"); } @Override public void query() { System.out.println("查询用户"); } // 为什么不能改变原有业务代码 // 1.改动原有的业务代码,在公司中是大忌! } -
代理角色(帮需要完成事项的人完成事项并附带一些附属功能)
public class UserServiceProxy implements UserService{ private UserServiceImpl userServiceImpl; public void setUserServiceImpl(UserServiceImpl userServiceImpl) { this.userServiceImpl = userServiceImpl; } @Override public void add() { log("add"); userServiceImpl.add(); } @Override public void delete() { log("delete"); userServiceImpl.delete(); } @Override public void update() { log("update"); userServiceImpl.update(); } @Override public void query() { log("query"); userServiceImpl.query(); } // 日志方法 public void log(String msg){ System.out.println("使用了" + msg + "方法"); } } -
客户(要求代理角色完成工作的人)
public class Client { public static void main(String[] args) { UserServiceImpl userService = new UserServiceImpl(); UserServiceProxy proxy = new UserServiceProxy(); proxy.setUserServiceImpl(userService); proxy.add(); } }
2、动态代理
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是我们直接写好的
- 动态代理分为两大类:1.基于接口的动态代理、2.基于类的动态代理
- 基于接口 --- JDK 动态代理
- 基于类 --- cglib
- java字节码实现:javassist
需要了解两个类:Proxy:代理、InvocationHandler:调用处理程序
-
抽象角色(接口)
public interface UserService { void add(); void delete(); void update(); void query(); } -
真实角色(实现类)
// 真实对象 public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("增加了一个用户"); } @Override public void delete() { System.out.println("删除了一个用户"); } @Override public void update() { System.out.println("更新了一个用户"); } @Override public void query() { System.out.println("查询用户"); } // 为什么不能改变原有业务代码 // 1.改动原有的业务代码,在公司中是大忌! } -
(动态)代理角色(代理类)
// 我们会用这个类,自动生成代理类 public class ProxyInvocationHandler implements InvocationHandler { // Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), // new Class<?>[]{Foo.class}, // handler); // 被代理的接口 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 Throwable { log(method.getName()); // 动态代理的本质,就是使用反射机制实现 Object result = method.invoke(target, args); return result; } public void log(String msg){ System.out.println("调用了" + msg + "方法"); } } -
客户(实体类)
public class Client { public static void main(String[] args) { // 真实角色 UserServiceImpl userService = new UserServiceImpl(); // 代理角色:当前不存在 ProxyInvocationHandler pih = new ProxyInvocationHandler(); // 真实对象 pih.setTarget(userService); // 设置要代理的对象 // 动态生成代理类 UserService proxy = (UserService) pih.getProxy(); proxy.add(); } }
动态代理的好处:
- 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务
- 公共业务就交给代理角色,实现了业务的分工
- 公共业务发生扩展的时候,方便集中管理
- 一个动态代理类代理的是一个接口,一般就是对应的一类业务
- 一个动态代理类可以代理多个类,只要是实现了同一个接口即可

浙公网安备 33010602011771号