代理模式
描述
说到代理模式,Spring AOP 就是一种基于动态代理的实现。
基于原有方法进行功能增强的一种模式。
基本使用
- 定义原有业务接口
java
public interface IService {
void action();
}
- 定义原有业务类
java
public class DefaultService implements IService{
@Override
public void action() {
System.out.println("action.....");
}
}
- 定义代理类(直接在代理类中增强)
java
public class ProxyService implements IService{
private IService service;
public ProxyService() {
this.service = new DefaultService();
}
@Override
public void action() {
this.actionBefore();
service.action();
}
private void actionBefore() {
System.out.println("actionBefore...");
}
}
- 基于已有的增强接口增强(接口的本质就是能力,如果一个类要使用一个能力,则实现这个接口即可)
java
public interface IProxy {
void ens();
}
java
public class EnsProxyService implements IService, IProxy {
private IService service;
public EnsProxyService() {
this.service = new DefaultService();
}
@Override
public void action() {
this.ens();
service.action();
}
@Override
public void ens() {
System.out.println("ens...");
}
}
使用
java
public class Sample {
public static void main(String[] args) {
IService service = new ProxyService();
service.action();
}
}
动态代理
所谓动态代理,不必在编码阶段把代理类生成出来,而是代码运行时,动态创建的代理对象。
基于JDK的动态代理
基于JDK的动态代理,需要代理的类必须声明接口。
- 声明接口
java
public interface IBizService {
void biz();
}
- 声明实现类
java
public class DefaultBizService implements IBizService{
@Override
public void biz() {
System.out.println("biz....");
}
}
- 基于JDK动态代理接口声明代理规则
java
public class BizInvocationHandler implements InvocationHandler {
private Object obj;
// 传入要代理的对象
public BizInvocationHandler(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invoke before...");
Object result = method.invoke(obj, args);
System.out.println("invoke after...");
return result;
}
}
- 使用
java
public class Sample {
public static void main(String[] args) {
IBizService bizService = new DefaultBizService();
IBizService proxyInstance = (IBizService) Proxy.newProxyInstance(bizService.getClass().getClassLoader(), bizService.getClass().getInterfaces(), new BizInvocationHandler(bizService));
proxyInstance.biz();
}
}
- 创建代理对象的过程实际还能封装(具有业务含义的封装需与对应的BizInvocationHandler绑定)
- 声明通用接口
java
public interface IdyProxy<T> {
T getProxy(T obj);
}
- 声明绑定handler的具体接口
java
public class BizDyProxy<T> implements IdyProxy<T> {
@Override
public T getProxy(T obj) {
T proxyInstance = (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new BizInvocationHandler(obj));
return proxyInstance;
}
}
- 使用
java
public class Sample {
public static void main(String[] args) {
IBizService bizService = new DefaultBizService();
// IBizService proxyInstance = (IBizService) Proxy.newProxyInstance(bizService.getClass().getClassLoader(), bizService.getClass().getInterfaces(), new BizInvocationHandler(bizService));
// proxyInstance.biz();
BizDyProxy<IBizService> dyProxy = new BizDyProxy<>();
IBizService proxy = dyProxy.getProxy(bizService);
proxy.biz();
}
}