系列文章目录
第一章 Spring之AOP-JDK动态代理源码解析
Spring之AOP-JDK动态代理源码解析
前言
主要介绍SpringAOP中JDK动态代理封装实现.
一、JDK动态代理
JDK动态代理使用Proxy类通过传入类加载器/ 接口类 /InvocationHandler实现类三个参数生成了一个代理对象,目的是用来对代理进行增强。
当使用代理对象调用被代理对象的方法时,会进入InvocationHandler的invoke的方法执行代理逻辑。
public class JDKProxyTest {
public static void main(String[] args) {
//被代理对象
User target = new User();
Proxy_interface proxyInstance = (Proxy_interface) Proxy.newProxyInstance(JDKProxyTest.class.getClassLoader(), new Class[]{Proxy_interface.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
//调用被代理对象的方法
method.invoke(target,args);
System.out.println("after");
return null;
}
});
proxyInstance.test();
}
}
结果打印:
before
3333
after
Process finished with exit code 0
二、Spring实现的JDK动态代理
1.基础代码案例
public class Spring_Proxy {
public static void main(String[] args) {
//被代理对象
User target = new User();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
//使用了jdk动态代理,不加这行代码,用的cglib动态代理
proxyFactory.setInterfaces(Proxy_interface.class);
//多个advice按顺序执行
//环绕
proxyFactory.addAdvice(new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("Around before");
Object obj = invocation.proceed();
System.out.println("Around after");
return obj;
}
});
//后置
proxyFactory.addAdvice(new AfterReturningAdvice() {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("after");
}
});
//前置
proxyFactory.addAdvice(new MethodBeforeAdvice() {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
//不用再执行invoke方法,被代理对象将自动执行
System.out.println("before");
}
});
//抛异常
proxyFactory.addAdvice(new ThrowsAdvice() {
/**
* * <pre class="code">public void afterThrowing(Exception ex)</pre>
* * <pre class="code">public void afterThrowing(RemoteException)</pre>
* * <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, Exception ex)</pre>
* * <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)</pre>
* @param returnValue
* @param method
* @param args
* @param target
* @param exception
*/
//自己加的方法,方法执行完执行再抛异常
//异常要匹配
public void afterThrowing(Method method, Object[] args, Object target, Exception ex){
System.out.println("Throwing......");
}
});
Proxy_interface user = (Proxy_interface) proxyFactory.getProxy();
user.test();
}
}
结果打印:
Around before
before
3333
after
Around after
Process finished with exit code 0
2.源码分析
2.1 AOP入口
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}
@EnableAspectJAutoProxy注解通过Import注解导入ImportBeanDefinitionRegistrar扩展点
AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,ImportBeanDefinitionRegistrar接口为ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法执行配置解析过程中解析@Import注解时变成BeanDefinition添加到BeanDefinitionMap
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
//指示是否要创建基于子类 (CGLIB) 的代理,而不是创建标准的基于 Java 接口的代理。默认值为false
boolean proxyTargetClass() default false;
//指示代理对象应该由 AOP 框架作为ThreadLocal公开,以便通过org.springframework.aop.framework.AopContext类进行检索。默认关闭,即不保证AopContext访问将起作用。
boolean exposeProxy() default false;
}
2.2 AspectJAutoProxyRegistrar类
AnnotationAwareAspectJAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor接口,该接口继承了BeanPostProcessor接口,也是为一个扩展点
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 注册名字为internalAutoProxyCreator的bean
//bean类为AnnotationAwareAspectJAutoProxyCreator
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
// 获得@EnableAspectJAutoProxy注解的属性值
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
//根据@EnableAspectJAutoProxy注解其中的proxyTargetClass/exposeProxy设置beanDefinition的属性
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
2.3 Bean生命周期初始化后生成代理Bean
AnnotationAwareAspectJAutoProxyCreator,当在进行Bean的生命周期的过程中,执行到初始化后时,会执行BeanPostProcessor的后置处理方法。postProcessAfterInitialization方法在其AbstractAutoProxyCreator父类中实现。
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
//获取缓存key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 如果是之前循环依赖创建过动态代理,则remove出来就是bean!=bean,不会去创建代理对象
// 如果之前没有出现循环依赖,则remove出来的值为null!=bean,会去创建代理对象
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 该方法将会返回动态代理实例
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
2.4 wrapIfNecessary创建动态代理
该方法判断是否需要进行创建动态代理,例如当没有找到匹配的advisor时不进行创建.
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//已经被处理过(解析切面时targetSourcedBeans出现过) 就是自己实现创建动态代理逻辑
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//不需要增强的
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//基础的bean(Advice PointCut Advisor AopInfrastructureBean)跳过
//当前bean是切面类需要跳过,例如@Aspect注解的类
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 根据当前bean找到所有匹配的advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 当前bean匹配到了advisor
if (specificInterceptors != DO_NOT_PROXY) {
// 标记为已处理
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//*****创建真正的代理对象*****
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
//加入到缓存
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
isInfrastructureClass方法:
protected boolean isInfrastructureClass(Class<?> beanClass) {
/**
* 当前正在创建的Beanclass为Advice PointCut Advisor AopInfrastructureBean直接跳过不需要解析
*/
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
存在ClassFilter执行matches匹配成功,为合格的advisor
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
createProxy创建动态代理
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
//创建一个代理对象工厂
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
//为proxyFactory设置创建jdk代理还是cglib代理
// 如果ProxyTargetClass为true,说明使用cglib,不是为jdk动态代理
if (!proxyFactory.isProxyTargetClass()) {
//确定给定的 bean 是否应该使用它的目标类而不是它的接口来代理。检查相应 bean 定义的"preserveTargetClass" attribute
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// 检查有没有接口,有接口使用jdk动态代理,没有接口使用cglib
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//specificInterceptors数组中的Advisor转化为数组形式的,specificInterceptors为查找出来匹配出来的所有advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
//代理工厂加入所有通知器advisor
proxyFactory.addAdvisors(advisors);
//设置targetSource对象
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
// 代表之前是否筛选advise.
// 因为继承了AbstractAdvisorAutoProxyCreator , 并且之前调用了findEligibleAdvisors进行筛选, 所以是true
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//真正的创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
JdkDynamicAopProxy#getProxy:最终创建的代理逻辑
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
2.5 getAdvicesAndAdvisorsForBean查找所有匹配的advisor
查找到匹配的advisor,则进行创建动态代理
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
/**
* 找到和当前bean匹配的advisor
*/
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
// 如果没找到不创建代理
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
findEligibleAdvisors方法:在当前 bean 工厂中查找所有符合条件的 Advisor bean,忽略 FactoryBeans 并排除当前正在创建的 bean。
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 容器中获取到实现了Advisor接口的实现类 (从缓存中拿)
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//判断我们的通知能不能作用到当前的类上(切点是否命中当前Bean),筛选Advisor Bean
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
//对我们的advisor进行排序
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
findCandidateAdvisors方法:通过两种方法进行查找匹配的advisor,一是Advisor代理方式(例如去Spring容器中获取到所有实现Advisor接口的实现类),二是AspectJ增强方式(即AspectJ注解方式)
/**
* 两种查找方式:
* Advisor代理方式 (@Transactional底层的方式)
* AspectJ增强方式
* @return
*/
@Override
protected List<Advisor> findCandidateAdvisors() {
// 找出xml配置的Advisor或者原生接口的AOP的Advisor 找出事务相关的advisor
List<Advisor> advisors = super.findCandidateAdvisors();
//找出Aspect相关的信息之后封装为一个advisor
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
//返回我们所有的通知
return advisors;
}
2.6 InvocationHandler的代理逻辑
当代理对象调用被代理对象的方法时,会进入invoke方法执行代理逻辑
/**
* Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
* InvocationHandler的实现类,当代理对象执行被代理对象的方法时会执行以下代理逻辑
* Implementation of {@code InvocationHandler.invoke}.
* <p>Callers will see exactly the exception thrown by the target,
* unless a hook method throws an exception.
*/
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
//获取到我们的目标对象
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
//被代理对象执行的equals方法不需要代理
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
//被代理对象执行的是hashCode方法 不需要代理
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
//被代理对象执行的class对象是DecoratingProxy 则不会对其应用切面进行方法的增强。返回源目标类型
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
// 被代理对象实现的Advised接口,则不会对其应用切面进行方法的增强。 直接执行方法
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
/**
* 暴露我们的代理对象到线程变量中,可在同一线程中执行不同方法,可以获取使用
*/
if (this.advised.exposeProxy) {
//把我们的代理对象暴露到线程变量中
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//获取被代理对象
target = targetSource.getTarget();
//获取被代理对象的class
Class<?> targetClass = (target != null ? target.getClass() : null);
//把被代理对象AOP的advisor全部转化为拦截器, 通过责任链模式来进行调用
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
//拦截器链为空
if (chain.isEmpty()) {
//通过反射直接调用执行
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
//创建一个方法调用对象,传入了所有的Advice,也就是传入了chain
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//调用执行
retVal = invocation.proceed();
}
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
2.7 Advice责任链调用
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
继续调用getInterceptorsAndDynamicInterceptionAdvice方法
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
//获取所有的Advisors进行筛选
for (Advisor advisor : config.getAdvisors()) {
//判断为PointcutAdvisor
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
//Pointcut中ClassFilter匹配 类匹配
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
//Pointcut的MethodMatcher匹配 方法匹配
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
//将advisor转化为MethodInterceptor
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
//还要判断MethodMatcher匹配isRuntime状态
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
//*******************************封装为InterceptorAndDynamicMethodMatcher对象,然后放入list*******************************
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
//不匹配isRuntime状态,直接放入list
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
//判断为IntroductionAdvisor
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
//其他
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
registry.getInterceptors适配方法,将所有的advice
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
//都是MethodInterceptor类型的advice
List<MethodInterceptor> interceptors = new ArrayList<>(3);
//获取advisor中的advise,此处
Advice advice = advisor.getAdvice();
//判断是否为MethodInterceptor实例,是就强转
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
//不是就去适配
/**
* 注册三个适配器,这三个适配器都实现了MethodInterceptor接口
* registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
* registerAdvisorAdapter(new AfterReturningAdviceAdapter());
* registerAdvisorAdapter(new ThrowsAdviceAdapter());
*/
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
invocation.proceed()执行责任链,interceptorsAndDynamicMethodMatchers即为传入的chain
public Object proceed() throws Throwable {
//从-1开始,结束条件执行被代理对象的下标=拦截器的长度-1(也就是执行到了最后一个拦截器时)
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
/**
* 获取第一个方法拦截器使用的是++index
*/
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//如果interceptorOrInterceptionAdvice为InterceptorAndDynamicMethodMatcher实例
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
//再次匹配MethodMatcher三个参数的matches方法
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
//匹配成功才继续调用invoke方法
//这里的invoke会调用advice包装类的invoke方法,例如MethodBeforeAdviceInterceptor AfterReturningAdviceInterceptor ThrowsAdviceInterceptor
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
//在这个地方需要注意,抵用第一个拦截器的invoke方法,传入的是this 当前的方法拦截器对象
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
总结
- Advisor增强器包含PointCut切点和Advice通知组成,PointCut可以获取ClassFilter和MethodMatcher对象,在判断一个类是否需要创建动态代理时,会先找到所有候选的Advisor,然后调用Advisor中PointCut的ClassFilter的Mather方法进行匹配,匹配成功的即为合格。
- 找到所有合格的Advisor后,就可以通过ProxyFactory创建动态代理对象
- 代理对象执行被代理对象的方法时,执行代理逻辑,会先找到所有匹配的Advice,此时利用的是PointCut中的MethodMatcher去进行匹配,之后去调用Advice责任链