Spring整理_04_代理模式
代理模式(SpringAOP的底层)
【springAOP和springMVC面试必问】
代理模式分类
- 静态代理
- 动态代理
静态代理
角色分析:
- 抽象角色:一般使用接口或者抽象类来解决
- 真实角色:被代理的角色
- 代理角色:代理真实角色,代理真实角色后,一般会做一些附属操作
- 客户:被代理对象·
代码步骤:
- 接口
- 真实角色
- 代理角色
- 客户访问代理角色
举例1:
接口:Rent.java
public interface Rent { void rent(); }
真实角色:Host.java
public class Host implements Rent { public void rent() { System.out.println("房东要租房子"); } }
代理角色:proxy.java
public class Proxy implements Rent { private Host host; public Proxy() { } public Proxy(Host host) { this.host = host; } public void rent() { seeHouse(); host.rent(); hetong(); fee(); } //看房 public void seeHouse(){ System.out.println("中介看房"); } //签租赁合同 public void hetong(){ System.out.println("签合同"); } //收房租 public void fee(){ System.out.println("收房租"); } }
客户访问代理角色:Client.java
public class Client{ public static void main(String[] args) { Host host = new Host(); Proxy proxy = new Proxy(host); proxy.rent(); } }

举例2
接口:UserService.java
public interface UserService { void add(); void delete(); void update(); void select(); }
真实角色:UserService.java
public class UserServiceImpl implements UserService { public void add() { System.out.println("增加了一个新用户"); } public void delete() { System.out.println("删除了一个新用户"); } public void update() { System.out.println("修改了一个新用户"); } public void select() { System.out.println("查询了一个新用户"); } }
代理角色:Proxy.java
public class Proxy implements UserService { UserService userService = new UserServiceImpl(); public void setUserService(UserService userService) { this.userService = userService; } public void add() { log(); userService.add(); } public void delete() { log(); userService.delete(); } public void update() { log(); userService.update(); } public void select() { log(); userService.select(); } public void log(){ System.out.println("我是日志"); } }
客户访问代理角色:Client.java
public class Client { public static void main(String[] args) { UserService userService = new UserServiceImpl(); Proxy proxy = new Proxy(); proxy.setUserService(userService); proxy.add(); proxy.update(); } }
代理模式好处:
- 可以使真实角色的操作更加纯粹,不用关注一些公共的业务
- 公共任务交给代理角色,实现了业务分工
- 公共业务发生扩展时,方便集中管理
缺点
- 一个真实的角色就会产生一个代理角色,使代码量翻倍,开发效率变低
动态代理
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是直接写好的
- 动态代理分为两类:基于接口的动态代理;基于类的动态代理
- 基于接口:jdk动态代理
- 基于类:cglib
- java字节码实现:javassist
需要了解两个类:
proxy:代理
InvocationHandler:调用处理程序(反射包下的接口)
InvocationHandler:
是由代理实例的调用处理程序实现的接口(人话:动态生成代理类)
invoke方法:
返回值:Object
参数:invoke(Object proxy,Method method,Object[] args)
- proxy:调用该方法的代理实例
- method:代理这个类(接口)中的哪一个方法
- args:方法里的参数
- 返回值:返回一个代理类
Proxy:
提供了创建动态代理类和实例的静态方法("类.静态方法"能创建一个实例)
示例代码:
InvocationHandler handler = new MyInvocationHandler(...); Class<?> proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(),Foo.class); Foo f = (Foo)proxyClass.getConstructor(InvocationHandler.class).newInstance(handler)
简单版:
Foo f = (Foo)Proxy.newProxyInstance(Foo.class.getClassLoador(),new Class<?>[]{Foo.class},handler)l;
举例1:
ProxyInvocationHandler:
//这个类会自动生成代理类 public class ProxyInvocationHandler implements InvocationHandler { //被代理的接口 private Rent rent; public void setRent(Rent rent) { this.rent = rent; } //生成代理类 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this); } //处理代理实例,并返回结果 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //动态代理的本质,就是使用反射机制实现 Object result = method.invoke(rent, args); return result; } }
Client:
public class Client { public static void main(String[] args) { //真实角色 Host host = new Host(); //代理角色 ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler(); //通过调用程序处理角色来处理我们要调用的接口对象 proxyInvocationHandler.setRent(host); //返回代理类 Rent proxy = (Rent) proxyInvocationHandler.getProxy();//这个proxy是自动生成的 proxy.rent(); } }
举例2:
工具类:
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 Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(target,args); return result; } }
Client.java
public class Client { public static void main(String[] args) { //真实角色 UserServiceImpl userService1 = new UserServiceImpl(); //代理角色 ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler(); proxyInvocationHandler.setTarget(userService1);//设置要代理的对象 UserService proxy = (UserService) proxyInvocationHandler.getProxy();//动态代理实现的是接口!!! proxy.delete(); } }
动态代理代理的是接口!!!

浙公网安备 33010602011771号