赞
踩
Spring创建Bean,会经过一系列生命周期的流程,而Spring启动,其实就是为了后续创建Bean做一些准备工作,本篇以及下一篇文章都是来详细分析Spring的启动过程。
目录
二、Spring加载流程之AnnotatedBeanDefinitionReader
2.AnnotationConfigApplicationContext的构造函数
3.AnnotatedBeanDefinitionReader的构造函数
4.AnnotationConfigUtils中的registerAnnotationConfigProcessors()
五、BeanDefinitionRegistryPostProcessor
通常,我们说的Spring启动,其实就是构造ApplicationContext对象以及调用refresh()方法的过程。那么这个过程会涉及到哪些操作呢?以下基于AnnotationConfigApplicationContext来进行说明:
1. 构造一个BeanFactory对象;
2. 构造BeanDefinitionReader,向BeanFactory注册各个注解模式需要的后置处理器;
3. 解析配置类,得到BeanDefinition,并注册到BeanFactory中;
① 解析@ComponentScan,此时就会完成扫描
② 解析@Import
③ 解析@Bean
④ ...
4.由于Spring启动过程中要创建非懒加载的单例Bean对象,那么就需要用到BeanPostProcessor,所以Spring在启动过程中就需要做两件事:
4.1. 生成默认的BeanPostProcessor对象,并添加到BeanFactory中:
① AutowiredAnnotationBeanPostProcessor:处理@Autowired、@Value 注解;
② CommonAnnotationBeanPostProcessor:处理@Resource、@PostConstruct、 @PreDestroy 注解;
③ ApplicationContextAwareProcessor:处理ApplicationContextAware等回调
4.2. 找到外部用户自定义的BeanPostProcessor对象(类型为BeanPostProcessor的Bean对象),并添加到BeanFactory中;
5. ApplicationContext支持国际化,需要初始化MessageSource对象;
6. ApplicationContext支持事件机制,还需要初始化ApplicationEventMulticaster对象;
7. 把用户定义的ApplicationListener对象添加到ApplicationContext中,等Spring启动完了就要发布事件了;
8. 创建非懒加载的单例Bean对象,并存在BeanFactory的单例池中;
9. 调用LifecycleBean的start()方法;
10. 发布ContextRefreshedEvent事件;
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
AnnotationConfigApplicationContext是Spring的高级容器,有多个构造方法,以下是基于AnnotationConfigApplicationContext(Class<?>... componentClasses)来分析,在这个构造方法中,首先会执行自己的无参构造方法---this(),在this()中会先执行父类GenericApplicationContext的默认构造方法;
- public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
- /**构造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner
- *这里由于它有父类,所以会先调用父类的构造方法,初始化DefaultListableBeanFactory
- *AnnotationConfigApplicationContext容器无参构造器--->父类GenericApplicationContext无参构造器,创建this.beanFactory = new DefaultListableBeanFactory();
- */
- this();
- //注册相关信息
- register(componentClasses);
- //刷新容器---核心
- refresh();
- }
- public GenericApplicationContext() {
- // 初始化一个beanFactory
- this.beanFactory = new DefaultListableBeanFactory();
- }
这个DefaultListableBeanFactory,非常重要,Spring加载的bean都会放到这个Bean工厂中,
当然GenericApplicationContext的父类AbstractApplicationContext,包括AbstractApplicationContext的父类DefaultResourceLoader都有默认构造方法的;
- public AbstractApplicationContext() {
- this.resourcePatternResolver = getResourcePatternResolver();
- }
-
- public DefaultResourceLoader() {
- }
这些提前初始化的属性到后面都会用到,以下是继承关系图:
回到AnnotationConfigApplicationContext(Class<?>... componentClasses)构造方法中的this(),
构造AnnotatedBeanDefinitionReader,主要作用是对BeanFactory进行设置和添加一些基础的PostProcessor(后置处理器),同时可以通过reader进行BeanDefinition的注册;
- public AnnotationConfigApplicationContext() {
- StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
- /** 什么是bean定义 ? BeanDefinition
- * 创建一个读取注解的Bean定义读取器,它的register()方法能够将类解析成为一个BeanDefination,然后将BeanDefination对象存到beanDefinationMap中,而beanDefinationMap是在Bean工厂中
- * 完成了Spring内部BeanDefinition的注册(主要是后置处理器)
- * 额外会创建StandardEnvironment
- */
- this.reader = new AnnotatedBeanDefinitionReader(this);//this 指的就是DefaultListableBeanFactory
- createAnnotatedBeanDefReader.end();
- /** 创建BeanDefinition扫描器,可以用来扫描包或者类继而转换为BeanDefinition
- * Spring默认的扫描器其实不是这个scanner对象,而是在后面自己又重新new了一个ClassPathBeanDefinitionScanner
- * Spring在执行工程后置处理器ConfigurationClassPostProcessor时,去扫描包时会new一个ClassPathBeanDefinitionScanner
- * 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
- */
- this.scanner = new ClassPathBeanDefinitionScanner(this);
- }
对于AnnotatedBeanDefinitionReader()构造函数里面的参数registry其实就是DefaultListableBeanFactory;
- public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
- this(registry, getOrCreateEnvironment(registry));
- }
-
- public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
- Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
- Assert.notNull(environment, "Environment must not be null");
- this.registry = registry;
- // 解析器,用来解析@Conditional注解的
- this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
- /** registerAnnotationConfigProcessors,向BeanFactory注册各个注解模式需要的后置处理器
- * 根据名字顾名思义就是->注册注解配置的处理器,也就是这个方法里面会注册一些用于处理注解的处理器
- */
- AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
- }
- public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
- registerAnnotationConfigProcessors(registry, null);
- }
-
- public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
- BeanDefinitionRegistry registry, @Nullable Object source) {
- // 获取beanFactory也就是DefaultListableBeanFactory
- DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
- if (beanFactory != null) {
- /**
- * 设置比较器,它是一个Comparator,可以用来进行排序,比如new ArrayList<>().sort(Comparator),主要能解析@Order和@Priority
- * 会获取某个对象上的Order注解或者通过实现Ordered接口所定义的值进行排序,在日常开发中可以利用这个类来进行排序
- */
- if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
- beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
- }
- /**
- * 设置依赖注入的候选处理器,用来判断某个Bean能不能用来进行依赖注入
- * 可以看到只要不是ContextAnnotationAutowireCandidateResolver类型 直接升级为最强类型
- */
- if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
- beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
- }
- }
-
- Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
-
- /**注册ConfigurationClassPostProcessor类型的BeanDefinition,ConfigurationClassPostProcessor是一个工厂后置处理器
- * 这个后置处理器非常重要,基本上类上面的注解都在这里面判断并解析,Spring的包扫描也在里面完成
- */
- 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));
- }
-
- /**
- * 注册AutowiredAnnotationBeanPostProcessor类型的BeanDefinition
- * 处理@Autowired注解的,它是一个bean的后置处理器,在bean的属性注入的时候会用到
- */
- 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));
- }
-
- /**
- * 注册CommonAnnotationBeanPostProcessor类型的BeanDefinition
- * 处理一些公共注解的,它是一个bean的后置处理器,可以处理@PostConstruct和@PreDestroy还有@Resource等
- */
- // 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));
- }
-
- // 注册PersistenceAnnotationBeanPostProcessor类型的BeanDefinition
- // 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));
- }
-
- /**
- * 注册EventListenerMethodProcessor类型的BeanDefinition,用来处理@EventListener注解的
- * Spring实现事件监听的方式有很多种,其中一种就是在方法上添加@EventListener注解
- */
- if (
- 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));
- }
-
- // 注册DefaultEventListenerFactory类型的BeanDefinition,用来处理@EventListener注解的
- 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;
- }
- /**
- * Load or refresh the persistent representation of the configuration, which
- * might be from Java-based configuration, an XML file, a properties file, a
- * relational database schema, or some other format.
- * <p>As this is a startup method, it should destroy already created singletons
- * if it fails, to avoid dangling resources. In other words, after invocation
- * of this method, either all or no singletons at all should be instantiated.
- * @throws BeansException if the bean factory could not be initialized
- * @throws IllegalStateException if already initialized and multiple refresh
- * attempts are not supported
- */
- void refresh() throws BeansException, IllegalStateException;
这是ConfigurableApplicationContext接口上refresh()方法的注释,意思是:加载或刷新持久化的配置,可能是XML文件、属性文件或关系数据库中存储的;由于这是一个启动方法,如果失败,它应 该销毁已经创建的单例,以避免占用资源,换句话说,在调用该方法之后,应该实例化所有的单例, 或者根本不实例化单例 。 有个地方需要注意:ApplicationContext关闭之后不代表JVM也关闭了,ApplicationContext是属于JVM的,ApplicationContext也是JVM中的一个对象。
在Spring的设计中,也提供可以刷新的ApplicationContext和不可以刷新的ApplicationContext, 比如:
AbstractRefreshableApplicationContext extends AbstractApplicationContext
就是可以刷新的;
GenericApplicationContext extends AbstractApplicationContext
就是不可以刷新的。 AnnotationConfigApplicationContext继承的是GenericApplicationContext,所以它是不能刷新的; AnnotationConfigWebApplicationContext继承的是 AbstractRefreshableWebApplicationContext,所以它是可以刷新的,上面说的不能刷新是指不能重复刷新,只能调用一次refresh方法,第二次时会报错。
2.1. prepareRefresh():
① 可以允许子容器设置一些内容到Environment中;
② 验证Environment中是否包括了必须要有的属性;
2.2. obtainFreshBeanFactory():进行BeanFactory的refresh,在这里会去调用子类的 refreshBeanFactory方法,具体子类是怎么刷新的得看子类的实现,最后再调用子类的 getBeanFactory方法,重新得到一个BeanFactory;
2.3. prepareBeanFactory(beanFactory):
① 设置beanFactory的类加载器,由于创建bean是由Bean工厂来创建,所有如果设置了类加载器,会把类加载器设置到Bean工厂中;
② 设置SpringEL表达式解析器:StandardBeanExpressionResolver,用来解析Spring中的表达式,例如: @Value("#{}");
③ 添加PropertyEditorRegistrar:ResourceEditorRegistrar,属性编辑器注册器,用来注册一些默认的PropertyEditor ;
④ 添加一个Bean的后置处理器:ApplicationContextAwareProcessor,是一个BeanPostProcessor,用来执行EnvironmentAware、ApplicationContextAware、ApplicationEventPublisherAware 等回调方法
⑤ 添加ignoredDependencyInterface:可以向这个属性中添加一些接口,如果某个类实现了其中的一个或多个接口,并且这个类中的某些set方法在接口中也存在,那么这个set方法在自动注入的 时候是不会执行的,比如EnvironmentAware这个接口,如果某个类实现了这个接口,那就必须实现它的setEnvironment方法,而这是一个set方法,和Spring中的autowire是冲突 的,那么Spring在自动注入时是不会调用setEnvironment方法的,而是等到回调Aware接口时再来调用(注意,这个功能仅限于xml的autowire,@Autowired注解是忽略这个属性的,这些接口有 EnvironmentAware
EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware
MessageSourceAware、ApplicationContextAware
其实在容器启动构造BeanFactory(DefaultListableBeanFactory)的时候,ignoredDependencyInterface就已经提前添加了另外三个,分別是BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
2.4. 添加resolvableDependencies:在byType进行依赖注入时,会先从这个属性中根据类型找bean
① BeanFactory.class:当前BeanFactory对象
② ResourceLoader.class:当前ApplicationContext对象
③ ApplicationEventPublisher.class:当前ApplicationContext对象
④ ApplicationContext.class:当前ApplicationContext对象
2.5. 添加一个Bean的后置处理器:ApplicationListenerDetector,是一个 BeanPostProcessor,用来判断某个Bean是不是ApplicationListener,如果是则把这个 Bean添加到ApplicationContext中去,注意一个ApplicationListener只能是单例的;
2.6. 添加一个Bean的后置处理器:LoadTimeWeaverAwareProcessor,是一个 BeanPostProcessor,用来判断某个Bean是不是实现了LoadTimeWeaverAware接口,如果实现了则把ApplicationContext中的loadTimeWeaver回调setLoadTimeWeaver方法设置给该Bean;
2.7. 添加一些单例bean到单例池:
① "environment":Environment对象
② "systemProperties":System.getSystemProperties()返回的Map对象
③ "systemEnvironment":System.getSystemEnvironment)返回的Map对象
④ "applicationStartup":DefaultApplicationStartup对象
2.8. postProcessBeanFactory(beanFactory) : 提供给AbstractApplicationContext的子类进行扩 展,具体的子类,可以继续向BeanFactory中再添加一些东西;
2.9. invokeBeanFactoryPostProcessors(beanFactory):执行BeanFactoryPostProcessor,到这一步,在BeanFactory中已经存在一个BeanFactoryPostProcessor: ConfigurationClassPostProcessor,它也是一个BeanDefinitionRegistryPostProcessor
2.9.1. 执行通过ApplicationContext添加进来的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法 ;
2.9.2. 执行BeanFactory中实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法 ;
2.9.3. 执行BeanFactory中实现了Ordered接口的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法 ;
2.9.4. 执行BeanFactory中其他的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法 ;
2.9.5. 执行上面所有的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法 ;
2.9.6. 执行通过ApplicationContext添加进来的BeanFactoryPostProcessor的 postProcessBeanFactory()方法 ;
2.9.7. 执行BeanFactory中实现了PriorityOrdered接口的BeanFactoryPostProcessor的 postProcessBeanFactory()方法 ;
2.9.8. 执行BeanFactory中实现了Ordered接口的BeanFactoryPostProcessor的 postProcessBeanFactory()方法 ;
2.9.9. 执行BeanFactory中其他的BeanFactoryPostProcessor的postProcessBeanFactory()方法;
2.10. registerBeanPostProcessors(beanFactory):因为上面的步骤完成了扫描,这个过程中我们可能自己定义了一些BeanPostProcessor,在这一步就会把BeanFactory中所有的 BeanPostProcessor找出来实例化得到相应的对象,并添加到BeanFactory中去(属性 beanPostProcessors),最后再重新添加一个ApplicationListenerDetector对象(之前其实就添加了过,这里是为了把ApplicationListenerDetector移动到最后);
2.11. initMessageSource():ApplicationContext是支持国际化的,但不是自己完全去实现,而是利用MessageSource去实现的,而MessageSource通常是需要我们自己去定义的,如果BeanFactory中存在一个叫做"messageSource"的 BeanDefinition,那么就会把这个Bean对象创建出来并赋值给ApplicationContext的 messageSource属性,让ApplicationContext拥有国际化的功能;
2.12.initApplicationEventMulticaster():初始化事件监听多路广播器,如果BeanFactory中存在一个叫做"applicationEventMulticaster"的BeanDefinition,就会把这个Bean对象创建出来并赋值给ApplicationContext的applicationEventMulticaster属性,如果没有,则默认采用SimpleApplicationEventMulticaster,让ApplicationContext拥有事件发布的功能;
2.13. onRefresh():提供给AbstractApplicationContext的子类进行扩展;
2.14. registerListeners():从BeanFactory中获取ApplicationListener类型的beanName,然后添加 到ApplicationContext中的事件广播器applicationEventMulticaster中去,到这一步因为 FactoryBean还没有调用getObject()方法生成Bean对象,所以这里要在根据类型找一下 ApplicationListener,记录一下对应的beanName;
2.15. finishBeanFactoryInitialization(beanFactory):完成BeanFactory的初始化,主要就是实例化 非懒加载的单例Bean;
2.16. finishRefresh():BeanFactory的初始化完后,就到了Spring启动的最后一步了,
① 初始化ApplicationContext的lifecycleProcessor,默认情况下设置的是 DefaultLifecycleProcessor ;
② 调用lifecycleProcessor的onRefresh()方法,如果是DefaultLifecycleProcessor,那么会获取所 有类型为Lifecycle的Bean对象,然后调用它的start()方法,这就是ApplicationContext的生命 周期扩展机制;
- @Override
- public void onRefresh() {
- startBeans(true);
- }
-
- private void startBeans(boolean autoStartupOnly) {
- Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
- Map<Integer, LifecycleGroup> phases = new TreeMap<>();
-
- // 按每个Bean的phase进行分组
- lifecycleBeans.forEach((beanName, bean) -> {
- if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
- int phase = getPhase(bean);
- phases.computeIfAbsent(
- phase,
- p -> new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly)
- ).add(beanName, bean);
- }
- });
-
- // 按分组执行start()
- if (!phases.isEmpty()) {
- phases.values().forEach(LifecycleGroup::start);
- }
- }
-
-
- protected Map<String, Lifecycle> getLifecycleBeans() {
- ConfigurableListableBeanFactory beanFactory = getBeanFactory();
- Map<String, Lifecycle> beans = new LinkedHashMap<>();
- //获取beanFactory中所有Lifecycle类型的beanName
- String[] beanNames = beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
- for (String beanName : beanNames) {
- String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
- boolean isFactoryBean = beanFactory.isFactoryBean(beanNameToRegister);
- String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
-
- // 如果所定义的Lifecycle的Bean是单例并且(不是FactoryBean或是Lifecycle类型或是SmartLifecycle类型的)
- if ((beanFactory.containsSingleton(beanNameToRegister) &&
- (!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck, beanFactory))) ||
- matchesBeanType(SmartLifecycle.class, beanNameToCheck, beanFactory)) {
- Object bean = beanFactory.getBean(beanNameToCheck);
- if (bean != this && bean instanceof Lifecycle) {
- beans.put(beanNameToRegister, (Lifecycle) bean);
- }
- }
- }
- return beans;
- }
-
③ 发布ContextRefreshedEvent事件;
- public void refresh() throws BeansException, IllegalStateException {
- synchronized (this.startupShutdownMonitor) {
- StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
-
- // 启动前的准备工作
- prepareRefresh();
- /*
- * 由于web项目中并不会先引入DefaultListableBeanFactory,在这里通知子类刷新BeanFactory,例如:AbstractRefreshableApplicationContext
- * 而我们是使用new AnnotationConfigApplicationContext()的方式,就是直接返回之前引入的DefaultListableBeanFactory
- * Tell the subclass to refresh the internal bean factory.
- * 这里会判断能否刷新,并且返回一个BeanFactory
- * 对于能进行重复刷新的子容器,刷新不代表完全清空,主要是先执行Bean的销毁,然后重新生成一个BeanFactory,再在接下来的步骤中重新去扫描等等
- */
- ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
-
- // Prepare the bean factory for use in this context.
- // 准备BeanFactory
- // 1. 设置BeanFactory的类加载器、SpringEL表达式解析器、类型转化注册器
- // 2. 添加三个BeanPostProcessor,注意是具体的BeanPostProcessor实例对象
- // 3. 记录ignoreDependencyInterface
- // 4. 记录ResolvableDependency
- // 5. 添加三个单例Bean
- prepareBeanFactory(beanFactory);
-
- try {
- // Allows post-processing of the bean factory in context subclasses.
- // 留的扩展方法,子类来设置一下BeanFactory
- postProcessBeanFactory(beanFactory);
-
- StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
-
- // Invoke factory processors registered as beans in the context.
- // BeanFactory准备好了之后,执行BeanFactoryPostProcessor,开始对BeanFactory进行处理
- // 默认情况下:
- // 此时beanFactory的beanDefinitionMap中有6个BeanDefinition,5个基础BeanDefinition+AppConfig的BeanDefinition
- // 而这6个中只有一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor
- // 这里会用ConfigurationClassPostProcessor这个类进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中
- // 再具体一点就是执行ConfigurationClassPostProcessor中的postProcessBeanDefinitionRegistry()方法进行扫描
- // 注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行
- invokeBeanFactoryPostProcessors(beanFactory); // scanner.scan()
-
- // Register bean processors that intercept bean creation.
- // 将扫描到的BeanPostProcessors实例化并排序,并添加到BeanFactory的beanPostProcessors属性中去
- registerBeanPostProcessors(beanFactory);
-
- beanPostProcess.end();
-
- // Initialize message source for this context.
- // 设置ApplicationContext的MessageSource,可以是用户设置的,或者是DelegatingMessageSource
- // ApplicationContext是支持国际化的,但不是自己完全去实现,而是利用MessageSource去实现的,而MessageSource通常是需要我们自己去定义的
- initMessageSource();
-
- // Initialize event multicaster for this context.
- // 初始化事件监听多路广播器,设置ApplicationContext的applicationEventMulticaster,可以是用户设置的,或者是默认的SimpleApplicationEventMulticaster
- initApplicationEventMulticaster();
-
- // Initialize other special beans in specific context subclasses.
- // 给子类的模板方法
- onRefresh();
-
- // Check for listener beans and register them.
- // 把定义的ApplicationListener的Bean对象,设置到ApplicationContext中去,并执行在此之前所发布的事件
- registerListeners();
-
- /**
- * Instantiate all remaining (non-lazy-init) singletons.
- * 创建非懒加载的单例bean,创建bean的时候需要用到BeanPostProcessor,而BeanPostProcessor都是存在于beanPostProcessors中
- * 而registerBeanPostProcessors(beanFactory)就是向BeanFactory的beanPostProcessors中添加BeanPostProcessor的对象
- */
- finishBeanFactoryInitialization(beanFactory);
-
- // Last step: publish corresponding event.
- finishRefresh();
- }
-
- catch (BeansException ex) {
- if (logger.isWarnEnabled()) {
- logger.warn("Exception encountered during context initialization - " +
- "cancelling refresh attempt: " + ex);
- }
-
- // Destroy already created singletons to avoid dangling resources.
- destroyBeans();
-
- // Reset 'active' flag.
- cancelRefresh(ex);
-
- // Propagate exception to caller.
- throw ex;
- }
-
- finally {
- // Reset common introspection caches in Spring's core, since we
- // might not ever need metadata for singleton beans anymore...
- resetCommonCaches();
- contextRefresh.end();
- }
- }
- }
BeanPostProcessor表示Bean的后置处理器,是用来对Bean进行加工的,类似的, BeanFactoryPostProcessor理解为BeanFactory的后置处理器,用来用对BeanFactory进行加工的, Spring支持用户自定义BeanFactoryPostProcessor的实现类,来对BeanFactory进行加工,比例如:
- @Component
- public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
- @Override
- public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
- throws BeansException {
- BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
- beanDefinition.setAutowireCandidate(false);
- }
- }
以上代码,就利用了BeanFactoryPostProcessor来拿到BeanFactory,然后获取BeanFactory内的某个BeanDefinition对象并进行修改,这一步是发生在Spring启动时,创建单例Bean之前的,所以此时对BeanDefinition就行修改是会生效的。 注意:在ApplicationContext内部有一个核心的DefaultListableBeanFactory,它实现了 ConfigurableListableBeanFactory和BeanDefinitionRegistry接口,所以ApplicationContext和 DefaultListableBeanFactory是可以注册BeanDefinition的,而ConfigurableListableBeanFactory是不能注册BeanDefinition的,只能获取BeanDefinition,对BeanDefinition做修改。
Spring还提供了一个BeanFactoryPostProcessor的子接口: BeanDefinitionRegistryPostProcessor
- public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
- void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws
- BeansException;
- }
我们可以看到BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口,并新 增了一个方法,注意方法的参数为BeanDefinitionRegistry,如果我们自定义一个类来实现 BeanDefinitionRegistryPostProcessor,那么在postProcessBeanDefinitionRegistry()方法中就可 以注册BeanDefinition了。比如:
- @Component
- public class MyBeanDefinitionRegistryPostProcessor implements
- BeanDefinitionRegistryPostProcessor {
- @Override
- public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws
- BeansException {
- AbstractBeanDefinition beanDefinition =
- BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
- beanDefinition.setBeanClass(User.class);
- registry.registerBeanDefinition("user", beanDefinition);
- }
- @Override
- public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
- throws BeansException {
- BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
- beanDefinition.setAutowireCandidate(false);
- }
- }
Lifecycle表示的是ApplicationContext的生命周期,可以定义一个SmartLifecycle来监听 ApplicationContext的启动和关闭:
- /**
- * Bean有生命周期,对于Spring容器而言也有一个生命周期,如果我们想去监听Spring容器什么时候创建好?有以下做法:
- * 1.监听Spring容器发布的这个事件 :publishEvent(new ContextRefreshedEvent(this))
- * 2.监听当前Spring容器是否启动完了,如下做法:
- */
- @Component
- //@Scope("prototype")
- public class MyLifecycle implements SmartLifecycle {
-
- private boolean isRunning;
-
- /**
- * Spring容器启动完了会调用start()
- */
- @Override
- public void start() {
- System.out.println("start...");
- isRunning=true;
- }
-
- /**
- * 调start()之前会执行isRunning(),判断当前是不是在运行,如果当前不是处于运行的过程中,才会调start()
- * 如果是在运行(true)才能调stop方法
- * 要触发stop(),要调用context.close(),或者注册关闭钩子(context.registerShutdownHook())
- */
- @Override
- public void stop() {
- System.out.println("stop...");
- }
-
-
- @Override
- public boolean isRunning() {
- return isRunning;
- }
-
- //分组
- @Override
- public int getPhase() {
- return 1;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。