Spring5深度源码分析(三)之AnnotationConfigApplicationContext启动原理分析
代码地址:https://github.com/showkawa/spring-annotation/tree/master/src/main/java/com/brian
AnnotationConfigApplicationContext启动原理分析主要分析下面三点
1.@Qualifier与@Primary注解的使用
2.BeanFactory与ApplicationContext区别
3.AnnotationConfigApplicationContext启动原理分析
1.@Qualifier与@Primary注解的使用
下面是 @Qualifier 和 @Primary注解的官方解释
@Qualifier
This annotation may be used on a field or parameter as a qualifier for candidate beans when autowiring. It may also be used to annotate other custom annotations that can then in turn be used as qualifiers.这个注释可用于作为预备bean的字段或参数,也可以用在其他的自定义注释下 @Qualifier(“XXX”) Spring的Bean注入配置注解,该注解指定注入的Bean的名称,Spring框架使用byName方式寻找合格的bean,这样就消除了byType方式产生的歧义。
qualifer字面意思合格者,一般情况下:代码里面需要注入其他依赖,一般用@Reource( 默认按名称装配,当找不到与名称匹配的bean才会按类型装配和@Autowired(默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用)
@Primary
Indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency. If exactly one ‘primary’ bean exists among the candidates, it will be the autowired value. This annotation is semantically equivalent to the {@code} element’s {@code primary} attribute 不难看出如果用primary注解其中一个bean就要优先于其他的Bean,当然这个对于这种三方jar包最好不要添加的,谁知道它会不会后期又出什么幺蛾子,只能改自己的代码了最后的方案是改成@qualifiel(“getMetricRegistry”),选取了其中一个bean注入
primary字面意思最主要者,如果是有配置过多数据源,那一定会熟悉这个注解
1.1 @Qualifier的使用
我们这里定义一个BookService接口
public interface BookService { void printBook(); }
两个实现类BookServiceImpl和OtherBookServiceImpl实现BookService接口的printBook()方法
@Service public class BookServiceImpl implements BookService { @Override public void printBook() { System.out.println("---BookServiceImpl---: spring5源码分析"); } }
@Service public class OtherBookServiceImpl implements BookService { @Override public void printBook() { System.out.println("---OtherBookServiceImpl---: 天道酬勤,一步一个坑"); } }
我们在BookController注入BooKService
@Controller public class BookController { @Autowiredprivate BookService bookService; private void printBook() { bookService.printBook(); } }
附上配置类MainConfig
@Configuration //告诉spring这是一个配置类 /* * @ComponentScan * value:只当于扫描的的包 * excludeFilters = 指定扫描的时候按照什么规则排除哪些组件 * includeFilters = 指定扫描的时候只需要包含哪些组件 * Filter.ANNOTATION:按照注解 * Filter.ASSIGNABLE_TYPE: 按照给定的类型 * */ //@ComponentScans(value = { // @ComponentScan(value = "com.brian",includeFilters = { // @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class}), // @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,classes = {BookService.class}), // @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {BrianTypeFilter.class}) // },useDefaultFilters = false) //}) @ComponentScan({"com.brian.service", "com.brian.controller"}) //@Import({Brian.class,Alan.class}) @Import({BrianSelector.class}) public class MainConfig { @Bean("person") //给容器中注册一个Bean;类型为返回值的类型;id默认是方法名作为id public Person person(){ return new Person("Alan",18); } /* * @Conditional() 按照条件注册 * * */ @Conditional({BrianCondition.class}) @Bean("person01") public Person person01() { return new Person("Brian",17); } @Conditional({BrianCondition.class}) @Bean("person02") public Person person02() { return new Person("wenTao",19); } /* * *给容器中注册组件 * 1,包扫描+ 组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的方法] * 2, @Bean [导入的第三方包里面的组件] * 3,@Import [快速的给容器导入一个组件] * 1.@Import(要导入的组件class) * 2.ImportSelector:返回需要导入的组件的全类名数组 * 3.ImportBeanDefinitionRegistrar: 手动注册bean到容器 * 4. 使用Spring提供的FactoryBean * */ @Bean public BrianBeanFactory brianBeanFactory() { return new BrianBeanFactory(); } }
在测试类MainTest类中测试该printBook()方法
public class MainTest { public static void main(String[] args) { ApplicationContext mainConfig = new AnnotationConfigApplicationContext(MainConfig.class); System.out.println("MainConfig容器创建成功"); BookController bookController = mainConfig.getBean(BookController.class); try { Method printBook = bookController.getClass().getDeclaredMethod("printBook"); printBook.setAccessible(true); printBook.invoke(bookController); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } // Alan alan1 = acac.getBean(Alan.class); // System.out.println("--ALAN--:" + alan1); // Alan alan2 = acac.getBean(Alan.class); //System.out.println("比较两个Alan实例: " + (alan1 == alan2)); // Person person1 = (Person) acac.getBean("person01"); // System.out.println("---main---test---person1---: " + person1.toString()); // Person person2 = (Person) acac.getBean("person02"); // System.out.println("---main---test---person2---: " + person2.toString()); // MathCalculator mathCalculator = (MathCalculator) acac.getBean("mathCalculator"); // System.out.println("----get--mathCalculator---: " + mathCalculator); // BrianBeanFactory beanFactory = acac.getBean(BrianBeanFactory.class); // WenTao wentao = null; // try { // wentao = beanFactory.getObject(); // } catch (Exception e) { // e.printStackTrace(); // } // System.out.println("----get--WenTao---: " + wentao); //关闭ioc容器 ((AnnotationConfigApplicationContext) mainConfig).close(); } }
看到有报错No qualifying bean of type 'com.brian.service.BookService' available: expected single matching bean but found 2: bookServiceImpl,otherBookServiceImpl,就是因为默认按类型装配
OK,此时我在BookController注入BookSevice的时候加上@Qualifier指定beanName,再次测试
@Controller public class BookController { @Autowired @Qualifier("bookServiceImpl") private BookService bookService; private void printBook() { bookService.printBook(); } }
1.2 @Primary的使用
继续返回到上面的报错时候的场景,因为此时BookService有两个实现类,此时我在OtherBookServiceImpl类上加上@Primary注解,再次测试
@Service @Primary public class OtherBookServiceImpl implements BookService { @Override public void printBook() { System.out.println("---OtherBookServiceImpl---: 天道酬勤,一步一个坑"); } }
这里顺便总结下常用的注解:
@Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean。
@Scope注解 作用域
@Lazy(true) 表示延迟初始化
@Service用于标注业务层组件、
@Controller用于标注控制层组件
@Repository用于标注数据访问组件,即DAO组件。
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
@Scope用于指定scope作用域的(用在类上)
@PostConstruct用于指定初始化方法(用在方法上)
@PreDestory用于指定销毁方法(用在方法上)
@Resource 默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
@DependsOn:定义Bean初始化及销毁时的顺序
@Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
@Autowired 默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用
@Autowired @Qualifier("OtherBookServiceImpl") 存在多个实例配合使用
2.BeanFactory与ApplicationContext区别
之前的源码分析有见过BeanFactory和FactoryBean接口的区别,FactoryBean是创建bean对象,而BeanFactory是获取对象。但ApplicationContext也可以获取对象,我上面的测试类getBean()方法就是的。同样都可以获取bean对象BeanFactory与ApplicationContext有什么区别?
1. BeanFactory负责读取bean配置文档,管理bean的加载,实例化,维护bean之间的依赖关系,负责bean的声明周期。
2. ApplicationContext除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能: a. 国际化支持 b. 资源访问:Resource rs = ctx. getResource(“classpath:config.properties”), “file:E:/config.properties” c. 事件传递:通过实现ApplicationContextAware接口 3. 常用的获取ApplicationContext的方法:
AnnotationConfigApplicationContext 从@Configuration配置类创建容器 FileSystemXmlApplicationContext:从【文件系统】 或者 【classpath的xml配置文件】 创建,参数为配置文件名或文件名数组 ClassPathXmlApplicationContext:从【classpath的xml配置文件】创建,可以从【jar包】中读取配置文件 WebApplicationContextUtils:从web应用的根目录读取配置文件,需要先在web.xml中配置,可以配置监听器或者servlet来实现
Spring的IoC容器就是一个实现了BeanFactory接口的可实例化类。事实上, Spring提供了两种不同的容器:一种是最基本的BeanFactory,另一种是扩展的ApplicationContext。
BeanFactory在初始化容器时 并未实例化Bean, 直到第一次访问 某个Bean时才实例目标Bean;而ApplicationContext则在初始化应用上下文时就实例化所有的单实例的Bean。
因此ApplicationContext的初始化时间会比BeanFactory稍长一些.
3.AnnotationConfigApplicationContext启动原理分析
从AnnotationConfigApplicationContext的类图中可以看出:
AnnotationConfigApplicationContext继承GenericApplicationContext这个通用应用上下文,GenericApplicationContext内部定义了一个DefaultListableBeanFactory实例,
GenericApplicationContext实现了BeanDefinitionRegistry接口,所以可以通过AnnotationConfigApplicationContext实例注册beanDefinition,然后调用refresh()方法来初始化上下文。
AnnotationConfigApplicationContext继承AbstractApplicationContext,AbstractApplicationContext提供了ApplicationContext的抽象实现。
我这边就从MainTest这个测试类开始AnnotationConfigApplicationContext启动原理分析:
MainTest测试类:
public class MainTest { public static void main(String[] args) {
// 1.读取配置类创建IOC容器 ApplicationContext mainConfig = new AnnotationConfigApplicationContext(MainConfig.class); System.out.println("MainConfig容器创建成功"); BookController bookController = mainConfig.getBean(BookController.class); try { Method printBook = bookController.getClass().getDeclaredMethod("printBook"); printBook.setAccessible(true); printBook.invoke(bookController); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); }//关闭ioc容器 ((AnnotationConfigApplicationContext) mainConfig).close(); } }
AnnotationConfigApplicationContext点进去,我这边后面的源码都会附带官方注释的翻译
/**
*创建一个新的AnnotationConfigApplicationContext,派生bean定义
*来自给定的带注释的类并自动刷新上下文。
* @param annotatedClasses一个或多个带注释的类,
*例如 {@link Configuration @Configuration}类
*/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//1. 初始化bean读取器和扫描器;
/** 调用父类GenericApplicationContext无参构造函数,初始化一个BeanFactory: this.beanFactory = new DefaultListableBeanFactory()*/
this();
// 2.注册bean配置类
register(annotatedClasses);
// 3.刷新上下文
refresh();
}
现在我们点进去this()这个方法;
/**
*创建一个需要填充的新AnnotationConfigApplicationContext
*通过{@link #register}调用,然后手动{@linkplain #refresh刷新}。
*/
public AnnotationConfigApplicationContext() {
//在IOC容器中初始化注解bean读取器AnnotatedBeanDefinitionReader this.reader = new AnnotatedBeanDefinitionReader(this);
//在IOC容器中初始化按类路径扫描注解bean的扫描器 this.scanner = new ClassPathBeanDefinitionScanner(this); }
this()方法在调用自身的无参构造方法时会先走父类GenericApplicationContext的无参构造方法
/**
*创建一个新的GenericApplicationContext。
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
//初始化一个BeanFactory this.beanFactory = new DefaultListableBeanFactory(); }
现在我们再点进去看下register(annotatedClasses)这个方法,直接调用AnnotatedBeanDefinitionReader的register方法
/** *注册一个或多个要处理的注释类。 * <p>对{@code register}的调用是幂等的; 添加相同的 *注释类不止一次没有额外的效果。 * @param annotatedClasses一个或多个带注释的类, *例如 {@link Configuration @Configuration}类 */ public void register(Class<?>... annotatedClasses) { for (Class<?> annotatedClass : annotatedClasses) { registerBean(annotatedClass); } } /** *从给定的bean类注册bean,从中派生元数据 *类声明的注释。 * @param annotatedClass bean的类 */ public void registerBean(Class<?> annotatedClass) { doRegisterBean(annotatedClass, null, null, null); } /** *从给定的bean类注册bean,从中派生元数据 *类声明的注释。 * @param annotatedClass bean的类 * @param instanceSupplier用于创建bean实例的回调 *(可能是{@code null}) * @param命名bean的显式名称 * @param限定符特定限定符注释要考虑,如果有的话, *除了bean类级别的限定符 * @param definition定制一个或多个用于自定义的回调 *工厂的{@link BeanDefinition},例如 设置lazy-init或主标志 * @since 5.0 */ <T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) { /** 将Bean配置类信息转成容器中AnnotatedGenericBeanDefinition数据结构,
* AnnotatedGenericBeanDefinition继承自BeanDefinition作用是定义一个bean的数据结构,
* 下面的getMetadata可以获取到该bean上的注解信息 */ AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
//@Conditional装配条件判断是否需要跳过注册 if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { return; }
//设置回调 @param instanceSupplier 用于创建bean实例的回调 abd.setInstanceSupplier(instanceSupplier);
//解析bean作用域(单例或者原型),如果有@Scope注解,则解析@Scope,没有则默认为singleton ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//作用域写回BeanDefinition数据结构, abd中缺损的情况下为空,将默认值singleton重新赋值到abd abd.setScope(scopeMetadata.getScopeName());
//生成bean配置类beanName String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//通用注解解析到abd结构中,主要是处理Lazy, primary DependsOn, Role ,Description这五个注解 AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
// @Qualifier特殊限定符处理,@param qualifiers 除了bean类级别的限定符之外,要考虑的限定符特定限定符注释(如果有) if (qualifiers != null) { for (Class<? extends Annotation> qualifier : qualifiers) { if (Primary.class == qualifier) {
// 如果配置@Primary注解,则设置当前Bean为自动装配autowire时首选bean abd.setPrimary(true); } else if (Lazy.class == qualifier) {
//设置当前bean为延迟加载 abd.setLazyInit(true); } else {
//其他注解,则添加到abd结构中 abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } }
/**自定义bean注册,通常用在applicationContext创建后,手动向容器中一lambda表达式的方式注册bean,
* 比如:applicationContext.registerBean(BookService.class, () -> new BookService()); */
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
//自定义bean添加到BeanDefinition customizer.customize(abd); }
//根据beanName和bean定义信息封装一个beanhold,heanhold其实就是一个 beanname和BeanDefinition的映射 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//创建代理对象 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
/** BeanDefinitionReaderUtils.registerBeanDefinition 内部通过
* DefaultListableBeanFactory.registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
* 按名称将bean定义信息注册到容器中,实际上DefaultListableBeanFactory内部维护一个Map<String, BeanDefinition>类型变量beanDefinitionMap,
* 用于保存注bean定义信息(beanname 和 beandefine映射)*/ BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); }
register方法重点完成了bean配置类本身的解析和注册,处理过程可以分为以下几个步骤:
1.根据bean配置类,使用BeanDefinition解析Bean的定义信息,主要是一些注解信息
2.Bean作用域的处理,没有@Scope注解默认解析成单例
3.借助AnnotationConfigUtils工具类解析通用注解
4.将bean定义信息已beanname,beandifine键值对的形式注册到ioc容器中
然后我们继续点进去refresh()方法
refresh方法在AbstractApplicationContext容器中实现,refresh()方法的作用加载或者刷新当前的配置信息,如果已经存在spring容器,则先销毁之前的容器,重新创建spring容器,载入bean定义,完成容器初始化工作,所以可以看出AnnotationConfigApplicationContext容器是通过调用其父类AbstractApplicationContext的refresh()函数启动整个IoC容器完成对Bean定义的载入。
AbstractApplicationContext类的refresh()方法源代码如下:
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //1.刷新前的预处理 prepareRefresh(); //2.获取刷新后的内部Bean工厂 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //3.BeanFactory的预准备工作 prepareBeanFactory(beanFactory); try { // BeanFactory准备工作完成后,可以做一些后置处理工作
// 4.空方法,用于在容器的子类中扩展 postProcessBeanFactory(beanFactory); // 5. 执行BeanFactoryPostProcessor的方法,BeanFactory的后置处理器,在BeanFactory标准初始化之后执行的 invokeBeanFactoryPostProcessors(beanFactory); // 6. 注册BeanPostProcessor(Bean的后置处理器),用于拦截bean创建过程,实现对bean的增强 registerBeanPostProcessors(beanFactory); // 7. 初始化MessageSource组件(做国际化功能;消息绑定,消息解析) initMessageSource(); // 8. 初始化事件派发器 initApplicationEventMulticaster(); // 9.空方法,可以用于子类实现在容器刷新时自定义逻辑 onRefresh(); // 10. 注册事件监听器,将所有项目里面的ApplicationListener注册到容器中来 registerListeners(); // 11. 初始化所有剩下的单实例bean,单例bean在初始化容器时创建,原型bean在获取时(getbean)时创建 finishBeanFactoryInitialization(beanFactory); // 12. 完成BeanFactory的初始化创建工作,IOC容器就创建完成; finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } //销毁已经创建的单例,以避免挂起资源。 destroyBeans(); //重置“活动”标志。 cancelRefresh(ex); //向调用者传播异常。 throw ex; } finally { //在Spring的core中重置常见的内省缓存,因为我们可能不再需要单例bean的元数据了... resetCommonCaches(); } } }
接下来我们要分析refresh()里面的这些方法
3.1 prepareRefresh ()刷新预处理方法:
/**
*准备此上下文以进行刷新,设置其启动日期和
*活动标志以及执行属性源的任何初始化。
*/
protected void prepareRefresh() { //设置容器启动时间 this.startupDate = System.currentTimeMillis();
//启动标识 this.closed.set(false); this.active.set(true); if (logger.isDebugEnabled()) { if (logger.isTraceEnabled()) { logger.trace("Refreshing " + this); } else { logger.debug("Refreshing " + getDisplayName()); } } //空方法,用于子容器自定义个性化的属性设置方法 initPropertySources(); //检验属性的合法等 getEnvironment().validateRequiredProperties(); //存储预刷新应用程序监听器… if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); } else { //将本地应用程序侦听器重置为预刷新状态。 this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } //保存容器中的一些早期的事件 this.earlyApplicationEvents = new LinkedHashSet<>(); }
3.2 obtainFreshBeanFactory()方法
该方法获取刷新后的内部Bean工厂,obtainFreshBeanFactory方法为内部bean工厂重新生成id,并返回bean工厂
/**
*告诉子类刷新内部bean工厂。
* @return新鲜的BeanFactory实例
* @see #refreshBeanFactory()
* @see #getBeanFactory()
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
/**
*为beanfactory生成唯一序列化id,beanfactory已经在GenericApplicationContext构造函数中初始化了,
*refreshBeanFactory的逻辑在AbstractApplicationContext的实现类GenericApplicationContext中
*/
refreshBeanFactory();
//获取beanfactory return getBeanFactory(); }
GenericApplicationContext类的refreshBeanFactory()方法
//--------------------------------------------------------------------- 实现AbstractApplicationContext的模板方法 //--------------------------------------------------------------------- / * * *什么都不做:我们只有一个内部BeanFactory,并且依赖于调用者 *通过我们的公共方法(或BeanFactory的)注册bean。 * @see # registerBeanDefinition * / @Override protected final void refreshBeanFactory() throws IllegalStateException { if (!this.refreshed.compareAndSet(false, true)) { throw new IllegalStateException( "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once"); }
//生成一个序列化id this.beanFactory.setSerializationId(getId()); }
这里使用AbstractApplicationContext.refreshBeanFactory()如果是注解的方式实现,则并没有解析项目包下的注解,而是通过在refresh()方法中执行ConfigurationClassPostProcessor后置处理器完成对bean的加载.
3.3 prepareBeanFactory(beanFactory)方法
prepareBeanFactory主要完成beanFactory的一些属性设置,BeanFactory的预准备工作
/** *配置工厂的标准上下文特征, *例如上下文的ClassLoader和后置处理器。 * @param beanFactory要配置的BeanFactory */ protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { //告诉内部bean工厂使用上下文的类加载器等等。 //设置类加载器
beanFactory.setBeanClassLoader(getClassLoader());
//bean表达式解析器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //使用上下文回调配置bean工厂。 //添加一个BeanPostProcessor实现ApplicationContextAwareProcessor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//设置忽略的自动装配接口,表示这些接口的实现类不允许通过接口自动注入 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); //注册可以自动装配的组件,就是可以在任何组件中允许自动注入的组件 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); //将早期后置处理器注册为application监听器,用于检测内部bean。 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); //添加编译时的AspectJ if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); //为匹配的类型设置一个临时类加载器。 beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // 给beanfactory容器中注册组件ConfigurableEnvironment、systemProperties、systemEnvironment if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
3.4 invokeBeanFactoryPostProcessors(beanFactory)方法
invokeBeanFactoryPostProcessors 执行bean工厂后置处理器
/** *实例化并调用所有已注册的BeanFactoryPostProcessor beans, *如果给定则遵守显示的顺序。 * <p>必须在单例实例化之前调用。 */ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
invokeBeanFactoryPostProcessors方法内部执行实现了BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor这两个接口的Processor,先获取所有BeanDefinitionRegistryPostProcessor的实现,按优先级执行(是否实现PriorityOrdered优先级接口,是否实现Ordered顺序接口);再以相同的策略执行所有BeanFactoryPostProcessor的实现。
PostProcessorRegistrationDelegate. invokeBeanFactoryPostProcessors实现:
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { //如果有的话,首先调用BeanDefinitionRegistryPostProcessors。 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); } }
//不要在这里初始化FactoryBeans:我们需要保留所有常规bean
//未初始化的,让bean工厂的后置处理程序负责于它们!
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); //首先,调用实现PriorityOrated接口的BeanDefinitionRegistryPostProcessors类的方法。 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); currentRegistryProcessors.clear(); //接下来,调用实现Ordered接口的BeanDefinitionRegistryPostProcessors类的方法。 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); currentRegistryProcessors.clear(); //最后,调用所有其他BeanDefinitionRegistryPostProcessors,直到没有其他的后置处理器出现。 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); currentRegistryProcessors.clear(); } //现在,调用到目前为止处理完所有处理器的postProcessBeanFactory回调。 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { //调用在上下文实例中注册的工厂处理器。 invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } //不要在这里初始化FactoryBeans:我们需要保留所有常规bean //未初始化,以让bean工厂的后值处理器负责于它们! String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { //跳过-已经在上面的第一阶段处理 } 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); } } //首先,调用实现PriorityOrated接口的BeanFactoryPostProcessors类。 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); //接下来,调用实现Ordered接口的BeanFactoryPostProcessors类方法。 List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); //最后,调用所有其他BeanFactoryPostProcessors,直到没有其他的后置处理器出现。 List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); //清除缓存的合并bean定义,因为后置处理器可能修改了原始元数据,例如替换了值中的占位符…… beanFactory.clearMetadataCache(); }
这里面在处理BeanDefinitionRegistryPostProcessors时有一个非常重要的过程,AnnotationConfigApplicationContext构造函数在初始化reader时为内部beanFactory容器初始化了一个id为org.springframework.context.annotation.internalConfigurationAnnotationProcessor的组件,这是一个ConfigurationClassPostProcessor组件,用来处理添加@Configuration注解的类,并将Bean定义注册到BeanFactory中。
3.5 invokeBeanFactoryPostProcessors(beanFactory)方法
注册后置处理器的大致逻辑是:
1.获取所有的 BeanPostProcessor
2.根据处理器实现的接口区分出4中类型:
2.1.实现PriorityOrdered接口的处理器
2.2.实现Ordered接口的处理器,
2.3.实现MergedBeanDefinitionPostProcessor接口的处理器,
2.4.普通后置处理器
3.按这个4中类型依次注册到容器中
4.注册一个特殊的后置处理器ApplicationListenerDetector,ApplicationListenerDetector本身也实现了MergedBeanDefinitionPostProcessor接口
/ * * *实例化并注册所有BeanPostProcessor bean,如果给定则遵循显式顺序。 * <p>必须在应用程序bean的任何实例化之前调用。 * / protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }
public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); //注册BeanPostProcessorChecker,当bean在BeanPostProcessor实例化过程中被创建时,即当一个bean没有资格被所有BeanPostProcessor处理时,它记录一条信息到日志。 int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); //按优先级分类 List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<BeanPostProcessor> internalPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } //首先,调用实现PriorityOrated接口的BeanPostProcessors类。 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); //接下来,调用实现Ordered接口的BeanPostProcessors类方法。 List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(); for (String ppName : orderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); //现在,注册所有常规的BeanPostProcessors。 List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); //最后,调用所有其他BeanPostProcessors,直到没有其他的后置处理器出现。 sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); //注册ApplicationListenerDetector,用于Bean创建完时检查是否是ApplicationListener beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }
3.6 initMessageSource()方法
初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
/ * * 初始化MessageSource。 *如果在此上下文中没有定义,则使用父类的。 * / protected void initMessageSource() { //获取beanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); //让MessageSource知道父类的MessageSource。 if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) { HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource; if (hms.getParentMessageSource() == null) { //如果没有注册父类的MessageSource,则只将父类的上下文设置为父类的MessageSource。 hms.setParentMessageSource(getInternalParentMessageSource()); } } if (logger.isTraceEnabled()) { logger.trace("Using MessageSource [" + this.messageSource + "]"); } } else { //使用空的MessageSource来接受getMessage调用。 DelegatingMessageSource dms = new DelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource()); this.messageSource = dms; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); if (logger.isTraceEnabled()) { logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]"); } } }
3.7 initApplicationEventMulticaster()方法
初始化事件派发器
/ * * 初始化ApplicationEventMulticaster。 如果上下文中没有定义,则使用SimpleApplicationEventMulticaster。 * @see org.springframework.context.event.SimpleApplicationEventMulticaster * / protected void initApplicationEventMulticaster() { //获取BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//如果有配置beanName为applicationEventMulticaster的事件派发器,则将其赋给容器中的applicationEventMulticaster对象 if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isTraceEnabled()) { logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else {
//不存在,则创建一个SimpleApplicationEventMulticaster事件派发器,并注册到beanfactory中 this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isTraceEnabled()) { logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " + "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]"); } } }
3.8 registerListeners()方法
registerListeners方法主要实现将事件监听器添加到IOC容器中的事件派发器中,并在最后做了一个事件发布的逻辑(如果之前的步骤有产生事件,则将earlyApplicationEvents中保存的事件逐一发布)
/ * * 添加实现ApplicationListener作为侦听器的bean。 *不影响其他侦听器,可以在不添加bean的情况下添加。 * / protected void registerListeners() { //首先注册静态指定的监听器。 for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } //不要在这里初始化factorybean:我们需要不初始化所有常规bean,以便让后置处理器处理它们 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } //发布早期的application事件… Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
3.9 finishBeanFactoryInitialization(beanFactory)方法
初始化所有剩下的单实例bean,单例bean在初始化容器时创建,原型bean在获取时(getbean)时创建
/ * * *完成这个上下文的bean工厂的初始化, 初始化所有剩余的单例bean。 * / protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { //初始化此上下文的转换服务。 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)); } //如果之前没有注册bean后置处理器(例如PropertyPlaceholderConfigurer bean),则注册一个默认的嵌入式值解析器:此时,主要用于在注释属性值中进行解析。 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } //提前初始化LoadTimeWeaverAware beans,以便尽早注册它们的转换器。 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } //停止使用临时类加载器进行类型匹配。 beanFactory.setTempClassLoader(null); //允许缓存所有bean定义元数据,不需要进一步更改。 beanFactory.freezeConfiguration(); //实例化所有剩余的(非懒加载初始化)单例。 beanFactory.preInstantiateSingletons(); }
DefaultListableBeanFactory. preInstantiateSingletons()方法的实现:
@Override public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } //容器中所有bean名称 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); for (String beanName : beanNames) {
//获取Bean的定义信息;RootBeanDefinition RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//非抽象,单例,非延迟加载 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//是否是FactoryBean if (isFactoryBean(beanName)) {
// 通过"&beanName"获取工厂Bean实例 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final 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 {
//不是FactoryBean,则利用getBean(beanName)实例化bean getBean(beanName); } } } for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
3.10 finishRefresh()方法
完成BeanFactory的初始化创建工作,代码走到这一步IOC容器就创建完成
/ * * *调用LifecycleProcessor,完成此上下文的刷新 方法并发布 * {@link org.springframework.context.event.ContextRefreshedEvent}。 * / protected void finishRefresh() { //清除上下文级的资源缓存(例如来自扫描的ASM元数据)。 clearResourceCaches(); //初始化和生命周期有关的后置处理器LifecycleProcessor,默认DefaultLifecycleProcessor initLifecycleProcessor(); // 回调生命周期处理器 getLifecycleProcessor().onRefresh(); //发布容器刷新完成事件:ContextRefreshedEvent publishEvent(new ContextRefreshedEvent(this)); LiveBeansView.registerApplicationContext(this); }
以上基本分析了AnnotationConfigApplicationContext容器的初始化过程, Spring容器在启动过程中,会先保存所有注册进来的Bean的定义信息;Spring容器根据条件创建Bean实例,区分单例,还是原型,后置处理器等(后置处理器会在容器创建过程中通过getBean创建,并执行相应的逻辑);Spring容器在创建bean实例后,会使用多种后置处理器来增加bean的功能,比如处理自动注入,AOP,异步,这种后置处理器机制也丰富了bean的功能。
我这边在AnnotationConfigApplicationContext启动原理分析的代码走读部分有参考博客: https://www.cnblogs.com/ashleyboy/p/9662119.html ,不过有些类的方法会有点不一样,因为我这边时基于Spring5.X的版本分析