Spring AOP源码剖析
Posted 怀瑾Hello World
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring AOP源码剖析相关的知识,希望对你有一定的参考价值。
Spring AOP源码剖析
1.代理对象创建
1.1.AOP基础⽤例准备
- Bean定义
package aop;
import org.springframework.stereotype.Component;
@Component
public class LagouBeanAop
public void tech()
System.out.println("java learning......");
- Aspect定义
package aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class LagouAspect
@Pointcut("execution(* aop.LagouBeanAop.tech())")
public void pointcut()
@Before("pointcut()")
public void before()
System.out.println("before method ......");
@After("pointcut()")
public void after()
System.out.println("after method ......");
@AfterReturning("pointcut()")
public void afterReturn()
System.out.println("after return method ......");
@AfterThrowing("pointcut()")
public void afterThrow()
System.out.println("after throw method ......");
@Around("pointcut()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable
System.out.println("around method before tagert method......");
joinPoint.proceed(joinPoint.getArgs());
System.out.println("around method after tagert method......");
- SpringConfiguration
package aop;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan("aop")
@EnableAspectJAutoProxy //开启spring对注解AOP的⽀持
public class SpringConfiguration
- 测试用例
/**
* 测试⽤例:Aop 代理对象创建
*/
@Test
public void testAopProxyBuild()
ApplicationContext applicationContext = new
AnnotationConfigApplicationContext(SpringConfiguration.class);
LagouBeanAop lagouBeanAop = applicationContext.getBean(LagouBeanAop.class);
lagouBeanAop.tech();
1.2.时机点分析
- 我们发现在 getBean 之前,LagouBean对象已经产⽣(即在第⼀⾏初始化代码中完成),⽽且该对象是⼀个代理对象(Cglib代理对象),我们断定,容器初始化过程中⽬标Ban已经完成了代理,返回了代理对象。
1.3.代理对象创建流程
- AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String,java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
/**
* Initialize the given bean instance, applying factory callbacks
* as well as init methods and bean post processors.
* <p>Called from @link #createBean for traditionally defined beans,
* and from @link #initializeBean for existing bean instances.
* @param beanName the bean name in the factory (for debugging purposes)
* @param bean the new bean instance we may need to initialize
* @param mbd the bean definition that the bean was created with
* (can also be @code null, if given an existing bean instance)
* @return the initialized bean instance (potentially wrapped)
* @see BeanNameAware
* @see BeanClassLoaderAware
* @see BeanFactoryAware
* @see #applyBeanPostProcessorsBeforeInitialization
* @see #invokeInitMethods
* @see #applyBeanPostProcessorsAfterInitialization
*/
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
if (System.getSecurityManager() != null)
AccessController.doPrivileged((PrivilegedAction<Object>) () ->
invokeAwareMethods(beanName, bean);
return null;
, getAccessControlContext());
else
invokeAwareMethods(beanName, bean);
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic())
// 执⾏所有的BeanPostProcessor#postProcessBeforeInitialization 初始化之前的处理器⽅法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
try
// 这⾥就开始执⾏afterPropertiesSet(实现了InitializingBean接⼝)⽅法和initMethod
invokeInitMethods(beanName, wrappedBean, mbd);
catch (Throwable ex)
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
if (mbd == null || !mbd.isSynthetic())
// 整个Bean初始化完成,执⾏后置处理器⽅法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
- AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException
Object result = existingBean;
// 循环后置处理器
for (BeanPostProcessor processor : getBeanPostProcessors())
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null)
return result;
result = current;
return result;
- 创建代理对象的后置处理AbstractAutoProxyCreator#postProcessAfterInitialization
/**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
* @see #getAdvicesAndAdvisorsForBean
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName)
if (bean != null)
// 检查下该类是否已经暴露过了(可能已经创建了,⽐如A依赖B时,创建A时候,就先去创建B。
// 当真正需要创建B时,就没必要再代理⼀次已经代理过的对象),避免重复创建
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean)
return wrapIfNecessary(bean, beanName, cacheKey);
return bean;
- AbstractAutoProxyCreator#wrapIfNecessary
/**
* Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
* @param bean the raw bean instance
* @param beanName the name of the bean
* @param cacheKey the cache key for metadata access
* @return a proxy wrapping the bean, or the raw bean instance as-is
*/
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;
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName))
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
// Create proxy if we have advice.
// 得到所有候选Advisor,对Advisors和bean的⽅法双层遍历匹配,最终得到⼀个List<Advisor>,即specificInterceptors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
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;
- specificInterceptors :得到所有候选Advisor,对Advisors和bean的⽅法双层遍历匹配,最终得到⼀个
List<Advisor>
- AbstractAutoProxyCreator#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 proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 根据⼀些情况判断是否要设置proxyTargetClass=true
if (!proxyFactory.isProxyTargetClass())
if (shouldProxyTargetClass(beanClass, beanName))
proxyFactory.setProxyTargetClass(true);
else
evaluateProxyInterfaces(beanClass, proxyFactory);
// 把指定和通⽤拦截对象合并, 并都适配成Advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 设置参数
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered())
proxyFactory.setPreFiltered(true);
// 上⾯准备做完就开始创建代理
return proxyFactory.getProxy(getProxyClassLoader());
- 接着跟进到ProxyFactory中
/**
* Create a new proxy according to the settings in this factory.
* <p>Can be called repeatedly. Effect will vary if we've added
* or removed interfaces. Can add and remove interceptors.
* <p>Uses the given class loader (if necessary for proxy creation).
* @param classLoader the class loader to create the proxy with
* (or @code null for the low-level proxy facility's default)
* @return the proxy object
*/
public Object getProxy(@Nullable ClassLoader classLoader)
// ⽤ProxyFactory创建AopProxy, 然后⽤AopProxy创建Proxy, 所以这⾥重要的是看获取的AopProxy对象是什么,
// 然后进去看怎么创建动态代理, 提供了两种:jdk proxy, cglib
return createAopProxy().getProxy(classLoader);
public class ProxyCreatorSupport extends AdvisedSupport
private AopProxyFactory aopProxyFactory;
public ProxyCreatorSupport()
this.aopProxyFactory = new DefaultAopProxyFactory();
protected final synchronized AopProxy createAopProxy()
if (!this.active)
activate();
//先获取创建AopProxy的⼯⼚, 再由此创建AopProxy
return getAopProxyFactory().createAopProxy(this);
public AopProxyFactory getAopProxyFactory()
return this.aopProxyFactory;
- 流程就是⽤AopProxyFactory创建AopProxy, 再⽤AopProxy创建代理对象,这⾥的AopProxyFactory默认是DefaultAopProxyFactory,看他的createAopProxy⽅法
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))
Class<?> targetClass = config.getTargetClass();
if (targetClass == null)
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass))
return new JdkDynamicAopProxy(config);
return new ObjenesisCglibAopProxy(config);
else
return new JdkDynamicAopProxy(config);
/**
* Determine whether the supplied @link AdvisedSupport has only the
* @link org.springframework.aop.SpringProxy interface specified
* (or no proxy interfaces specified at all).
*/
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config)
Class<?>[] ifcs = config.getProxiedInterfaces();
return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
- 这⾥决定创建代理对象是⽤JDK Proxy,还是⽤ Cglib 了,最简单的从使⽤⽅⾯使⽤来说:设置proxyTargetClass=true强制使⽤Cglib 代理,什么参数都不设并且对象类实现了接⼝则默认⽤JDK 代理,如果没有实现接⼝则也必须⽤CglibProxyFactory#getProxy(java.lang.ClassLoader)
------ CglibAopProxy#getProxy(java.lang.ClassLoader)
@Override
public Object getProxy(@Nullable ClassLoader classLoader)
if (logger.isTraceEnabled())
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
try
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass))
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces)
this.advised.addInterface(additionalInterface);
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// 配置 Cglib 增强
Enhancer enhancer = createEnhancer();
if (classLoader != null)
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass))
enhancer.setUseCache(false);
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++)
types[x] = callbacks[x].getClass();
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// ⽣成代理类,并且创建⼀个代理类的实例
return createProxyClassAndInstance(enhancer, callbacks);
catch (CodeGenerationException | IllegalArgumentException ex)
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
catch (Throwable ex)
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
2.Spring声明式事务控制
声明式事务很⽅便,尤其纯注解模式,仅仅⼏个注解就能
以上是关于Spring AOP源码剖析的主要内容,如果未能解决你的问题,请参考以下文章