代理模式
Spring AOP的底层 SpringAOP SpringMVC
1. 静态代理
-
抽象角色:接口、抽象类
-
真实角色:被代理的绝色
-
代理角色:代理真实角色
-
客户:访问代理对象
-
步骤
-
接口
//租房 public interface Rent { public void rent(); }
-
真实角色
//房东 public class Host implements Rent{ public void rent() { System.out.println("房东租房中..."); } }
-
代理角色
//房东 public class Host implements Rent{ public void rent() { 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 { public void add(); public void delete(); public void update(); public 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("查找商品"); } }
-
代理角色
//代理对象 public class UserServiceProxy implements UserService{ private UserServiceImpl userService; public void setUserService(UserServiceImpl userService) { this.userService = userService; } @Override public void add() { log("添加"); userService.add(); } @Override public void delete() { log("删除"); userService.delete(); } @Override public void update() { log("修改"); userService.update(); } @Override public void query() { log("查找"); userService.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.setUserService(userService); proxy.delete(); } }
纵向开发:dao --> service --> controller --> 客户端
业务拓展时横向开发,在 service 业务层增加(AOP实现机制)
2. 动态代理
- 与静态代理角色一样
- 动态代理的代理类是动态生成的
- 动态代理分为两大类:基于接口的动态代理、基于类的动态代理
- 基于接口 JDK动态代理
- 基于类 cglib
- java 字节码 javasist
- 优势
- 简化真实角色操作,无需关注公共业务
- 公共业务交给代理角色,实现业务分工
- 公共业务拓展时,方便集中管理
- 一个动态代理类代理的是一个接口,对应的一类业务
- 一个动态代理类可以代理多个类,只要实现同一接口即可
Proxy 代理
InvocationHandler 调用处理程序
-
接口
//租房 public interface Rent { public void rent(); }
-
真实角色
//房东 public class Host implements Rent { public void rent() { System.out.println("房东租房中..."); } }
-
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); } //处理代理实例并返回 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { seeHouse(); //动态代理的本质:反射机制 Object result = method.invoke(rent, args); fare(); contract(); return result; } //带租客看房 public void seeHouse(){ System.out.println("中介带租客看房中..."); } //收中介费 public void fare(){ System.out.println("收中介费..."); } //签合同 public void contract(){ System.out.println("签合同中..."); } }
-
客户端
public class Client { public static void main(String[] args) { //真实角色 Host host = new Host(); //代理角色 ProxyInvocationHandler pih = new ProxyInvocationHandler(); //通过调用程序处理角色 处理 需要调用的接口 pih.setRent(host); Rent proxy = (Rent)pih.getProxy(); //动态生成 proxy.rent(); } }
工具类
package com.yl.demo04;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//自动生成代理类
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);
}
//处理代理实例并返回
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动态代理的本质:反射机制
Object result = method.invoke(target, args);
log(method.getName());
return result;
}
public void log(String msg){
System.out.println("执行了" + msg + "操作");
}
}
import com.yl.demo02.UserService;
import com.yl.demo02.UserServiceImpl;
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();
}
}