当前位置: 首页 > wzjs >正文

南宁网站建设活动网站建设公司包括哪些方面

南宁网站建设活动,网站建设公司包括哪些方面,wordpress暴力,网站开发名片我们通常聊到spring bean的生命周期,大多是从网上找帖子背些基本概念,这样我们学到的东西是不够直观清晰的,这篇文章我就试着从源码级别来讲清楚bean的创建过程。 一、准备demo代码 我们既然要深入源码来看bean的创建过程,那么就…

      我们通常聊到spring bean的生命周期,大多是从网上找帖子背些基本概念,这样我们学到的东西是不够直观清晰的,这篇文章我就试着从源码级别来讲清楚bean的创建过程。

一、准备demo代码

        我们既然要深入源码来看bean的创建过程,那么就要写一个简单的demo,用于我们debug跟踪代码的执行过程,从而可以非常直观的看到核心源码发挥的作用。

package com.example.bean;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Test1 {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);Student student1 = (Student)context.getBean("student");Student student2 = (Student)context.getBean("student");System.out.println(student1 == student2);}
}

         可以看到里面涉及到了Student类,Student类代码如下:

package com.example.bean;import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class Student implements InitializingBean {@Autowiredprivate Cource cource;private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic void afterPropertiesSet() throws Exception {this.name = "zhangsan";this.age = 10;}
}

       在学生类中还注入了课程类Cource,这个类代码如下:

package com.example.bean;import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;@Component
public class Cource implements InitializingBean {private String courceName;public String getCourceName() {return courceName;}public void setCourceName(String courceName) {this.courceName = courceName;}@Overridepublic void afterPropertiesSet() throws Exception {this.courceName = "语文";}
}

        除了这两个我们要重点关注的类之外,我们还要关注AppConfig类,这个类用于指定我们扫描包的范围,是非常重要的。

package com.example.bean;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration
@ComponentScan("com.example.bean")
public class AppConfig {
}

         我们整体代码的结构如下图所示。

      上面在Test1这个类中我们使用的AnnotationConfigApplicationContext 是 Spring 框架中用于基于注解配置的应用程序上下文实现类。如果你程序还是用xml来定义bean的话,就得用ClassPathXmlApplicationContext这个上下文实现类了。

二、准备注解解析器和组件扫描器

        我们看代码new AnnotationConfigApplicationContext(AppConfig.class);点击进去看里面的源码,如下所示。

       可以看到入参是不固定数量的,不过从形参名称componentClasses就可以看出来入参跟Component相关,而我们的入参类AppConfig类上就有@ComponentScan注解,这个注解用于扫描指定包下的类。

	/*** Create a new AnnotationConfigApplicationContext, deriving bean definitions* from the given component classes and automatically refreshing the context.* @param componentClasses one or more component classes &mdash; for example,* {@link Configuration @Configuration} classes*/public AnnotationConfigApplicationContext(Class <? > ...componentClasses) {this();register(componentClasses);refresh();}

       接下来我们看构造方法的第一行代码this();显然这是调用了内部的无参构造器,我们看看这个无参构造器中都有哪些代码,如下所示。

   其中StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");这行代码只是启动一个性能监控步骤,用于记录创建AnnotatedBeanDefinitionReader的耗时,它不是重点,这个我们直接忽略它。

2.1 注解解析器       

接下来就是this.reader = new AnnotatedBeanDefinitionReader(this);这是准备注解解析器的代码,我们点进去看看里面的逻辑。

/*** Create a new AnnotationConfigApplicationContext that needs to be populated* through {@link #register} calls and then manually {@linkplain #refresh refreshed}.*/
public AnnotationConfigApplicationContext() {StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");this.reader = new AnnotatedBeanDefinitionReader(this);createAnnotatedBeanDefReader.end();this.scanner = new ClassPathBeanDefinitionScanner(this);
}

        可以看到如下图所示内容,可以看到我们把AnnotationConfigApplicationContext作为BeanDefinitionRegistry类型的入参传进来了,然后内部调用到registerAnnotationConfigProcessors(BeanDefinitionRegistry registry)方法的调用链如下图所示,这些代码不是重点,我们知道是这么个调用流程即可。

       之所以把AnnotationConfigApplicationContext作为参数可以直接作为AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry)的参数传过来是因为AnnotationConfigApplicationContext是BeanDefinitionRegistry的实现类,如下图所示。

        我们接着回到上面提到的registerAnnotationConfigProcessors(BeanDefinitionRegistry registry)方法,如下所示,我们关注里面的registerAnnotationConfigProcessors(registry, null);方法。

public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {registerAnnotationConfigProcessors(registry, null);
}

         方法源码如下,这里面上来就看到一个非常核心的组件DefaultListableBeanFactory,这个组件有多核心,我们总结一下这个组件的功能就知道了。

public static Set < BeanDefinitionHolder > registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);if (beanFactory != null) {if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);}if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());}}//......这里暂时省略一部分代码
}

         DefaultListableBeanFactory说明如下:

DefaultListableBeanFactory是spring框架中最核心的BeanFactory实现类,负责管理bean的定义、实例化、依赖注入以及生命周期,它是Spring IoC容器的基础设施,同时也是高级容器(如ApplicationContext)的底层实现。好家伙,这一个组件就包括了这么多功能,下面具体说下每个功能。

1)Bean定义管理

       实现了BeanDefinitionRegistry接口,支持动态注册和存储Bean定义(BeanDefinition)。

       另一个就是维护了一个Map<String, BeanDefinition>结构的beanDefinitionMap,这个map用来存储所有bean的基础信息(BeanDefinition在创建bean时使用)。

2)Bean实例化与依赖注入

       继承AbstractAutowireCapableBeanFactory,提供bean的实例化、属性填充(populateBean)和初始化(initializeBean)逻辑。

       支持构造器注入和Setter注入。

3)单例与作用域管理

       维护单例bean缓存(singletonObjects),支持singleton和prototype作用域。

       通过三级缓存(第三级singletonFactories、第二级earlySingletonObjects、第一级singletonObjects)解决循环依赖问题。

4)类型转换与自动装配

       实现AutowireCapableBeanFactory,支持按类型(byType)或名称(byName)自动装配。

       处理@Autowired、@Value、@Resource等注解的依赖注入。

5)生命周期回调

        处理InitializingBean、DisposableBean 等接口的回调。

        支持@PostConstruct 和@PreDestroy 注解。

6)Bean后置处理

        通过BeanPostProcessor和BeanFactoryPostProcessor扩展bean的创建和初始化逻辑。

        说完DefaultListableBeanFactory,我们再回到刚才registerAnnotationConfigProcessors方法的源码,如下所示。我们第一步获取到DefaultListableBeanFactory之后,便接着给这个beanFactory设置dependencyComparator和autowireCandidateResolver这两个组件。

public static Set < BeanDefinitionHolder > registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);if (beanFactory != null) {if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);}if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());}}//......这里暂时省略一部分代码
}

        其中beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);这句代码是要配置依赖比较器,确保BeanFactory使用AnnotationAwareOrderComparator作为依赖比较器,它的作用是在自动装配时,spring需要确定多个候选bean的注入顺序,这时AnnotationAwareOrderComparator可以解析@Order或者@Priority注解以及Ordered接口按优先级排序bean。

       其次就是beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());这句代码是配置自动装配候选解析器。它的作用是在自动装配过程中决定哪些bean符合条件作为候选依赖。注解支持@Qualifier(按名称精确匹配 Bean)、@Value(解析 SpEL 表达式或占位符)、@Lazy(延迟初始化代理)。

       接下来我们继续分析registerAnnotationConfigProcessors方法的源码如下所示,可以看到是要组装beanDefs,这是个由BeanDefinitionHolder组成的Set集合。然后看到下面很多if判断并且往这个beanDefs里面添加元素,我们就拿第一个if判断来举例。

public static Set < BeanDefinitionHolder > registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {//......这里暂时省略一部分代码Set < BeanDefinitionHolder > beanDefs = new LinkedHashSet < > (8);if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));}// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition();try {def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,AnnotationConfigUtils.class.getClassLoader()));} catch (ClassNotFoundException ex) {throw new IllegalStateException("Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);}def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));}if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));}if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));}return beanDefs;
}

           第一个If判断如下,上来先判断在注册器registry中是否有常量CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME,这个常量我们在当前AnnotationConfigUtils这个类中可以看到如下图所示,是一个挺长名字的字符串。

if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}

        我们看registry.containsBeanDefinition方法内部逻辑,可以看到有三个实现类,我们刚从上面知道我们使用工厂是DefaultListableBeanFactory,因此我们进入到DefaultListableBeanFactory这个内部看看

        方法registry.containsBeanDefinition具体代码如下,可以看到就是判断beanDefinitionMap中是否存在当前key。由于我们目前还处于最开始阶段,因此这里beanDefinitionMap是空,也就是key在map中不存在。

@Override
public boolean containsBeanDefinition(String beanName) {Assert.notNull(beanName, "Bean name must not be null");return this.beanDefinitionMap.containsKey(beanName);
}

        beanDefinitionMap的定义如下。

/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

        因此就进入到if内部,如下所示,可以看到定义了一个根beanDefinition,也就是RootBeanDefinition,它是由ConfigurationClassPostProcessor真正来实现具体功能的。ConfigurationClassPostProcessor是spring实现注解驱动编程(如@Configuration、@Bean、@ComponentScan等)的关键组件。负责解析和处理基于注解的配置元数据。

if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}

        然后我们进入到beanDefs.add()方法中调用的方法registerPostProcessor,看看里面做了什么操作。这里面我们重点关注registry.registerBeanDefinition(beanName, definition);这行代码

private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);registry.registerBeanDefinition(beanName, definition);return new BeanDefinitionHolder(definition, beanName);
}

         DefaultListableBeanFactory工厂类中registerBeanDefinition方法源码如下所示,我们目前beanDefinitionMap中还没有元素,因此existingDefinition是null,因此走else分支代码,else分支代码中上来是判断目前是不是正在创建bean,代码:if (hasBeanCreationStarted())

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {Assert.hasText(beanName, "Bean name must not be empty");Assert.notNull(beanDefinition, "BeanDefinition must not be null");if (beanDefinition instanceof AbstractBeanDefinition) {try {((AbstractBeanDefinition) beanDefinition).validate();} catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,"Validation of bean definition failed", ex);}}BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);if (existingDefinition != null) {if (!isAllowBeanDefinitionOverriding()) {throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);} else if (existingDefinition.getRole() < beanDefinition.getRole()) {// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTUREif (logger.isInfoEnabled()) {logger.info("Overriding user-defined bean definition for bean '" + beanName +"' with a framework-generated bean definition: replacing [" +existingDefinition + "] with [" + beanDefinition + "]");}} else if (!beanDefinition.equals(existingDefinition)) {if (logger.isDebugEnabled()) {logger.debug("Overriding bean definition for bean '" + beanName +"' with a different definition: replacing [" + existingDefinition +"] with [" + beanDefinition + "]");}} else {if (logger.isTraceEnabled()) {logger.trace("Overriding bean definition for bean '" + beanName +"' with an equivalent definition: replacing [" + existingDefinition +"] with [" + beanDefinition + "]");}}this.beanDefinitionMap.put(beanName, beanDefinition);} else {if (hasBeanCreationStarted()) {// Cannot modify startup-time collection elements anymore (for stable iteration)synchronized(this.beanDefinitionMap) {this.beanDefinitionMap.put(beanName, beanDefinition);List < String > updatedDefinitions = new ArrayList < > (this.beanDefinitionNames.size() + 1);updatedDefinitions.addAll(this.beanDefinitionNames);updatedDefinitions.add(beanName);this.beanDefinitionNames = updatedDefinitions;removeManualSingletonName(beanName);}} else {// Still in startup registration phasethis.beanDefinitionMap.put(beanName, beanDefinition);this.beanDefinitionNames.add(beanName);removeManualSingletonName(beanName);}this.frozenBeanDefinitionNames = null;}if (existingDefinition != null || containsSingleton(beanName)) {resetBeanDefinition(beanName);} else if (isConfigurationFrozen()) {clearByTypeCache();}
}

        hasBeanCreationStarted方法内部代码如下,其实就是判断了一个名叫alreadyCreated的集合是否有元素,在这个阶段这个集合还没有开始创建bean,这里集合是空的,因此返回的是false。

/*** Check whether this factory's bean creation phase already started,* i.e. whether any bean has been marked as created in the meantime.* @since 4.2.2* @see #markBeanAsCreated*/
protected boolean hasBeanCreationStarted() {return !this.alreadyCreated.isEmpty();
}

        回过来上面的registerBeanDefinition方法代码就会走到如下图所示位置,这里就是将beanName作为key,将beanDefinition作为value保存到了beanDefinitionMap当中,并且把beanName也专门保存到beanDefinitionNames集合当中。

        我们再回到上面提到的registerAnnotationConfigProcessors方法,我们刚才只是举例说明了第一个if条件判断中的逻辑。另外还要简单提一下的是beanName为下面二个

	/*** The bean name of the internally managed Autowired annotation processor.*/public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalAutowiredAnnotationProcessor";/*** The bean name of the internally managed JSR-250 annotation processor.*/public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalCommonAnnotationProcessor";

         其中org.springframework.context.annotation.internalAutowiredAnnotationProcessor这个beanName对应的根beanDefinition是AutowiredAnnotationBeanPostProcessor,它是spring依赖注入机制的关键组件,负责处理@Autowired、@Value、@Inject等注解,完成bean的自动装配逻辑。

       另外org.springframework.context.annotation.internalCommonAnnotationProcessor这个beanName对应的根beanDefinition是CommonAnnotationBeanPostProcessor,它是BeanPostProcessor的实现类,主要功能包括:

1)处理生命周期注解

       @PostConstruct:在bean初始化阶段,(afterPropertiesSet 之后、init-method 之前)调用标记的方法。

       @PreDestroy:在bean销毁阶段调用标记的方法。

2)处理依赖注入注解

       @Resource:按名称或类型注入依赖,支持JNDI查找(需配置)。

2.2 组件扫描器

       我们再回到AnnotationConfigApplicationContext无参构造器源码这块,我们下面接着分析this.scanner = new ClassPathBeanDefinitionScanner(this);这行代码

public AnnotationConfigApplicationContext() {StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");this.reader = new AnnotatedBeanDefinitionReader(this);createAnnotatedBeanDefReader.end();this.scanner = new ClassPathBeanDefinitionScanner(this);
}

        嵌套比较深,调用链如下,我们重点关注下面setResourceLoader(resourceLoader);方法。

         方法setResourceLoader内容源码如下,该方法用于配置与资源加载相关的核心组件,支持类路径扫描和组件索引加载,常用于spring的组件扫描器(如ClassPathBeanDefinitionScanner)或元数据处理类中。

public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);this.componentsIndex = CandidateComponentsIndexLoader.loadIndex(this.resourcePatternResolver.getClassLoader());
}

1) 初始化资源模式解析器

this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);是将ResourceLoader转换为ResourcePatternResolver,目的是支持从类路径中按模式(如classpath*:com/example/**/*.class)批量加载资源。

2)初始化元数据读取工厂

this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);

CachingMetadataReaderFactory基于ResourceLoader创建可缓存的MetadataReaderFactory,它的功能是读取.class文件的元数据(如类名、注解、接口等),避免重复解析开销。并且默认使用ConcurrentHashMap缓存MetadataReader,value为资源描述符。

3. 加载组件索引

this.componentsIndex = CandidateComponentsIndexLoader.loadIndex(this.resourcePatternResolver.getClassLoader());从类路径的 META-INF/spring.components 文件中加载组件索引,避免全路径扫描,显著提升大型应用的启动速度。不过这个需要依赖maven

<dependency><groupId>org.springframework</groupId><artifactId>spring-context-indexer</artifactId><optional>true</optional>
</dependency>

三、将指定配置类存放到注解解析器

        我们回到AnnotationConfigApplicationContext的构造方法这里,看第二行register(commponentClasses)代码。

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {this();register(componentClasses);refresh();
}

         register内部源码如下,可以看到我们又看到了熟悉的reader变量,这个我们在上面讲到的注解解析器的时候讲到了,里面存放的是beanName和对应的根beanDefinition,现在这里我们要把我们制定的AppConfig这个配置类也存放到reader当中。

@Override
public void register(Class <? > ...componentClasses) {Assert.notEmpty(componentClasses, "At least one component class must be specified");StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register").tag("classes", () - > Arrays.toString(componentClasses));this.reader.register(componentClasses);registerComponentClass.end();
}

        调用层级较深,调用链如下图所示

         doRegisterBean方法内部源码如下,可以看到生成了一个AnnotatedGenericBeanDefinition实例对象,它是Spring Framework 中用于封装基于注解的Bean定义的核心类。它继承自GenericBeanDefinition,并扩展了对注解元数据的支持,主要用于处理通过注解驱动配置(如@Configuration、@Component等)定义的bean。最典型的就是处理像我们AppConfig这样带有@Configuration注解的配置类,创建AnnotatedGenericBeanDefinition并存储该类的元数据。

private < T > void doRegisterBean(Class < T > beanClass, @Nullable String name, @Nullable Class <? extends Annotation > [] qualifiers, @Nullable Supplier < T > supplier, @Nullable BeanDefinitionCustomizer[] customizers) {AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}abd.setInstanceSupplier(supplier);ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);abd.setScope(scopeMetadata.getScopeName());String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);if (qualifiers != null) {for (Class <? extends Annotation > qualifier: qualifiers) {if (Primary.class == qualifier) {abd.setPrimary(true);} else if (Lazy.class == qualifier) {abd.setLazyInit(true);} else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));}}}if (customizers != null) {for (BeanDefinitionCustomizer customizer: customizers) {customizer.customize(abd);}}BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

 四、执行BeanFactoryPostProcessors

         我们接下来分析的就是spring中最核心的方法refresh方法中的内容了,我们跳过前面不重要的步骤,直接看执行BeanFactoryPostProcessors的内容,如下图所示。

        我们进入到invokeBeanFactoryPostProcessors方法内部,如下所示,我们重点关注第一行的代码PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}
}

        我们进入到我们方法内部,这个方法代码非常多,我们不用都关注,我们抽出重点需要关注的点关注即可。

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {// WARNING: Although it may appear that the body of this method can be easily// refactored to avoid the use of multiple loops and multiple lists, the use// of multiple lists and multiple passes over the names of processors is// intentional. We must ensure that we honor the contracts for PriorityOrdered// and Ordered processors. Specifically, we must NOT cause processors to be// instantiated (via getBean() invocations) or registered in the ApplicationContext// in the wrong order.//// Before submitting a pull request (PR) to change this method, please review the// list of all declined PRs involving changes to PostProcessorRegistrationDelegate// to ensure that your proposal does not result in a breaking change:// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22// Invoke BeanDefinitionRegistryPostProcessors first, if any.Set<String> processedBeans = new HashSet<>();if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;registryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);}else {regularPostProcessors.add(postProcessor);}}// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!// Separate between BeanDefinitionRegistryPostProcessors that implement// PriorityOrdered, Ordered, and the rest.List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.boolean reiterate = true;while (reiterate) {reiterate = false;postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);reiterate = true;}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();}// Now, invoke the postProcessBeanFactory callback of all processors handled so far.invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,// Ordered, and the rest.List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// Finally, invoke all other BeanFactoryPostProcessors.List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);// Clear cached merged bean definitions since the post-processors might have// modified the original metadata, e.g. replacing placeholders in values...beanFactory.clearMetadataCache();}

         下面我把重点需要关注的代码粘贴出来,其中下面第一行代码是通过BeanDefinitionRegistryPostProcessor这个类找到我们在上面2.1中注解解析器中提到的对应的beanName,这里对应的beanName是org.springframework.context.annotation.internalConfigurationAnnotationProcessor(我们在2.1中就截图说明了这个beanName对应了ConfigurationClassPostProcessor这个根beanDefinition,而ConfigurationClassPostProcessor又是BeanDefinitionRegistryPostProcessor的实现类)

String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());

        接下来for循环中就是判断org.springframework.context.annotation.internalConfigurationAnnotationProcessor是否匹配,我们通过2.1节可以知道DefaultListableBeanFactory这个组件是支持优先级的,因此走到if内部,currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));这行代码便是要通过ppName(也就是我们前面提到的beanName)获取对应的beandefinition,我们这里显然应该得到的就是ConfigurationClassPostProcessor

for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}
}

         然后我们就重点关注invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());这行代码了。这个方法内部代码如下,这里面重点关注的是for循环内部的postProcessor.postProcessBeanDefinitionRegistry(registry);这行代码。

private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process").tag("postProcessor", postProcessor::toString);postProcessor.postProcessBeanDefinitionRegistry(registry);postProcessBeanDefRegistry.end();}
}

        postProcessBeanDefinitionRegistry方法源码如下,在这个方法内部我们重点关注最后面那行processConfigBeanDefinitions(registry);

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {int registryId = System.identityHashCode(registry);if (this.registriesPostProcessed.contains(registryId)) {throw new IllegalStateException("postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);}if (this.factoriesPostProcessed.contains(registryId)) {throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);}this.registriesPostProcessed.add(registryId);processConfigBeanDefinitions(registry);
}

         processConfigBeanDefinitions方法源码如下,又是有很多代码,我们重点关注的是parser.parse(candidates)方法,如下图所示。

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {List<BeanDefinitionHolder> configCandidates = new ArrayList<>();String[] candidateNames = registry.getBeanDefinitionNames();for (String beanName : candidateNames) {BeanDefinition beanDef = registry.getBeanDefinition(beanName);if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {if (logger.isDebugEnabled()) {logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);}}else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));}}// Return immediately if no @Configuration classes were foundif (configCandidates.isEmpty()) {return;}// Sort by previously determined @Order value, if applicableconfigCandidates.sort((bd1, bd2) -> {int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());return Integer.compare(i1, i2);});// Detect any custom bean name generation strategy supplied through the enclosing application contextSingletonBeanRegistry sbr = null;if (registry instanceof SingletonBeanRegistry) {sbr = (SingletonBeanRegistry) registry;if (!this.localBeanNameGeneratorSet) {BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);if (generator != null) {this.componentScanBeanNameGenerator = generator;this.importBeanNameGenerator = generator;}}}if (this.environment == null) {this.environment = new StandardEnvironment();}// Parse each @Configuration classConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment,this.resourceLoader, this.componentScanBeanNameGenerator, registry);Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());do {StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");parser.parse(candidates);parser.validate();Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());configClasses.removeAll(alreadyParsed);// Read the model and create bean definitions based on its contentif (this.reader == null) {this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment,this.importBeanNameGenerator, parser.getImportRegistry());}this.reader.loadBeanDefinitions(configClasses);alreadyParsed.addAll(configClasses);processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();candidates.clear();if (registry.getBeanDefinitionCount() > candidateNames.length) {String[] newCandidateNames = registry.getBeanDefinitionNames();Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));Set<String> alreadyParsedClasses = new HashSet<>();for (ConfigurationClass configurationClass : alreadyParsed) {alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());}for (String candidateName : newCandidateNames) {if (!oldCandidateNames.contains(candidateName)) {BeanDefinition bd = registry.getBeanDefinition(candidateName);if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&!alreadyParsedClasses.contains(bd.getBeanClassName())) {candidates.add(new BeanDefinitionHolder(bd, candidateName));}}}candidateNames = newCandidateNames;}}while (!candidates.isEmpty());// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classesif (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());}if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {// Clear cache in externally provided MetadataReaderFactory; this is a no-op// for a shared cache since it'll be cleared by the ApplicationContext.((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();}}

        我们继续看parse方法内的源码,可以看到try中if、else if还有else都调用了本类中一个parse方法名一样,参数不一样的parse方法,这个是我们重点关注的。

public void parse(Set < BeanDefinitionHolder > configCandidates) {for (BeanDefinitionHolder holder: configCandidates) {BeanDefinition bd = holder.getBeanDefinition();try {if (bd instanceof AnnotatedBeanDefinition) {parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());} else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());} else {parse(bd.getBeanClassName(), holder.getBeanName());}} catch (BeanDefinitionStoreException ex) {throw ex;} catch (Throwable ex) {throw new BeanDefinitionStoreException("Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);}}this.deferredImportSelectorHandler.process();
}

        这个同名prase方法内部代码如下。

protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}

        我们继续到processConfigurationClass方法内部查看源码,如下所示,

protected void processConfigurationClass(ConfigurationClass configClass, Predicate < String > filter) throws IOException {if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {return;}ConfigurationClass existingClass = this.configurationClasses.get(configClass);if (existingClass != null) {if (configClass.isImported()) {if (existingClass.isImported()) {existingClass.mergeImportedBy(configClass);}// Otherwise ignore new imported config class; existing non-imported class overrides it.return;} else {// Explicit bean definition found, probably replacing an import.// Let's remove the old one and go with the new one.this.configurationClasses.remove(configClass);this.knownSuperclasses.values().removeIf(configClass::equals);}}// Recursively process the configuration class and its superclass hierarchy.SourceClass sourceClass = asSourceClass(configClass, filter);do {sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);}while (sourceClass != null);this.configurationClasses.put(configClass, configClass);
}

        我们需要重点关注的代码是如下图所示地方,

       其中componentScans运行得到的结果如下图所示,可以看到basePackages下面就是我们的AppConfig配置类中指定要扫描的包路径。

        接着看componentScanParser.parse方法的源码,又是一大坨代码,我们直接看最后一行代码return scanner.doScan(StringUtils.toStringArray(basePackages));

public Set < BeanDefinitionHolder > parse(AnnotationAttributes componentScan, String declaringClass) {ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);Class <? extends BeanNameGenerator > generatorClass = componentScan.getClass("nameGenerator");boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :BeanUtils.instantiateClass(generatorClass));ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");if (scopedProxyMode != ScopedProxyMode.DEFAULT) {scanner.setScopedProxyMode(scopedProxyMode);} else {Class <? extends ScopeMetadataResolver > resolverClass = componentScan.getClass("scopeResolver");scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));}scanner.setResourcePattern(componentScan.getString("resourcePattern"));for (AnnotationAttributes includeFilterAttributes: componentScan.getAnnotationArray("includeFilters")) {List < TypeFilter > typeFilters = TypeFilterUtils.createTypeFiltersFor(includeFilterAttributes, this.environment,this.resourceLoader, this.registry);for (TypeFilter typeFilter: typeFilters) {scanner.addIncludeFilter(typeFilter);}}for (AnnotationAttributes excludeFilterAttributes: componentScan.getAnnotationArray("excludeFilters")) {List < TypeFilter > typeFilters = TypeFilterUtils.createTypeFiltersFor(excludeFilterAttributes, this.environment,this.resourceLoader, this.registry);for (TypeFilter typeFilter: typeFilters) {scanner.addExcludeFilter(typeFilter);}}boolean lazyInit = componentScan.getBoolean("lazyInit");if (lazyInit) {scanner.getBeanDefinitionDefaults().setLazyInit(true);}Set < String > basePackages = new LinkedHashSet < > ();String[] basePackagesArray = componentScan.getStringArray("basePackages");for (String pkg: basePackagesArray) {String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);Collections.addAll(basePackages, tokenized);}for (Class <? > clazz: componentScan.getClassArray("basePackageClasses")) {basePackages.add(ClassUtils.getPackageName(clazz));}if (basePackages.isEmpty()) {basePackages.add(ClassUtils.getPackageName(declaringClass));}scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {@Overrideprotected boolean matchClassName(String className) {return declaringClass.equals(className);}});return scanner.doScan(StringUtils.toStringArray(basePackages));
}

       doScan内部源码如下,我们重点关注其中的外层for循环中的第一行代码Set<BeanDefinition> candidates = findCandidateComponents(basePackage);

protected Set < BeanDefinitionHolder > doScan(String...basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");Set < BeanDefinitionHolder > beanDefinitions = new LinkedHashSet < > ();for (String basePackage: basePackages) {Set < BeanDefinition > candidates = findCandidateComponents(basePackage);for (BeanDefinition candidate: candidates) {ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);candidate.setScope(scopeMetadata.getScopeName());String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);if (candidate instanceof AbstractBeanDefinition) {postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);}if (candidate instanceof AnnotatedBeanDefinition) {AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);}if (checkCandidate(beanName, candidate)) {BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);definitionHolder =AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);beanDefinitions.add(definitionHolder);registerBeanDefinition(definitionHolder, this.registry);}}}return beanDefinitions;
}

       findCandidateComponents方法源码如下:我们重点关注的是return scanCandidateComponents(basePackage);这行代码。

public Set < BeanDefinition > findCandidateComponents(String basePackage) {if (this.componentsIndex != null && indexSupportsIncludeFilters()) {return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);} else {return scanCandidateComponents(basePackage);}
}

        scanCandidateComponents方法源码如下所示,其中packageSearchPath获取到的值如下图,很明显就是要把com/example/bean包下的所有类都扫描出来

      下面resources这个变量的值刚好可以验证我们的猜想,如下图所示。从而到这里就可以知道我们是在这一步将AppConfig配置类中指定的com/example/bean包下的所有类扫描出来的,并且后面会组装成BeanDefinition存起来,从而给bean的实例化、初始化提供基础条件。

private Set < BeanDefinition > scanCandidateComponents(String basePackage) {Set < BeanDefinition > candidates = new LinkedHashSet < > ();try {String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +resolveBasePackage(basePackage) + '/' + this.resourcePattern;Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);boolean traceEnabled = logger.isTraceEnabled();boolean debugEnabled = logger.isDebugEnabled();for (Resource resource: resources) {if (traceEnabled) {logger.trace("Scanning " + resource);}try {MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);if (isCandidateComponent(metadataReader)) {ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);sbd.setSource(resource);if (isCandidateComponent(sbd)) {if (debugEnabled) {logger.debug("Identified candidate component class: " + resource);}candidates.add(sbd);} else {if (debugEnabled) {logger.debug("Ignored because not a concrete top-level class: " + resource);}}} else {if (traceEnabled) {logger.trace("Ignored because not matching any filter: " + resource);}}} catch (FileNotFoundException ex) {if (traceEnabled) {logger.trace("Ignored non-readable " + resource + ": " + ex.getMessage());}} catch (Throwable ex) {throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, ex);}}} catch (IOException ex) {throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);}return candidates;
}

五、实例化

         在上面invokeBeanFactoryPostProcessors方法执行完后,我们已经扫描出了com.example.bean目录下所有类并生成了对应的BeanDefinition,用于后面创建实例。下面通过源码来了解一下这块。我们要重点关注的是spring的refresh方法中的finishBeanFactoryInitialization(beanFactory);这行代码。

          我们进入finishBeanFactoryInitialization方法内部,代码挺多,我们跳过不重要的,直接看这个方法的最后一行beanFactory.preInstantiateSingletons();内的实现逻辑

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// Initialize conversion service for this context.if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}// Register a default embedded value resolver if no BeanFactoryPostProcessor// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:// at this point, primarily for resolution in annotation attribute values.if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal - > getEnvironment().resolvePlaceholders(strVal));}// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName: weaverAwareNames) {getBean(weaverAwareName);}// Stop using the temporary ClassLoader for type matching.beanFactory.setTempClassLoader(null);// Allow for caching all bean definition metadata, not expecting further changes.beanFactory.freezeConfiguration();// Instantiate all remaining (non-lazy-init) singletons.beanFactory.preInstantiateSingletons();
}

          preInstantiateSingletons方法内部代码如下,我们要关注的是for循环中的getBean(beanName)方法。

public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.List < String > beanNames = new ArrayList < > (this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...for (String beanName: beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof FactoryBean) {FactoryBean <? > factory = (FactoryBean <? > ) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction < Boolean > )((SmartFactoryBean <? > ) factory)::isEagerInit,getAccessControlContext());} else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean <? > ) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}} else {getBean(beanName);}}}// Trigger post-initialization callback for all applicable beans...for (String beanName: beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction < Object > )() - > {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());} else {smartSingleton.afterSingletonsInstantiated();}smartInitialize.end();}}
}

         getBean(beanName);方法源码如下

public Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);
}

         然后接着看doGetBean方法的源码,如下,我们重点关注的是if (mbd.isSingleton())这个if判断的内部的return createBean(beanName, mbd, args);这行代码。

protected < T > T doGetBean(String name, @Nullable Class < T > requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {String beanName = transformedBeanName(name);Object beanInstance;// Eagerly check singleton cache for manually registered singletons.Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isTraceEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");} else {logger.trace("Returning cached instance of singleton bean '" + beanName + "'");}}beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);} else {// Fail if we're already creating this bean instance:// We're assumably within a circular reference.if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// Check if bean definition exists in this factory.BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.String nameToLookup = originalBeanName(name);if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);} else if (args != null) {// Delegation to parent with explicit args.return (T) parentBeanFactory.getBean(nameToLookup, args);} else if (requiredType != null) {// No args -> delegate to standard getBean method.return parentBeanFactory.getBean(nameToLookup, requiredType);} else {return (T) parentBeanFactory.getBean(nameToLookup);}}if (!typeCheckOnly) {markBeanAsCreated(beanName);}StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);try {if (requiredType != null) {beanCreation.tag("beanType", requiredType::toString);}RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// Guarantee initialization of beans that the current bean depends on.String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep: dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}registerDependentBean(dep, beanName);try {getBean(dep);} catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}// Create bean instance.if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () - > {try {return createBean(beanName, mbd, args);} catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}});beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);} else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);} finally {afterPrototypeCreation(beanName);}beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);} else {String scopeName = mbd.getScope();if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");}Scope scope = this.scopes.get(scopeName);if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try {Object scopedInstance = scope.get(beanName, () - > {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);} finally {afterPrototypeCreation(beanName);}});beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);} catch (IllegalStateException ex) {throw new ScopeNotActiveException(beanName, scopeName, ex);}}} catch (BeansException ex) {beanCreation.tag("exception", ex.getClass().toString());beanCreation.tag("message", String.valueOf(ex.getMessage()));cleanupAfterBeanCreationFailure(beanName);throw ex;} finally {beanCreation.end();}}return adaptBeanInstance(name, beanInstance, requiredType);
}

         然后看createBean方法内部源码如下,这里我们重点关注的是最下面那个try中的Object beanInstance = doCreateBean(beanName, mbdToUse, args);这行代码。

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {if (logger.isTraceEnabled()) {logger.trace("Creating instance of bean '" + beanName + "'");}RootBeanDefinition mbdToUse = mbd;// Make sure bean class is actually resolved at this point, and// clone the bean definition in case of a dynamically resolved Class// which cannot be stored in the shared merged bean definition.Class <? > resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.try {mbdToUse.prepareMethodOverrides();} catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}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;} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {// A previously detected exception with proper bean creation context already,// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.throw ex;} catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}
}

         然后我们进入到doCreateBean内部,我们现在要关注实例化,因此很明显,我们应该重点关注的是if (instanceWrapper == null) 这个if条件内的instanceWrapper = createBeanInstance(beanName, mbd, args);这行代码。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class <? > beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// Allow post-processors to modify the merged bean definition.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;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}addSingletonFactory(beanName, () - > getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject = bean;try {populateBean(beanName, mbd, instanceWrapper);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) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set < String > actualDependentBeans = new LinkedHashSet < > (dependentBeans.length);for (String dependentBean: dependentBeans) {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 " +"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");}}}}// Register bean as disposable.try {registerDisposableBeanIfNecessary(beanName, bean, mbd);} catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;
}

          然后我们看createBeanInstance方法内部源码,如下,我们重点关注的是最后一行代码return instantiateBean(beanName, mbd);

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// Make sure bean class is actually resolved at this point.Class <? > beanClass = resolveBeanClass(mbd, beanName);if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());}Supplier <? > instanceSupplier = mbd.getInstanceSupplier();if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);}if (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}// Shortcut when re-creating the same bean...boolean resolved = false;boolean autowireNecessary = false;if (args == null) {synchronized(mbd.constructorArgumentLock) {if (mbd.resolvedConstructorOrFactoryMethod != null) {resolved = true;autowireNecessary = mbd.constructorArgumentsResolved;}}}if (resolved) {if (autowireNecessary) {return autowireConstructor(beanName, mbd, null, null);} else {return instantiateBean(beanName, mbd);}}// Candidate constructors for autowiring?Constructor <? > [] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {return autowireConstructor(beanName, mbd, ctors, args);}// Preferred constructors for default construction?ctors = mbd.getPreferredConstructors();if (ctors != null) {return autowireConstructor(beanName, mbd, ctors, null);}// No special handling: simply use no-arg constructor.return instantiateBean(beanName, mbd);
}

         instantiateBean源码如下所示,我们重点关注的是beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);这行代码。

protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {try {Object beanInstance;if (System.getSecurityManager() != null) {beanInstance = AccessController.doPrivileged((PrivilegedAction < Object > )() - > getInstantiationStrategy().instantiate(mbd, beanName, this),getAccessControlContext());} else {beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);}BeanWrapper bw = new BeanWrapperImpl(beanInstance);initBeanWrapper(bw);return bw;} catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);}
}

          instantiate方法源码如下图所示,我们debug代码可以看到代码走到了用红色方框圈住的那行代码constructorToUse = clazz.getDeclaredConstructor();这行代码显然是为了获取类的无参构造器,我们学习反射的时候就知道,要创建实例,主要就是通过先拿到构造器来创建实例的。

           上面拿到了构造器之后,紧接着就是走到return BeanUtils.instantiateClass(constructorToUse);这行代码,从调用的方法名就知道要通过构造器去创建实例对象,源码如下所示,ReflectionUtils.makeAccessible(ctor);这行代码相信大家也不陌生,如果反射要使用私有构造器去创建实例对象的话得先进行赋权,也就是setAccessible为true。这也就是为何反射不安全的原因。紧接着我们就重点看创建实例的代码,也就是return ctor.newInstance(argsWithDefaultValues);这行代码。

public static < T > T instantiateClass(Constructor < T > ctor, Object...args) throws BeanInstantiationException {Assert.notNull(ctor, "Constructor must not be null");try {ReflectionUtils.makeAccessible(ctor);if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {return KotlinDelegate.instantiateClass(ctor, args);} else {Class <? > [] parameterTypes = ctor.getParameterTypes();Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");Object[] argsWithDefaultValues = new Object[args.length];for (int i = 0; i < args.length; i++) {if (args[i] == null) {Class <? > parameterType = parameterTypes[i];argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);} else {argsWithDefaultValues[i] = args[i];}}return ctor.newInstance(argsWithDefaultValues);}} catch (InstantiationException ex) {throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);} catch (IllegalAccessException ex) {throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);} catch (IllegalArgumentException ex) {throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);} catch (InvocationTargetException ex) {throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());}
}

          newInstance的源码如下所示,我们显然应该关注的是倒数第二行T inst = (T) ca.newInstance(initargs);

@CallerSensitive
public T newInstance(Object...initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {if (!override) {if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {Class <? > caller = Reflection.getCallerClass();checkAccess(caller, clazz, null, modifiers);}}if ((clazz.getModifiers() & Modifier.ENUM) != 0)throw new IllegalArgumentException("Cannot reflectively create enum objects");ConstructorAccessor ca = constructorAccessor; // read volatileif (ca == null) {ca = acquireConstructorAccessor();}@SuppressWarnings("unchecked")T inst = (T) ca.newInstance(initargs);return inst;
}

         创建完实例后如下图所示,可见这时Cource类只是刚实例化出来,还没有进行初始化(courceName会在afterPropertiesSet方法中被赋值),代码到这里就看完了实例化的过程。

六、属性填充 

         我们所举例的代码中,Student类中注入了Course类,因此我们关注Student类的实例创建及属性填充。我们再回到上面提到的doCreateBean源码中,如下所示,可以看到在Object exposedObject = bean;这行代码的下面有一行populateBean(beanName, mbd, instanceWrapper);这样的代码。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class <? > beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// Allow post-processors to modify the merged bean definition.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;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}addSingletonFactory(beanName, () - > getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject = bean;try {populateBean(beanName, mbd, instanceWrapper);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) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set < String > actualDependentBeans = new LinkedHashSet < > (dependentBeans.length);for (String dependentBean: dependentBeans) {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 " +"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");}}}}// Register bean as disposable.try {registerDisposableBeanIfNecessary(beanName, bean, mbd);} catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;
}

         populateBean方法源码如下,这段代码中真正执行自动注入逻辑的代码是如下图所示代码

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {if (bw == null) {if (mbd.hasPropertyValues()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");} else {// Skip property population phase for null instance.return;}}// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the// state of the bean before properties are set. This can be used, for example,// to support styles of field injection.if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (InstantiationAwareBeanPostProcessor bp: getBeanPostProcessorCache().instantiationAware) {if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}}}PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);int resolvedAutowireMode = mbd.getResolvedAutowireMode();if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs = new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable.if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}// Add property values based on autowire by type if applicable.if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs;}boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);PropertyDescriptor[] filteredPds = null;if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();}for (InstantiationAwareBeanPostProcessor bp: getBeanPostProcessorCache().instantiationAware) {PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {return;}}pvs = pvsToUse;}}if (needsDepCheck) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}checkDependencies(beanName, mbd, filteredPds, pvs);}if (pvs != null) {applyPropertyValues(beanName, mbd, bw, pvs);}
}

         真正去执行自动注入的组件是AutowiredAnnotationBeanPostProcessor,而AutowiredAnnotationBeanPostProcessor又是InstantiationAwareBeanPostProcessor的实现类,AutowiredAnnotationBeanPostProcessor类中的postProcessProperties()方法负责解析@Autowired和@Value等注解。当调用到getBeanPostProcessorCache().instantiationAware的postProcessAfterInstantiation方法时就会调用到 AutowiredAnnotationBeanPostProcessor 的 postProcessProperties() 方法,从而完成自动注入,也就是完成属性填充。如下图所示

七、Aware接口回调 

        我们上面看完了属性填充阶段的代码,接下来就该看初始化的方法了,不过在初始化之前会先进行Aware接口回调,我们通过代码来印证一下。

       我们回到上面提到的doCreateBean源码内部,如下所示,我们找到刚才属性填充那一行代码的下一行代码,也就是populateBean方法下面的exposedObject = initializeBean(beanName, exposedObject, mbd);这行代码

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class <? > beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// Allow post-processors to modify the merged bean definition.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;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}addSingletonFactory(beanName, () - > getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject = bean;try {populateBean(beanName, mbd, instanceWrapper);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) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set < String > actualDependentBeans = new LinkedHashSet < > (dependentBeans.length);for (String dependentBean: dependentBeans) {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 " +"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");}}}}// Register bean as disposable.try {registerDisposableBeanIfNecessary(beanName, bean, mbd);} catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;
}

         我们进入到方法initializeBean内部,如下所示,我们在第一个else分支中可以看到invokeAwareMethods(beanName, bean);这么一行代码,从字面意思就可以看出来这是要执行Aware接口回调了。

protected Object initializeBean(String beanName, 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()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {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()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}

           我们debug代码走到Student类的初始化流程,看看代码执行到invokeAwareMethods方法内部时,我们可以看到代码会走setBeanName方法,而我们的Student类中因为实现了BeanNameAware接口,因此重写了setBeanName方法,因此代码走到这里就该去Student类中执行setBeanName方法了。

        我们debug结果如下图所示,可以看到,确实是进入到Student类的setBeanName方法中去执行了。这就是Aware接口回调的简单应用。

 八、初始化前处理器(BeanPostProcessor前置处理)

         我们目前代码走到这里,Student类还没有完成初始化呢,而在初始化方法被调用之前,还有个步骤就是初始化前置处理器,我们从源码来看,我们先回到initializeBean方法源码,如下所示,这里面有一行代码是wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);这就是执行初始化前置处理器,我们这里没有举初始化前置处理所用到的例子(涉及到初始化前置处理器的场景包括我们的类中使用了@PostConstruct注解修饰一个初始化方法,这种场景下,执行@PostConstruct这个注解修饰的方法就发生在初始化前置处理器之中

protected Object initializeBean(String beanName, 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()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {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()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}

  九、初始化

          在看完初始化前置处理器之后,我们紧接着就是看初始化的源码,我们还是回到initializeBean方法内部,如下所示,中间try中的那行invokeInitMethods(beanName, wrappedBean, mbd);代码就是执行初始化逻辑。

protected Object initializeBean(String beanName, 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()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {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()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}

         我们为验证这个,还是通过debug的方式来进行,我们进入到invokeInitMethods源码内部,在代码中间else分支中有一行((InitializingBean) bean).afterPropertiesSet();便是执行Student类中的afterPropertiesSet方法。

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {boolean isInitializingBean = (bean instanceof InitializingBean);if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isTraceEnabled()) {logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");}if (System.getSecurityManager() != null) {try {AccessController.doPrivileged((PrivilegedExceptionAction < Object > )() - > {((InitializingBean) bean).afterPropertiesSet();return null;}, getAccessControlContext());} catch (PrivilegedActionException pae) {throw pae.getException();}} else {((InitializingBean) bean).afterPropertiesSet();}}if (mbd != null && bean.getClass() != NullBean.class) {String initMethodName = mbd.getInitMethodName();if (StringUtils.hasLength(initMethodName) &&!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.isExternallyManagedInitMethod(initMethodName)) {invokeCustomInitMethod(beanName, bean, mbd);}}
}

         代码执行效果如下图所示,可以看到确实进入到afterPropertiesSet方法内部了。从而这里就完成了初始化的动作。

十、初始化后置处理器 

       我们demo中没有涉及到初始化后置处理器的场景,但其实我们最常见的AOP,就可能发生在这个阶段。初始化后置处理器的源码我们还是回到上面提到的initializeBean方法源码内部,如下所示,在差不多最下面有一行wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);代码,就是处理初始化后置处理器的。

protected Object initializeBean(String beanName, 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()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {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()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}

          经过以上步骤之后,我们的Bean就初始化完成了,也就准备就绪了。我这里只是举了一个比较简单的场景,更多复杂的场景大家可以自行研究学习。

http://www.dtcms.com/wzjs/582578.html

相关文章:

  • 网站开发策划案国际电商平台排名
  • 做网站优化需要做哪些事项河北网站建设备案
  • 电子商务网站开发时间进度表网站建设调研提纲
  • 做1688网站需要懂英语吗wordpress优化软件
  • php 网站开发工程师湖北网站建设哪家好
  • 织梦企业网站源码广东省建设教育协会网站
  • 微网站模板 餐饮沈阳网约车公司
  • 推广网站案例一个人怎么开贸易公司
  • 电子商务做网站设计梧州市建设局网站
  • 行业网站建设的书公司网站建设宣传话语
  • 申请完域名如何建网站Wordpress建立空白页面
  • 网站建站上海旅游商城网站订单处理
  • 嘉兴网站建设有前途吗常平网页设计
  • 网站建设与网页设计大作业网站的优化公司
  • 版纳网站建设滴滴出行网站建设
  • 漳州网站建设哪家好南京网站制作报价
  • 沈阳方正建设监理网站做网站合同范本
  • 做seo网站 公司网站做贷款许可证
  • 做网站 能挣钱吗网站后台程序开发教程
  • 网站推广公司渠道wordpress免邮箱 注册
  • 阿里云网站建设部署与发布网站建设的编程技术
  • soho建设外贸网站管理系统入口admin
  • 嘉兴网站建设有前途吗东营
  • 网站开发广告语大全各类服装网站建设
  • 杭州网站建设培训学校网页游戏代理加盟
  • 上海网站优化上寻花问柳专注做一家男人最爱的网站
  • 微信公众号的h5网站开发6黑龙江省建设厅官网
  • 有经验的常州手机网站discuz 网站搬家
  • 大连建设教育网站wordpress上一篇下一篇插件
  • 咋么做进网站跳转加群中国免费素材网站