代理模式
客户端不直接访问目标对象,需要通过第三者来实现间接访问对象
代理对象在客户端和目标对象之间起中介作用,能够屏蔽目标对象不想让客户端知道的内容,或增加额外的服务
动态代理
JDK 动态代理:基于接口,利用 JDK API 动态地在内存中构建代理对象,从而实现目标对象的代理功能。称为 JDK 代理或接口代理。
JDK 动态代理例子
MapperInvocationHandler
实现InvocationHandler
接口,实现invoke
方法,该方法最终是代理类增强的目标类方法JDKProxyFactory
用于生成代理对象的工厂,通过调用Proxy.newProxyInstance
方法生成代理对象UserMapper
目标类,JDK 代理的目标类必须实现某个接口IUserMapper
目标类接口
MapperInvocationHandler
java
public class MapperInvocationHandler implements InvocationHandler {
// 动态的目标对象
private Object target;
public MapperInvocationHandler(Object target) {
this.target = target;
}
/**
* 增强方法
* @param proxy 代理实例
* @param method 目标方法
* @param args 目标方法参数
* @return 返回值
* @throws Throwable 异常
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("=========JDK 动态代理前置增强=========");
method.invoke(target, args);
System.out.println("=========JDK 动态代理后置增强=========");
return null;
}
}
JDKProxyFactory
java
public class JDKProxyFactory {
// 动态的目标对象
private Object target;
public JDKProxyFactory(Object target) {
this.target = target;
}
// 为目标对象生成代理对象
public Object getTargetProxy(){
return Proxy.newProxyInstance(
// 目标对象使用的类加载器
target.getClass().getClassLoader(),
// 目标对象实现的接口
target.getClass().getInterfaces(),
// 事件处理器
new MapperInvocationHandler(target)
);
}
}
IUserMapper
java
public interface IUserMapper {
void save();
}
UserMapper
java
public class UserMapper implements IUserMapper {
@Override
public void save() {
System.out.println("保存用户数据");
}
}
Client
java
public class Client {
public static void main(String[] args) {
JDKProxyFactory jdkProxyFactory = new JDKProxyFactory(new UserMapper());
IUserMapper userMapperProxy = (IUserMapper) jdkProxyFactory.getTargetProxy();
userMapperProxy.save();
}
}
运行结果
bash
=========JDK 动态代理前置增强=========
保存用户数据
=========JDK 动态代理后置增强=========
Process finished with exit code 0