前言
前面我们已经讲到了singletonFactories的作用和在初始化后增强的一个阶段中会将bean变成一个代理bean,创建代理bean的流程中会看到如下源码:
所以spring中创建代理对象有两种方式:Cglib和JdkDynamic,使用代码示例来感受下这两种方式是如何创建代理和调用接口的
Jdk代理
只能对接口进行代理(newProxyInstance的第二个参数决定),生成一个接口的匿名类,匿名类拥有InvocationHandler的引用,Jdk动态代理只是想在调用目标类的方法前再加一层逻辑。至理名言:没有什么是加入一层解决不了的
public class JdkProxy {
static class ProxyHandler implements InvocationHandler {
private Object targetObject;
public ProxyHandler(Object targetObject) {
this.targetObject = targetObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("这里有个切面");
return method.invoke(targetObject,args);
}
}
public static final Object createProxy(Object targetObject) {
return Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), targetObject.getClass().getInterfaces(), new ProxyHandler(targetObject));
}
public static void main(String[] args) {
User userA = (User)JdkProxy.createProxy(new UserA());
userA.f1();
User userB = (User)JdkProxy.createProxy(new UserB());
userB.f1();
}
}
运行结果与上一篇文章中使用切面的效果相同,createProxy为目标类的所有接口实现一个匿名类,且匿名类的实例拥有InvocationHandler对应的实例。通过反射在调用匿名类的任何接口时都会进入invoke方法,使得目标类的方法被调用前都能被拦截,并加入一层逻辑
Cglib代理
能对接口和类进行代理,生成代理的子类,生成的子类拥有MethodInterceptor的引用,通过反射调用任何接口时都会进入intercept方法,使得目标类的方法被调用前都能被拦截,并加入一层逻辑
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy {
static class ProxyHandler implements MethodInterceptor {
private Object targetObject;
public ProxyHandler(Object targetObject) {
this.targetObject = targetObject;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("这里有个切面");
return method.invoke(targetObject,objects);
}
}
public static final Object createProxy(Object targetObject) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetObject.getClass());
enhancer.setCallback(new ProxyHandler(targetObject));
return enhancer.create();
}
public static void main(String[] args) {
User userA = (User) CglibProxy.createProxy(new UserA());
userA.f1();
User userB = (User) CglibProxy.createProxy(new UserB());
userB.f1();
}
}
责任链模式
上面讲的代理与Spring Aop有很强的关联,在学习Aop之前先温习一下责任链模式。责任链模式在spring中有广泛的应用,http请求过滤、spring security权限过滤、aop切面顺序调用等都会涉及
责任链模式:
示例代码:
public interface MethodAdvice {
Object proceed(MethodInterceptorChain chain) throws Throwable;
}
public class MethodInterceptorChain{
//拥有拦截器链条
List<MethodAdvice> chains = new ArrayList<>();
private TargetMethod targetMethod;
int index = 0;
public void addInterceptor(MethodAdvice method){
chains.add(method);
}
public Object proceed() throws Throwable {
if(index == chains.size()){
return targetMethod.method.invoke(targetMethod.targetObject,targetMethod.args);
}else{
//顶层遍历拦截器
return chains.get(index++).proceed(this);
}
}
static class TargetMethod{
private Object targetObject;
private Method method;
private Object[] args;
}
static class ProxyHandler implements MethodInterceptor {
private Object targetObject;
private MethodInterceptorChain chain;
public ProxyHandler(Object targetObject,MethodInterceptorChain chain) {
this.targetObject = targetObject;
this.chain = chain;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
TargetMethod targetMethod = new TargetMethod();
targetMethod.method = method;
targetMethod.targetObject = this.targetObject;
targetMethod.args = objects;
this.chain.targetMethod = targetMethod;
//链条调用触发
return this.chain.proceed();
}
}
public Object createProxy(Object targetObject) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetObject.getClass());
enhancer.setCallback(new ProxyHandler(targetObject,this));
return enhancer.create();
}
public static void main(String[] args) {
MethodInterceptorChain chain = new MethodInterceptorChain();
User userA = (User) chain.createProxy(new UserA());
chain.addInterceptor(chain1 -> {
System.out.println("around 之前");
Object ret = chain1.proceed();
System.out.println("around 之后");
return ret;
});
chain.addInterceptor((chain1 -> {
System.out.println("before...");
return chain1.proceed();
}));
chain.addInterceptor(chain1 -> {
Object ret = null;
try {
ret = chain1.proceed();
} finally {
System.out.println("after...");
}
return ret;
});
chain.addInterceptor(chain1 -> {
Object ret = chain1.proceed();
System.out.println("afterReturning...");
return ret;
});
chain.addInterceptor(chain1 -> {
Object ret = null;
try {
ret = chain1.proceed();
} catch (Throwable e) {
System.out.println("afterThrowing...");
}
return ret;
});
userA.f1();
}
}
运行效果
可以看出与Aop中几个注解的顺序是一致的