使用一个代理对象将对象包装起来,然后用该代理对象来取代该对象,任何对原始对象的调用都要通过代理,代理对象决定是否以及何时调用原始对象的方法 静态代理
标准的静态代理模式需要定义一个接口,然后被代理对象与代理对象均需要重写接口方法,被代理对象本身只需要实现真正的业务逻辑,而代理对象中的方法需要调用被代理对象的方法,且可以在调用前后新增一些其他逻辑处理。
代理对象中需要显式声明被代理对象,也就是需要持有被代理对象的引用,一般通过代理对象的构造器传入被代理对象,以达到持有被代理对象的目的
interface MyInterface {
void test();
}
class MyImplement implements MyInterface {
@Override
public void execute() {
System.out.println("我自己的逻辑...");
}
}
//代理类
class MyProxy implements MyInterface {
private MyInterface myInterface;
//构造器注入要代理的类
public MyProxy (MyInterface myInterface) {
this.myInterface= myInterface;
}
@Override
public void test() {
System.out.println("前拦截...");
myInterface.test();
System.out.println("后拦截...");
}
}
//使用
MyInterface myInterface= new MyProxy(new MyImplement ());
myInterface.test();
前拦截...
我自己的逻辑...
后拦截...
动态代理
定义的代理对象必须要实现java.lang.reflect.InvocationHandler接口被代理对象必须要显示的实现至少一个接口(不能继承),或者自身是一个接口, 不能继承
public interface MyInterface {
public void test();
}
class MyImplement implements MyInterface{
@Override
public void test() {
System.out.println("我自己的逻辑");
}
}
class Invocation implements InvocationHandler, Serializable{
//代理对象
private Object target;
//动态生成代理对象
public Object getInstance(Object target){
this.target = target;
Class> clazz = target.getClass();
return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前拦截");
Object obj = method.invoke(target, args);
System.out.println("后拦截");
return obj;
}
}
//测试
MyInterface proxyMy = (MyInterface) new Invocation().getInstance(new MyImplement());
proxyMy.test();
//结果
前拦截
我自己的逻辑
后拦截
mybatis中代理mapper:
public class MapperRegistry {
//使用Map来存放
private final Map, MapperProxyFactory>> knownMappers = new HashMap<>();
//获取代理对象
@SuppressWarnings("unchecked")
public T getMapper(Class type) {
final MapperProxyFactory mapperProxyFactory = (MapperProxyFactory) knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new RuntimeException("Type " + type + " is not known to the MapperRegistry.");
}
try {
return mapperProxyFactory.newInstance();
} catch (Exception e) {
throw new RuntimeException("Error getting mapper instance. Cause: " + e, e);
}
}
//添加代理对象
public void addMapper(Class type) {
if (type.isInterface()) {
if (hasMapper(type)) {
throw new RuntimeException("Type " + type + " is already known to the MapperRegistry.");
}
boolean loadCompleted = false;
try {
knownMappers.put(type, new MapperProxyFactory<>(type));
loadCompleted = true;
} finally {
if (!loadCompleted) {
knownMappers.remove(type);
}
}
}
}
//是否有代理对象
public boolean hasMapper(Class type) {
return knownMappers.containsKey(type);
}
}
//mapper代理工厂
public class MapperProxyFactory {
private final Class mapperInterface;
public MapperProxyFactory(Class mapperInterface) {
this.mapperInterface = mapperInterface;
}
protected T newInstance(MapperProxy mapperProxy){
return (T)Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, mapperProxy);
}
public T newInstance(){
MapperProxy mapperProxy = new MapperProxy<>(mapperInterface);
return newInstance(mapperProxy);
}
}
//InvocationHandler,代理对象执行类,代理对象执行逻辑在invoke
public class MapperProxy implements InvocationHandler, Serializable {
private final Class mapperInterface;
//这里可以有其他参数, 在构造器中赋值
public MapperProxy(Class mapperInterface){
this.mapperInterface = mapperInterface;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("参数: " + args[0]) ;
System.out.println("执行的方法: " + method);
System.out.println("开始处理逻辑...");
return null;
}
}
//代码测试,建一个用户Mapper
public interface UserMapper {
public void addUser();
public void deleteUser(Integer id);
}
public class ProxyTest {
public static void main(String[] args) {
//前面2步,项目启动的时候就会注册,遍历@MapperScan下的.class
MapperRegistry mapperRegistry = new MapperRegistry();
mapperRegistry.addMapper(UserMapper.class);
final UserMapper mapper = mapperRegistry.getMapper(UserMapper.class);
mapper.deleteUser(2);
}
}
//结果
参数: 2
执行的方法: public abstract void base.proxy.UserMapper.deleteUser(java.lang.Integer)
开始处理逻辑...



