动态代理(基于JDK的动态代理和基于CGLIB的动态代理)
建议订阅博主专栏,从下到上系统手写spring源码,体会其中过程!
AopProxy是获取代理对象的抽象接口,JdkDynamicAopProxy的基于JDK动态代理的具体实现。TargetSource,被代理对象的封装。MethodInterceptor,方法拦截器,是AOP Alliance的"公民",顾名思义,可以拦截方法,可在被代理执行的方法前后增加代理行为。
基于CGLIB的动态代理实现逻辑也比较简单,查看CglibAopProxy。与基于JDK的动态代理在运行期间为接口生成对象的代理对象不同,基于CGLIB的动态代理能在运行期间动态构建字节码的class文件,为类生成子类,因此被代理类不需要继承自任何接口。
前置知识:MethodMatcher methodMatcher = new AspectJExpressionPointcut("execution(* org.springframework.test.service.WorldService.explode(..))").getMethodMatcher();
根据表达式能匹配到类和方法。
基于JDK的动态代理
- TargetSource:被代理的目标类,该类主要对需要代理的类进行包装。
public class TargetSource {
private final Object target;
public TargetSource(Object object){
this.target = object;
}
//表示目标对象实现的接口数组
public Class<?>[] getTargetClass(){
return this.target.getClass().getInterfaces();
}
public Object getTarget(){
return this.target;
}
}
- MethodMatcher:方法匹配接口,用来接收表达式能匹配到的全部类和方法。
public interface MethodMatcher {
/**
* 方法匹配
* @param method
* @param targetClass
* @return
*/
boolean matches(Method method, Class<?> targetClass);
}
- AdvisedSupport:该类是它用于支持和管理代理对象的相关配置和信息,还包括目标对象和匹配类信息,后面获取这些对象都是在这个类中获取。
public class AdvisedSupport {
/**
* 被代理对象
*/
private TargetSource targetSource;
/**
* 方法拦截器是一种在方法调用前后进行额外逻辑处理的机制
*/
private MethodInterceptor methodInterceptor;
/**
* 方法匹配
*/
private MethodMatcher methodMatcher;
public TargetSource getTargetSource(){
return this.targetSource;
}
public void setTargetSource(TargetSource targetSource){
this.targetSource = targetSource;
}
public MethodInterceptor getMethodInterceptor(){
return this.methodInterceptor;
}
public void setMethodInterceptor(MethodInterceptor methodInterceptor){
this.methodInterceptor = methodInterceptor;
}
public MethodMatcher getMethodMatcher(){
return this.methodMatcher;
}
public void setMethodMatcher(MethodMatcher methodMatcher){
this.methodMatcher = methodMatcher;
}
}
- AopProxy:代理接口,提供获取代理对象的接口。
- JdkDynamicAopProxy:这个类实现了AopProxy, InvocationHandler能够获取代理对象,和提供代理的对象有方法被调用时,会触发invoke方法,在这里面可以对方法进行增强,其中ReflectiveMethodInvocation类是对目标类进行包装,MethodInterceptor.invoke会调用我们定义的切面方法。
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {
private final AdvisedSupport advised;
public JdkDynamicAopProxy(AdvisedSupport advised){
this.advised = advised;
}
/**
* 被代理的对象(该对象)有方法被调用时,会触发该方法
* @return
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//判读被代理的对象中执行的方法,是不是我们规定匹配的方法
if(advised.getMethodMatcher().matches(method,advised.getTargetSource().getTarget().getClass())){
//代理方法
MethodInterceptor methodInterceptor = advised.getMethodInterceptor();
return methodInterceptor.invoke(new ReflectiveMethodInvocation(advised.getTargetSource().getTarget(),method,args));
}
//如果执行的不是代理方法,直接执行,不做增强
return method.invoke(advised.getTargetSource().getTarget(), args);
}
/**
* 返回代理对象
* @return
*/
@Override
public Object getProxy() {
//ClassLoader loader,
//Class<?>[] interfaces,
//InvocationHandler h 传入这个类
return Proxy.newProxyInstance(getClass().getClassLoader(),advised.getTargetSource().getTargetClass(),this);
}
}
基于CGLIB的动态代理
- CGLIB的动态代理是基于Enhancer来生成的对象,具体和上面差不多。
public class CglibAopProxy implements AopProxy{
private final AdvisedSupport advised;
public CglibAopProxy(AdvisedSupport advised){
this.advised = advised;
}
@Override
public Object getProxy() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(advised.getTargetSource().getTarget().getClass());
enhancer.setInterfaces(advised.getTargetSource().getTargetClass());
//设置Callback
enhancer.setCallback(new DynamicAdvisedInterceptor(advised));
return enhancer.create();
}
private static class DynamicAdvisedInterceptor implements MethodInterceptor {
private final AdvisedSupport advised;
public DynamicAdvisedInterceptor(AdvisedSupport advised){
this.advised = advised;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
CglibMethodInvocation methodInvocation = new CglibMethodInvocation(advised.getTargetSource().getTarget(), method, objects, methodProxy);
if (advised.getMethodMatcher().matches(method, advised.getTargetSource().getTarget().getClass())) {
//代理方法
return advised.getMethodInterceptor().invoke(methodInvocation);
}
return methodInvocation.proceed();
}
}
/**
* 目标对象封装类
*/
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
private final MethodProxy methodProxy;
private Object target;
private Object[] arguments;
public CglibMethodInvocation(Object target, Method method, Object[] arguments, MethodProxy methodProxy) {
super(target, method, arguments);
this.methodProxy = methodProxy;
this.target = target;
this.arguments = arguments;
}
@Override
public Object proceed() throws Throwable {
return this.methodProxy.invoke(this.target, this.arguments);
}
}
}