代理回顾
Spring代理与责任链中讲到代理:JDK代理、Cglib代理,核心是使用Proxy.newProxyInstance方法生成一个接口的代理实例
原生jdk代理代码示例:
public interface BrandMapper {
List getAll();
}
public class DefaultBrandMapper implements BrandMapper {
@Override
public List getAll() {
System.out.println("DefaultBrandMapper....");
return null;
}
}
//代理都需要实现InvocationHandler,被代理接口所有方法的执行都会进入代理的invoke方法
public class MapperProxy<T> implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//这里为什么会有一个if判断
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
}
System.out.println("进入代理1:" + method);
//这里的proxy就是main函数中brandMaper指向的一个Proxy实例,下面的打印会调用brandMapper.toString(),由于被代理又进入invoke,若没有上述if,就会递归
System.out.println("进入代理2:" + proxy);
//执行DefaultBrandMapper实例的method方法
method.invoke(new DefaultBrandMapper(),args);
return null;
}
@Override
public String toString() {
System.out.println("MapperProxy toString");
return "111";
}
}
public class MapperProxyFactory<T> {
private final Class<T> mapperInterface;
public MapperProxyFactory(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
}
}
public class ProxyTest {
public static void main(String[] args) {
MapperProxyFactory mapperProxyFactory = new MapperProxyFactory(BrandMapper.class);
BrandMapper brandMapper = (BrandMapper) mapperProxyFactory.newInstance(new MapperProxy<BrandMapper>());
brandMapper.getAll();
}
}
再看注释
/**
* Returns an instance of a proxy class for the specified interfaces
* that dispatches method invocations to the specified invocation
* handler.
* 为指定的接口返回Proxy类型的实例,该Proxy实例将方法调用发送到指定的
* InvocationHandler的invoke方法
*/
Object Proxy::newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
/**
* proxy the proxy instance that the method was invoked on
* proxy类型的实例,方法被调用在该实例上。就是上面newProxyInstance的返回值
*/
Object InvocationHandler::invoke(Object proxy, Method method, Object[] args)