Spring ApplicationContext 初始化流程
主题
学习记录一下applicationContext在初始化过程中做的一些操作..
从全局整体来看.不会涉及太多细节.
applicationcontext的refresh方法是一个startup method.算是spring启动的一个方法.它处理各种配置,不管是XML还是properties还是啥.创建了各种bean.算是一个最核心的方法.
refresh方法里面包含了一大堆模板方法.每个模板都做了一些事情,相当于一个小步骤..
从代码整体来看大概包含了这么一些步骤.其中2,3,4,5,6这几部是我个人觉得最核心的步骤.我想特别记录下我的想法
1. prepareRefresh
1 /** 2 * Prepare this context for refreshing, setting its startup date and 3 * active flag as well as performing any initialization of property sources. 4 */ 5 protected void prepareRefresh() { 6 this.startupDate = System.currentTimeMillis(); 7 this.active.set(true); 8 9 if (logger.isInfoEnabled()) { 10 logger.info("Refreshing " + this); 11 } 12 13 // Initialize any placeholder property sources in the context environment 14 initPropertySources(); 15 16 // Validate that all properties marked as required are resolvable 17 // see ConfigurablePropertyResolver#setRequiredProperties 18 getEnvironment().validateRequiredProperties(); 19 20 // Allow for the collection of early ApplicationEvents, 21 // to be published once the multicaster is available... 22 this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>(); 23 }
这个方法基本啥都没做.留给子类ac去做自定义的操作.
比如web环境下的ac可能会将servletConfig或者servletContext里配置的一些参数值也当做属性值加入到spring中.因为你的spring的部分配置可能会依赖这些web.xml里的配置
另外就是对必要属性的验证.如果有必要的话可以自己去写一个ac继承spring,然后重写initPropertySources方法去设置你觉得必要的属性.然后当getEnvironment().validateRequiredProperties();
的时候如果没有找到你之前setRequiredProperties的那些属性.就会提示报错.
2. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
获取BF这个步骤主要作用就是构造一个bf.然后去加载对应的beanDifination信息.
/** * Tell the subclass to refresh the internal bean factory. * @return the fresh BeanFactory instance * @see #refreshBeanFactory() * @see #getBeanFactory() */ protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
getBeanFactory方法就是获取当前这个ac里设置的bf,没啥好说的.主要看看refreshBeanFactory这个方法里面做了啥.
1 /** 2 * This implementation performs an actual refresh of this context's underlying 3 * bean factory, shutting down the previous bean factory (if any) and 4 * initializing a fresh bean factory for the next phase of the context's lifecycle. 5 */ 6 @Override 7 protected final void refreshBeanFactory() throws BeansException { 8 if (hasBeanFactory()) { 9 destroyBeans(); 10 closeBeanFactory(); 11 } 12 try { 13 DefaultListableBeanFactory beanFactory = createBeanFactory(); 14 beanFactory.setSerializationId(getId()); 15 customizeBeanFactory(beanFactory); 16 // 这里不同的ac可能会有不同的loadDefination的方法,比如AnnotationConfigWebApplicationContext就会扫描注解注册BD 17 loadBeanDefinitions(beanFactory); 18 synchronized (this.beanFactoryMonitor) { 19 this.beanFactory = beanFactory; 20 } 21 } 22 catch (IOException ex) { 23 throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); 24 } 25 }
2.1 shuwdown之前的bf
如果当前这个ac已经有bf了(比如之前ac的refresh就调用过)了.那这里需要把这个bf shutdown.
比如把bf里的各种缓存的map情况.然后所有的单例bean如果impl了DisposableBean,还需要调用它的destroy方法去做相应的操作.
2.2 创建bf
DefaultListableBeanFactory beanFactory = createBeanFactory();
createBeanFactory默认返回的是DefaultListableBeanFactory类的实例.目前为止spring中还没看到其他继承这个BF的实现类.基本都是用这个类作为默认的BF.可能因为功能已经足够强大了吧..另外因为ApplicationContext也继承了BF,所以很多操作会在ac里操作掉..根据ac的不同实现做不同的操作.可能这也是bf没有这么多实现的原因吧...
2.3 配置bf
customizeBeanFactory(beanFactory);
这是一个模板方法.允许子类ac去实现他.对bf进行一些个性化配置.比如是否需要解决单例的循环依赖呀? 是否允许beanDifination多次定义被覆盖呀?
bf里配置还蛮多的..不过我看源码里目前子类ac也没啥进行定制的...
2.4 加载bd
loadBeanDefinitions(beanFactory);
BeanFactory的作用就是读取bean的配置信息变成内存中的BeanDifination.然后在创建bean的时候根据这个bd去构造具体的bean.
不同的bean的配置方式可能各种各样.比如有XML的.Properties的.传统注解@Service@Autowired的.又或是@Configuration这种java config方式的..但是他们在内存中都是通过BeanDifination来表示的(可能是不同子类).
不同的ApplicationContext代表了不同的环境.比如适用于web环境的WebApplicationContext,也有传统单独使用spring的时候的XML里的ClassPathXmlApplicationContext等等
这些不同的ac加载bd的方式也会各有不同.所以在这个loadBeanDefinitions模板方法里就是要根据不同的ac去实现不同的加载bd的方式.
比如XML的ac就应该委托XmlBeanDefinitionReader去读取bean形式的配置.转化成BeanDifination注册到BF中.
而支持Annotation的ac就应该委托AnnotatedBeanDefinitionReader这种reader去扫描Java源码.注册相应的BD.
当然.注册的BD不一定就是我们代码里用到的那些bean对应的bd.也可能是一些BeanPostProcessor或者子接口的实现类.
因为比如InstantiationAwareBeanPostProcessor类似这种特殊的接口都是参与Spring的生命周期可以在一些必要的时候替换掉原始的bean.或者对bean的属性进行一些加工.
比如@Autowired这种操作就是用到特殊的bpp..AutowiredAnnotationBeanPostProcessor..同理@Configuration也是一样..
所以说不同的bean的配置方式在spring创建对应的bean过程中走的流程可能是不一样的,这也是Spring比较灵活的地方.
有些bean会被适用于它的bpp去处理去生成或者去注入属性.而有一些可能就是比较原生,直接通过bd被BeanWrapper给new出来.
3.prepareBeanFactory
1 /** 2 * Configure the factory's standard context characteristics, 3 * such as the context's ClassLoader and post-processors. 4 * @param beanFactory the BeanFactory to configure 5 */ 6 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { 7 // Tell the internal bean factory to use the context's class loader etc. 8 beanFactory.setBeanClassLoader(getClassLoader()); 9 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); 10 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); 11 12 // Configure the bean factory with context callbacks. 13 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); 14 beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); 15 beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); 16 beanFactory.ignoreDependencyInterface(MessageSourceAware.class); 17 beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); 18 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); 19 20 // BeanFactory interface not registered as resolvable type in a plain factory. 21 // MessageSource registered (and found for autowiring) as a bean. 22 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); 23 beanFactory.registerResolvableDependency(ResourceLoader.class, this); 24 beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); 25 beanFactory.registerResolvableDependency(ApplicationContext.class, this); 26 27 // Detect a LoadTimeWeaver and prepare for weaving, if found. 28 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { 29 beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); 30 // Set a temporary ClassLoader for type matching. 31 beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); 32 } 33 34 // Register default environment beans. 35 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { 36 beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); 37 } 38 if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { 39 beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); 40 } 41 if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { 42 beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); 43 } 44 }
大致做的事情就是
3.1 SPEL
设置spelResolver用于spel的解析. spel单独就有一个自己的模块. 具体就不说了.
3.2 PropertyEditorRegistrar
设置PropertyEditorRegistrar. spring的配置文件很多都是XML或者property这种文本.读取出来的都是字符串.但是java对象有各种类型的属性.所以生成bean的时候需要做一些类型转化
比如 String -> Int类似这种, 就需要自己去写一个PropertyEditorSupport的实现类,去impl setAsText(String) 的方法.把XML里得到的字符串转化成Java对象里的Int值.Spring自带了很多这种Editor
ResourceEditorRegistrar.java
另外spring的类型转化也有很多种方法.这种PropertyEditorSupport(java.beans包下的)可能是早期的方案.后续的SPring版本中有一些地方转化用到了conversionService. 里面又设计到其他的一些类型转化接口.
可以参考我的这篇文章
https://www.cnblogs.com/abcwt112/p/7447435.html
3.3 注册BeanPostProcessor
beanPostProcessor可以在bean初始化方法(比如XML里的init-method或者InitializingBean的afterPropertySet方法)前和后对bean进行加工或者返回一个wrapper替换掉原本的bean.
注意的是bean的属性填充是在bpp2个操作之前的.就是populate(BeanFactory创建bean的一个利用BeanWrapper去设置bean的属性的时候回调用的方法)方法已经被调用过的.
Spring在这里new了一个ApplicationContextAwareProcessor
1 @Override 2 public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException { 3 AccessControlContext acc = null; 4 5 if (System.getSecurityManager() != null && 6 (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || 7 bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || 8 bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) { 9 acc = this.applicationContext.getBeanFactory().getAccessControlContext(); 10 } 11 12 if (acc != null) { 13 AccessController.doPrivileged(new PrivilegedAction<Object>() { 14 @Override 15 public Object run() { 16 invokeAwareInterfaces(bean); 17 return null; 18 } 19 }, acc); 20 } 21 else { 22 invokeAwareInterfaces(bean); 23 } 24 25 return bean; 26 } 27 28 private void invokeAwareInterfaces(Object bean) { 29 if (bean instanceof Aware) { 30 if (bean instanceof EnvironmentAware) { 31 ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment()); 32 } 33 if (bean instanceof EmbeddedValueResolverAware) { 34 ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver( 35 new EmbeddedValueResolver(this.applicationContext.getBeanFactory())); 36 } 37 if (bean instanceof ResourceLoaderAware) { 38 ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext); 39 } 40 if (bean instanceof ApplicationEventPublisherAware) { 41 ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext); 42 } 43 if (bean instanceof MessageSourceAware) { 44 ((MessageSourceAware) bean).setMessageSource(this.applicationContext); 45 } 46 if (bean instanceof ApplicationContextAware) { 47 ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext); 48 } 49 } 50 }
对实现了一部分Aware的bean做方法调用.
比如你的bean impl了ApplicationContextAware这个接口.那就会调用你的setApplicationContext方法去让你有机会将ac设置为你的bean里的一个属性.
为什么Aware的一些接口要用这些内置的bpp去处理,而不是当做一般的bean注入?
我个人觉得是第一,要控制是什么时候注入这些bean.比如如果只是在一般的populate属性的时候注入这个ac.那这个时候不是所有的bean都被new过..可能会有一些意想不到的问题.
第二我觉得是因为ac和BeanFactory可能会有多个,比如早期没有springboot的时候.spring会有一个ac.然后springmvc自己也会有一个ac.有parent和child的关系.那你在一个bean里注入ac.就会有2个符合条件的ac选择.这也是有问题的.
3.4 忽略部分类型bean的注入
1 beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); 2 beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); 3 beanFactory.ignoreDependencyInterface(MessageSourceAware.class); 4 beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); 5 beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
为什么这些类型的bean不需要注入? 因为3.3里已经在bpp里处理了
3.5 指定部分类型的bean注入
1 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); 2 beanFactory.registerResolvableDependency(ResourceLoader.class, this); 3 beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); 4 beanFactory.registerResolvableDependency(ApplicationContext.class, this);
指定了一些bean的类型使用特定的bean注入..比如BeanFactory就使用当前这个ac对应的bf去注入即可.
3.6 额外注册一些Bean
1 // Detect a LoadTimeWeaver and prepare for weaving, if found. 2 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { 3 beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); 4 // Set a temporary ClassLoader for type matching. 5 beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); 6 } 7 8 // Register default environment beans. 9 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { 10 beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); 11 } 12 if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { 13 beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); 14 } 15 if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { 16 beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); 17 }
如果有一些bean你没配置.那就会使用spring默认的配置.比如environment.你如果配置了.那就用你的bean
4. postProcessBeanFactory(beanFactory);
这个方法是一个模板方法,允许子类对bf做一些处理.
比如一些web相关的ac会在这里add一些bpp比如ServletContextAwareProcessor来对servlet做一些处理
或者在这里也可以get BF以后去调用方法增加一些BeanFactoryPostProcessor.
5.invokeBeanFactoryPostProcessors(beanFactory);
做到这个方法的时候BF已经加载完所有的BeanDifination了(详见第2节).但是任何bean都还没有被初始化(new).
看方法名字就知道这个方法是去激活调用beanFactoryPostProcessors的相关方法的.
beanFactoryPostProcessors这个接口还有一个子接口叫做BeanDefinitionRegistryPostProcessor.
这个子接口的postProcessBeanDefinitionRegistry方法是处理BeanDefinitionRegistry用的.可能是个新增的接口.因为我看到网上很多博客上都只写了BFPP而没有写这个接口..(因为大部分文章介绍的是早期的spring)
这个接口的会先于BFPP的postProcessBeanFactory掉用,他可以处理BeanDefinitionRegistry,有一些BF实现了这个接口,也有一些BF没有.绝大部分大部分ac使用的DefaultListableBeanFactory
是实现了这个接口的.所以可以处理BeanDefinitionRegistryPostProcessor.
BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry作用是给你一个机会去手动注册beanDifination..可以用这个接口去注册一些BeanFactoryPostProcessor..当然普通的BD也可以去注册或者修改.但是如果是这种目的的话最好可以使用BeanFactoryPostProcessor的postProcessBeanFactory.这样通用性更好.也更合理.
BeanFactoryPostProcessor的postProcessBeanFactory用于修改BeanFactory或者去修改BF里的BeanDifination..
一个典型的案例就是在早期版本的spring(还没用springboot的时候)我们会配置placeholderconfigurer.这个类就是实现了BeanFactoryPostProcessor接口.他会扫描所有bean里的属性.去把${}这种占位符替换成property文件里指定的值.常用于db的配置独立放在.properties文件中,datasource的配置放在bean.XML文件中.
所以invokeBeanFactoryPostProcessors(beanFactory);这个方法所做的事情就是.
1.获取所有手动注册的BeanDefinitionRegistryPostProcessor.去调用postProcessBeanDefinitionRegistry.
所谓的手动注册就是在之前几节的模板方法中直接调用ApplicationContext的addBeanFactoryPostProcessor方法注册的BeanDefinitionRegistryPostProcessor
2.然后获取扫描bf中所有注册的BeanDefinitionRegistryPostProcessor.
按PriorityOrdered > Ordered > rest 去排序,依次调用postProcessBeanDefinitionRegistry方法
也就是说你的非手动注册的BeanDefinitionRegistryPostProcessor如果实现了PriorityOrdered接口.那肯定会比实现了Ordered接口的BeanDefinitionRegistryPostProcessor早调用.
同样接口的.就按接口内定义的顺序排序.比如Ordered接口.就是数字越小排在越前面
3.处理一般的BeanFactoryPostProcessor的postProcessBeanFactory方法.
顺序和BeanDefinitionRegistryPostProcessor一样,也是 手动注册的> PriorityOrdered > Ordered > rest
1 public static void invokeBeanFactoryPostProcessors( 2 ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { 3 4 // Invoke BeanDefinitionRegistryPostProcessors first, if any. 5 Set<String> processedBeans = new HashSet<String>(); 6 7 if (beanFactory instanceof BeanDefinitionRegistry) { 8 BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; 9 List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>(); 10 List<BeanDefinitionRegistryPostProcessor> registryPostProcessors = 11 new LinkedList<BeanDefinitionRegistryPostProcessor>(); 12 13 for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { 14 // 特殊的BeanDefinitionRegistryPostProcessor的,比如处理@configuration.注册bd 15 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { 16 BeanDefinitionRegistryPostProcessor registryPostProcessor = 17 (BeanDefinitionRegistryPostProcessor) postProcessor; 18 registryPostProcessor.postProcessBeanDefinitionRegistry(registry); 19 registryPostProcessors.add(registryPostProcessor); 20 } 21 else { 22 regularPostProcessors.add(postProcessor); 23 } 24 } 25 26 // Do not initialize FactoryBeans here: We need to leave all regular beans 27 // uninitialized to let the bean factory post-processors apply to them! 28 // Separate between BeanDefinitionRegistryPostProcessors that implement 29 // PriorityOrdered, Ordered, and the rest. 30 String[] postProcessorNames = 31 beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 32 33 // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. 34 List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>(); 35 for (String ppName : postProcessorNames) { 36 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { 37 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); 38 processedBeans.add(ppName); 39 } 40 } 41 sortPostProcessors(beanFactory, priorityOrderedPostProcessors); 42 registryPostProcessors.addAll(priorityOrderedPostProcessors); 43 invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry); 44 45 // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. 46 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 47 List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>(); 48 for (String ppName : postProcessorNames) { 49 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { 50 orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); 51 processedBeans.add(ppName); 52 } 53 } 54 sortPostProcessors(beanFactory, orderedPostProcessors); 55 registryPostProcessors.addAll(orderedPostProcessors); 56 invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry); 57 58 // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. 59 boolean reiterate = true; 60 while (reiterate) { 61 reiterate = false; 62 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 63 for (String ppName : postProcessorNames) { 64 if (!processedBeans.contains(ppName)) { 65 BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class); 66 registryPostProcessors.add(pp); 67 processedBeans.add(ppName); 68 pp.postProcessBeanDefinitionRegistry(registry); 69 reiterate = true; 70 } 71 } 72 } 73 74 // Now, invoke the postProcessBeanFactory callback of all processors handled so far. 75 invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory); 76 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); 77 } 78 79 else { 80 // Invoke factory processors registered with the context instance. 81 invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); 82 } 83 84 // Do not initialize FactoryBeans here: We need to leave all regular beans 85 // uninitialized to let the bean factory post-processors apply to them! 86 String[] postProcessorNames = 87 beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); 88 89 // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, 90 // Ordered, and the rest. 91 List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); 92 List<String> orderedPostProcessorNames = new ArrayList<String>(); 93 List<String> nonOrderedPostProcessorNames = new ArrayList<String>(); 94 for (String ppName : postProcessorNames) { 95 if (processedBeans.contains(ppName)) { 96 // skip - already processed in first phase above 97 } 98 else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { 99 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); 100 } 101 else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { 102 orderedPostProcessorNames.add(ppName); 103 } 104 else { 105 nonOrderedPostProcessorNames.add(ppName); 106 } 107 } 108 109 // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. 110 sortPostProcessors(beanFactory, priorityOrderedPostProcessors); 111 invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); 112 113 // Next, invoke the BeanFactoryPostProcessors that implement Ordered. 114 List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); 115 for (String postProcessorName : orderedPostProcessorNames) { 116 orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); 117 } 118 sortPostProcessors(beanFactory, orderedPostProcessors); 119 invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); 120 121 // Finally, invoke all other BeanFactoryPostProcessors. 122 List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); 123 for (String postProcessorName : nonOrderedPostProcessorNames) { 124 nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); 125 } 126 invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); 127 }
6.registerBeanPostProcessors(beanFactory);
注册BPP.
之前是BFPP用于处理BeanFactory,处理其中的BeanDifination.那这里就是注册BPP用于在处理bean了.
对于BPP并没有手动注册的方法..比如ac的addBeanPostProcessor这种方法..BFPP相关方法的调用是先于bean 初始化(new)的,很好理解,因为是对BeanFactory的处理,而不是当bean的处理.. (但是BFPP也是会在bean new之前全部被扫描从bf里找出来特殊处理...所以从这点上说好像不用手动配置也可以..)
而bpp是在bean 初始化或者填充属性过程中处理的.是在bean被new的过程中处理的...没必要手动注册...因为当前这一步仅仅是添加bpp..还不会调用bpp的相关方法(因为这个时候还没有new bean)...这一点BFPP不同(BFPP直接调用相关方法).直接和一般的bean一样配置就行了.
BPP的处理顺序和BFPP一样(再次强调一下,这里只是把这些BPP的特殊的bean new出来了.并不会new 一般的bean.所以这里不会调用BPP的相关方法).最后就是BPP也有特殊的子接口,叫做MergedBeanDefinitionPostProcessor,是最后处理的.所以这些MergedBeanDefinitionPostProcessor会在BPP的最内层.(如果只是当做一般的BPP去使用相关方法的话就不要使用这个子接口.因为会影响处理的顺序..)
7.initMessageSource
初始化MessageSource,主要用于国际化.没怎么用过.没深入研究..大致是读取不同语言的properties根据Locale去做相应的处理.
8.initApplicationEventMulticaster
同7个人没咋用过.
ApplicationContext可以publish一些Event.你也可以注册一些Listener去监听自己感兴趣的实践.
9.onRefresh();
也是一个模板方法.给子类ac一个机会去初始化自己想要初始化的特殊的bean
比如一些web的ac会初始化ThemeSource...用于web页面的主题展示和切换...比如jsp里的标签:<spring:theme code="style"/>
现在前后端分离了这个感觉很少用了...
10.registerListeners();
配合8.可以注册一些listener去监听你感兴趣的ApplicationEvent
11.finishBeanFactoryInitialization(beanFactory);
除了注册一些特殊的bean.比如ConversionService以外.
最重要的就是对于之前BF加载的每一个BD.如果这个bean是单例并且不是lazy的.不是abstract的(XML里可以配置一个bean是abstract.用于继承简化配置),就去初始化对应的bean.也就是通过BeanFactory.doGetBean方法去创建这个bean的实例..
里面涉及比较复杂的步骤...涉及各种BPP的调用,还有各种情况的处理...比如循环依赖, 代理方法什么的.....后面会再分享..
12.finishRefresh()
完成refresh.个人没怎么用过.
会注册LifecycleProcessor.如果你的bean实现了Lifecycle接口.在ac做stop.refresh或者start等方法的时候你的bean也会被调用这些方法给你一些回调处理的机会.