Spring源码-AOP部分-Spring是如何对bean实现AOP代理的
实验环境:spring-framework-5.0.2、jdk8、gradle4.3.1
历史文章
AOP代理对象也是在bean的实例化过程中创建的,如果不明白可以看一下bean实例化过程。如果类配置了@EnableAspectJAutoProxy注解 ,Spring则会在BeanPostProcessor.after这一步通过AnnotationAwareAspectJAutoProxyCreator这个BeanPostProcessor创建一个代理对象,替换掉了原有的bean对象返回了出去。
我们再来看一下bean创建流程
创建bean方法如下
doCreateBean方法
/**
* 真正创建bean的方法
*/
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 封装被创建的bean对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// TODO【重要】 这一步创建了bean实例,只是一个早期的对象,还没有填充属性值
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
// 获取实例化对象的类型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 调用post-processors
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 向容器中缓存单例模式的bean,防止循环引用
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// TODO【重要】 向三级缓存添加bean实例 匿名内部类,防止循环引用,尽早持有对象的引用
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 初始化bean实例,exposedObject在初始化完成之后返回依赖注入完成之后的bean
Object exposedObject = bean;
try {
// TODO 【重要】 bean属性依赖注入,并且将bean定义中配置的属性值赋值给实例对象
populateBean(beanName, mbd, instanceWrapper);
// TODO 【重要】开始初始化bean对象(含AOP)
// 调用Aware接口方法 -> 调用BeanPostProcessor.before方法 -> 调用init-method方法 -> 调用BeanPostProcessor.after方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
// 获取指定名称的已注册的单例bean
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
// 根据名称获取已注册的bean和正在实例化的bean是同一个
if (exposedObject == bean) {
// 当前实例化的bean初始完成
exposedObject = earlySingletonReference;
}
// 当前bean依赖其他bean,且当发送循环引用时,不允许创建新的实例对象
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 获取当前bean所依赖的其他bean
String[] dependentBeans = getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 对依赖bean进行类型检查
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// 注册完成依赖注入的bean
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
/**
* 初始化容器创建的bean实例对象,为其添加BeanPostProcessor后置处理器
* 调用Aware接口方法 -> 调用BeanPostProcessor.before方法 -> 调用init-method方法 -> 调用BeanPostProcessor.after方法
*/
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 通过JDK的安全机制验证权限
if (System.getSecurityManager() != null) {
// 实现PrivilegedAction接口的匿名内部类
AccessController.doPrivileged((PrivilegedAction