闽公网安备 35020302035485号
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
//堆代码 duidaima.com
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
//省略。。。
}
小伙伴们看,这里的 resolveBeforeInstantiation 方法就是给 BeanPostProcessor 一个返回代理对象的机会,在这个方法中,最终就会触发到 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法,而在 postProcessBeforeInstantiation 方法中,会先判断当前 bean 是否是 AOP 相关类等:@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
前面 if 分支中的内容,我在前面的文章中已经和大家分析过了,这里就不再赘述。@Nullable
protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
// We can't create fancy target sources for directly registered singletons.
if (this.customTargetSourceCreators != null &&
this.beanFactory != null && this.beanFactory.containsBean(beanName)) {
for (TargetSourceCreator tsc : this.customTargetSourceCreators) {
TargetSource ts = tsc.getTargetSource(beanClass, beanName);
if (ts != null) {
return ts;
}
}
}
// No custom TargetSource found.
return null;
}
可以看到,这里就是当前类 AbstractAutoProxyCreator 中有一个 customTargetSourceCreators 变量,现在就是遍历该变量,通过这个集合中保存的 TargetSourceCreator 来创建 TargetSource 对象。@Override
@Nullable
public final TargetSource getTargetSource(Class<?> beanClass, String beanName) {
AbstractBeanFactoryBasedTargetSource targetSource =
createBeanFactoryBasedTargetSource(beanClass, beanName);
if (targetSource == null) {
return null;
}
DefaultListableBeanFactory internalBeanFactory = getInternalBeanFactoryForBean(beanName);
// We need to override just this bean definition, as it may reference other beans
// and we're happy to take the parent's definition for those.
// Always use prototype scope if demanded.
BeanDefinition bd = getConfigurableBeanFactory().getMergedBeanDefinition(beanName);
GenericBeanDefinition bdCopy = new GenericBeanDefinition(bd);
if (isPrototypeBased()) {
bdCopy.setScope(BeanDefinition.SCOPE_PROTOTYPE);
}
internalBeanFactory.registerBeanDefinition(beanName, bdCopy);
// Complete configuring the PrototypeTargetSource.
targetSource.setTargetBeanName(beanName);
targetSource.setBeanFactory(internalBeanFactory);
return targetSource;
}
首先,TargetSource 对象是通过 createBeanFactoryBasedTargetSource 方法来创建的,这个方法是一个抽象方法,将来在子类中被实现。接下来会调用 getInternalBeanFactoryForBean 方法创建一个新的内部容器 internalBeanFactory,本质上这个 internalBeanFactory 其实是一个子容器,现有的容器将作为这个子容器的父容器。protected DefaultListableBeanFactory getInternalBeanFactoryForBean(String beanName) {
synchronized (this.internalBeanFactories) {
return this.internalBeanFactories.computeIfAbsent(beanName,
name -> buildInternalBeanFactory(getConfigurableBeanFactory()));
}
}
protected DefaultListableBeanFactory buildInternalBeanFactory(ConfigurableBeanFactory containingFactory) {
// Set parent so that references (up container hierarchies) are correctly resolved.
DefaultListableBeanFactory internalBeanFactory = new DefaultListableBeanFactory(containingFactory);
// Required so that all BeanPostProcessors, Scopes, etc become available.
internalBeanFactory.copyConfigurationFrom(containingFactory);
// Filter out BeanPostProcessors that are part of the AOP infrastructure,
// since those are only meant to apply to beans defined in the original factory.
internalBeanFactory.getBeanPostProcessors().removeIf(beanPostProcessor ->
beanPostProcessor instanceof AopInfrastructureBean);
return internalBeanFactory;
}
这个其实就是正常的容器创建,倒也没啥好说的,但是有几个需要注意的点:在调用 buildInternalBeanFactory 方法构建容器的时候,会先调用 getConfigurableBeanFactory 方法获取到当前容器作为父容器,如果当前容器不存在,那么就会抛出异常。这就意味着,当我们自己提供 TargetSourceCreator 实例的时候,一定要指定一个容器。
在创建了内部容器之后,会从内部容器中移除所有 AopInfrastructureBean 类型的 BeanPostProcessor,也就是内部容器将来创建出来的 bean,不再走 AopInfrastructureBean 类型后置处理器,因为这种类型的后置处理器主要是用来处理 AOP 的,现在,AOP 代理当场就生成了,就不再需要这些后置处理器了。
public class UserServiceTargetSource extends AbstractBeanFactoryBasedTargetSource {
@Override
public Object getTarget() throws Exception {
return getBeanFactory().getBean(getTargetBeanName());
}
@Override
public boolean isStatic() {
return true;
}
}
关于 TargetSource 本身,我在之前的 Spring 源码视频中已经和大家介绍过很多了,这里我就不再啰嗦了。public class CustomTargetSourceCreator extends AbstractBeanFactoryBasedTargetSourceCreator {
@Override
protected AbstractBeanFactoryBasedTargetSource createBeanFactoryBasedTargetSource(Class<?> beanClass, String beanName) {
if (getBeanFactory() instanceof ConfigurableListableBeanFactory) {
if (beanClass.isAssignableFrom(UserService.class)) {
return new UserServiceTargetSource();
}
}
return null;
}
}
如果要创建的 bean 是 UserService 的话,那么就给返回一个 UserServiceTargetSource 对象。@Component
public class SetCustomTargetSourceCreator implements BeanPostProcessor, PriorityOrdered, BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public int getOrder() {
return Integer.MIN_VALUE;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof AnnotationAwareAspectJAutoProxyCreator) {
AnnotationAwareAspectJAutoProxyCreator annotationAwareAspectJAutoProxyCreator = (AnnotationAwareAspectJAutoProxyCreator)bean;
CustomTargetSourceCreator customTargetSourceCreator = new CustomTargetSourceCreator();
customTargetSourceCreator.setBeanFactory(beanFactory);
annotationAwareAspectJAutoProxyCreator.setCustomTargetSourceCreators(customTargetSourceCreator);
}
return bean;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}
AnnotationAwareAspectJAutoProxyCreator 本身就是一个 BeanPostProcessor,我们现在要做的就是修改这个 BeanPostProcessor,BeanPostProcessor 是在 Spring 容器启动时候的 refresh 方法中去初始化的,整个的初始化过程我在之前的BeanPostProcessor 是在何时介入 Bean 创建的?一文中已经详细介绍过了。@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class JavaConfig {
}
大功告成。