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

你接入的网站不属于同一个主体推广文章的注意事项

你接入的网站不属于同一个主体,推广文章的注意事项,网站二级目录做优化,天津市建设工程交易中心网站前言 Spring框架中最重要的肯定是IOC容器#xff0c;那么其如何进行初始化#xff0c;就是通过refresh()这个方法#xff0c;无论是单独使用Spring框架#xff0c;还是SpringBoot#xff0c;最终都会通过执行到这个方法#xff0c;那么下面会介绍一下这个方法 一、IOC容…前言 Spring框架中最重要的肯定是IOC容器那么其如何进行初始化就是通过refresh()这个方法无论是单独使用Spring框架还是SpringBoot最终都会通过执行到这个方法那么下面会介绍一下这个方法 一、IOC容器初始化过程 对于单独测试Spirng框架的场景有两个常见的高级容器 AnnotationConfigApplicationContext 和 ClassPathXmlApplicationContext在这两个类的构造方法都会使用到refresh()来刷新容器 AnnotationConfigApplicationContext AnnotationConfigApplicationContext会通过扫描配置类来创建IOC容器 Testpublic void m1() {AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(AspectConfig.class);MathCalculator mathCalculator context.getBean(MathCalculator.class);int ans mathCalculator.div(10, 5);System.out.println(结果: ans);}public AnnotationConfigApplicationContext(Class?... componentClasses) {// 调用无参构造方法this();// 注册新的组件register(componentClasses);// 刷新容器refresh();}构造方法 public AnnotationConfigApplicationContext() {StartupStep createAnnotatedBeanDefReader this.getApplicationStartup().start(spring.context.annotated-bean-reader.create);// 创建注解Readerthis.reader new AnnotatedBeanDefinitionReader(this);createAnnotatedBeanDefReader.end();// 创建类扫描this.scanner new ClassPathBeanDefinitionScanner(this); }创建的AnnotatedBeanDefinitionReader 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;this.conditionEvaluator new ConditionEvaluator(registry, environment, null);// 这里最后一行很关键注册了一些核心的BeanPostProcessorAnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }下面的方法就是容器启动时初始化注册一些基础使用的类其中有一个需要着重看一眼的就是负责处理Configuration的后置处理器ConfigurationClassPostProcessor public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {registerAnnotationConfigProcessors(registry, null); }public static SetBeanDefinitionHolder 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());}}SetBeanDefinitionHolder beanDefs new LinkedHashSet(8);// 这里是最重要的就是注册用来处理Configuration注解的后置处理器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));}// 省略了一些代码return beanDefs; }ClassPathXmlApplicationContext 加载bean的xml文件底层也是通过refresh()方式 public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, Nullable ApplicationContext parent)throws BeansException {super(parent);setConfigLocations(configLocations);if (refresh) {refresh();} }二、refresh() 方法简介 refresh()为ConfigurableApplicationContext中的接口子类AbstractApplicationContext重写了该方法负责初始化IOC容器 该方法中总共包含12个方法大体的工作内容介绍 刷新前的准备工作获取Bean工厂工厂前期的准备子类重写方法可以对Bean工厂进行扩展执行BeanFactory的后置处理器注册Bean的后置处理器初始化消息源负责国际化初始化上下文事件子类重写方法初始化其它特殊bean注册监听器工厂基本创建完毕剩余的收尾工作刷新完成剩余的收尾工作 Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh this.applicationStartup.start(spring.context.refresh);// Prepare this context for refreshing. // 1 准备预处理记录容器的启动时间startupDate, 标记容器为激活初始化上下文环境如文件路径信息验证必填属性是否填写prepareRefresh();// 2 告诉子类去刷新bean工厂此方法解析配置文件并将bean信息存储到beanDefinition中注册到BeanFactory//但是未被初始化仅将信息写到了beanDefination的map中**重点方法下面的操作都基于这个beanFactory进行的ConfigurableListableBeanFactory beanFactory obtainFreshBeanFactory();// Prepare the bean factory for use in this context.// 3 设置beanFactory的基本属性类加载器添加多个beanPostProcesserprepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.// 4 扩展机制: 允许上下文子类中对bean工厂进行后处理postProcessBeanFactory(beanFactory);StartupStep beanPostProcess this.applicationStartup.start(spring.context.beans.post-process);/**************************以上是BeanFactory的创建及预准备工作 ****************/// Invoke factory processors registered as beans in the context.// 5 调用BeanFactoryPostProcessor各个实现类的方法 invokeBeanFactoryPostProcessors(beanFactory);// 6 注册 BeanPostProcessor 的实现类registerBeanPostProcessors(beanFactory);beanPostProcess.end();// 7 初始化ApplicationContext的MessageSource组件(资源文件)如国际化文件消息解析绑定等initMessageSource();// 8 初始化ApplicationContext事件广播器initApplicationEventMulticaster();// 9 在特定上下文子类中初始化其他特殊beanonRefresh();// 10 获取所有的事件监听器并将监听器注册到事件广播器registerListeners();// 11 初始化所有不是懒加载的singleton beanfinishBeanFactoryInitialization(beanFactory);// 12 广播事件ApplicationContext初始化完成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 {// 重置 Spring 核心中的公共自省缓存因为我们可能不再需要单例 bean 的元数据......// Reset common introspection caches in Springs core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();contextRefresh.end();}}}1 prepareRefresh() 刷新准备 1、prepareRefresh()刷新前的预处理;1、initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置方法2、getEnvironment().validateRequiredProperties();检验属性的合法等3、earlyApplicationEvents new LinkedHashSet();保存容器中的一些早期的事件/*** Prepare this context for refreshing, setting its startup date and 容器刷新的准备工作设置启动时间* active flag as well as performing any initialization of property sources. 以及初始化属性源*/protected void prepareRefresh() {// Switch to active.this.startupDate System.currentTimeMillis(); // 获取当前时间// 设置关闭状态false 启动状态truethis.closed.set(false);this.active.set(true);// 输出日志if (logger.isDebugEnabled()) {if (logger.isTraceEnabled()) {logger.trace(Refreshing this);}else {logger.debug(Refreshing getDisplayName());}}// Initialize any placeholder property sources in the context environment.// 初始化一些属性在容器环境中 留给子类重写initPropertySources();// Validate that all properties marked as required are resolvable:// see ConfigurablePropertyResolver#setRequiredProperties// 验证属性的是否合法getEnvironment().validateRequiredProperties();// Store pre-refresh ApplicationListeners...if (this.earlyApplicationListeners null) {this.earlyApplicationListeners new LinkedHashSet(this.applicationListeners);}else {// Reset local application listeners to pre-refresh state.this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}// Allow for the collection of early ApplicationEvents,// to be published once the multicaster is available...// 通过集合保存早期的容器事件// 等派发起好了以后,在派发出去this.earlyApplicationEvents new LinkedHashSet();}a initPropertySources() 是个空方法留给子类重写自定义 /*** pReplace any stub property sources with actual instances.* see org.springframework.core.env.PropertySource.StubPropertySource* see org.springframework.web.context.support.WebApplicationContextUtils#initServletPropertySources*/protected void initPropertySources() {// For subclasses: do nothing by default.}b validateRequiredProperties() 验证请求属性方法很简单循环遍历判断是否为Null存在则直接抛出异常MissingRequiredPropertiesException该异常为自定义异常类 public void validateRequiredProperties() {// 创建异常信息MissingRequiredPropertiesException ex new MissingRequiredPropertiesException();Iterator var2 this.requiredProperties.iterator();// 遍历 找到空的keywhile(var2.hasNext()) {String key (String)var2.next();if (this.getProperty(key) null) {ex.addMissingRequiredProperty(key);}}// 存在空的直接抛出异常if (!ex.getMissingRequiredProperties().isEmpty()) {throw ex;}}2 obtainFreshBeanFactory() 获取bean工厂 该方法很简单获取到对应的bean工厂类型为DefaultListableBeanFactory也是Spring中功能最全的IOC容器 /*** Tell the subclass to refresh the internal bean factory.* return the fresh BeanFactory instance 返回容器示例* see #refreshBeanFactory()* see #getBeanFactory()*/protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {// 刷新容器refreshBeanFactory();// 通过getter方法获取到Bean工厂返回,其实就是默认的DefaultListableBeanFactoryreturn getBeanFactory();}a refreshBeanFactory() 在GenericApplicationContext类初始化的时候就创建了一个默认的BeanFactory,然后这里会设置Id 创建的beanFactory是DefaultListableBeanFactory类型该beanFactory在类初始化的时候就创建了 public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {// 构造方法public GenericApplicationContext() {// 这里也代表了DefaultListableBeanFactory是Spring中最核心的类this.beanFactory new DefaultListableBeanFactory();}/*** Do nothing: We hold a single internal BeanFactory and rely on callers* to register beans through our public methods (or the BeanFactorys).* see #registerBeanDefinition*/Overrideprotected 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就是 org.springframework.context.annotation.AnnotationConfigApplicationContext5b0abc94this.beanFactory.setSerializationId(getId());} // ... }3 prepareBeanFactory() 准备工厂 3、prepareBeanFactory(beanFactory);BeanFactory的预准备工作BeanFactory进行一些设置1、设置BeanFactory的类加载器、支持表达式解析器...2、添加部分BeanPostProcessor【ApplicationContextAwareProcessor】3、设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx4、注册可以解析的自动装配我们能直接在任何组件中自动注入BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext5、添加BeanPostProcessor【ApplicationListenerDetector】6、添加编译时的AspectJ7、给BeanFactory中注册一些能用的组件environment【ConfigurableEnvironment】、systemProperties【MapString, Object】、systemEnvironment【MapString, Object】/*** Configure the factorys standard context characteristics, 配置工厂启动时上下文特征* such as the contexts ClassLoader and post-processors. 例如容器的类加载器和后置处理器* param beanFactory the BeanFactory to configure*/protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the contexts class loader etc.// 1.设置Bean的类加载器beanFactory.setBeanClassLoader(getClassLoader());if (!shouldIgnoreSpel) {// 设置支持相关表达式语言的解析器beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));}// 添加属性的编辑注册器beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.// 2.添加部分后置处理器【ApplicationContextAwareProcessor】beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 3.设置忽略自动装配的接口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.ignoreDependencyInterface(ApplicationStartupAware.class);// BeanFactory interface not registered as resolvable type in a plain factory.// MessageSource registered (and found for autowiring) as a bean.// 4.注册可以解析的自动装配beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// Register early post-processor for detecting inner beans as ApplicationListeners.// 5.添加BeanPostProcessor【ApplicationListenerDetector】事件监听beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// Detect a LoadTimeWeaver and prepare for weaving, if found.if (!NativeDetector.inNativeImage() beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// Set a temporary ClassLoader for type matching.beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// Register default environment beans.// 给BeanFactory中注册一些能用的组件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());}if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());}}4 postProcessBeanFactory() 子类重写扩展 提供的扩展机制子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置 /*** Modify the application contexts internal bean factory after its standard* initialization. All bean definitions will have been loaded, but no beans* will have been instantiated yet. This allows for registering special* BeanPostProcessors etc in certain ApplicationContext implementations.* param beanFactory the bean factory used by the application context*/protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {}5 invokeBeanFactoryPostProcessors() a 方法入口 这个方法会继续调用一个包装类中的方法负责执行后置处理器其中的参数getBeanFactoryPostProcessors()会获取后置处理器这里获取的后置处理器是框架初始化需要的会被优先执行 但需要注意的是并不是Spring框架需要的在实际测试过程中如果使用SpringBoot可以成功获取到如果单独启动Spring则啥也没有 /*** Instantiate and invoke all registered BeanFactoryPostProcessor beans,* respecting explicit order if given.* pMust be called before singleton instantiation.*/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()));}}上面两张图也说明了问题如果想在Spring框架基础上封装其它框架例如经典的SpringBootSpring会先执行SpringBoot初始化需要的后置处理器保证核心框架先顺利启动然后再执行其它依赖和手写的后置处理器 当然侧面证明了Spring提供的良好的扩展性能再启动Spring的时候优先执行二次封装的代码最后在是其它依赖和自己写的代码 b 接口介绍 下面方法会用到这2个接口这里先介绍一下 BeanFactoryPostProcessor BeanFactoryPostProcessor的执行时机为容器初始化后实例化Bean前Spring允许在这个时候可以对Bean工厂进行修改一种良好的扩展性能 public interface BeanFactoryPostProcessor {// 通过参数ConfigurableListableBeanFactory可以获取到定义信息void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }使用示例 Component public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println(调用MyBeanFactoryPostProcessor的postProcessBeanFactory);BeanDefinition bd beanFactory.getBeanDefinition(mathCalculator);System.out.println(属性值------ bd.getPropertyValues().toString());MutablePropertyValues pv bd.getPropertyValues();if (pv.contains(remark)) {pv.addPropertyValue(remark, 把备注信息修改一下);}bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);} }BeanDefinitionRegistryPostProcessor 通过下面的代码看到它继承了BeanFactoryPostProcessor它会在所有的bean定义信息还未被加载将要被加载的时候执行可以对BeanDefiniton进行增删改查 public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {/*** Modify the application contexts internal bean definition registry after its* standard initialization. All regular bean definitions will have been loaded,* but no beans will have been instantiated yet. This allows for adding further* bean definitions before the next post-processing phase kicks in.* param registry the bean definition registry used by the application context* throws org.springframework.beans.BeansException in case of errors*/void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; }c 方法分析 首先参数传递过来的后置处理器该参数上面已经介绍了这些是框架启动需要的例如SpringBoot如果是单独的Spring启动则为空集合判断是否实现了BeanDefinitionRegistry该接口只有IOC容器实现了该接口才代表允许其它代码操作BeanDefinition看成一个开关入口执行第1步首先执行SpringBoot框架需要的BeanDefinitionRegistryPostProcessor需要先把框架处理完毕执行第2步执行其它依赖和开发人员写的BeanDefinitionRegistryPostProcessor 优先执行实现了PriorityOrdered接口的次之执行实现了Ordered接口的执行剩余的后置处理器 接下来会先执行一批BeanFactoryPostProcessor上面也介绍了这2个接口是继承关系所以重写子类方法必须也带上父类方法上面执行的BeanDefinitionRegistryPostProcessor后置处理器肯定也有BeanFactoryPostProcessor的方法这里需要执行这里启动就是2部分 先执行上面这些实现了BeanDefinitionRegistryPostProcessor接口里面肯定重写了父类BeanFactoryPostProcessor需要先执行参数传递过来的BeanFactoryPostProcessor这些也需要先执行 到此上面已经把BeanDefinitionRegistryPostProcessor处理完毕接下来就是BeanFactoryPostProcessor这里会和上面一样先处理PriorityOrdered次之Ordered最后剩余的总结代码非常长理解了很简答总体思想就是先执行框架启动需要的然后在执行自己写的先执行BeanDefinitionRegistryPostProcessor后BeanFactoryPostProcessor public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListBeanFactoryPostProcessor beanFactoryPostProcessors) {// Invoke BeanDefinitionRegistryPostProcessors first, if any.// 执行BeanDefinitionRegistryPostProcessors的实现类【首先调用】SetString processedBeans new HashSet();// 实现该接口才允许操作BeanDefinition,当然DefaultListableBeanFactory肯定实现了if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry (BeanDefinitionRegistry) beanFactory;ListBeanFactoryPostProcessor regularPostProcessors new ArrayList();ListBeanDefinitionRegistryPostProcessor registryProcessors new ArrayList();// 1 处理参数传递过来的后置处理器这些是Spring启动需要的// 按照实现接口分类存进去, 并且优先执行实现了BeanDefinitionRegistryPostProcessor的后置方法,系统类的先执行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.// 定义一个变量,用于后续分批执行代码ListBeanDefinitionRegistryPostProcessor currentRegistryProcessors new ArrayList();// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.// 第一步 执行实现了 PriorityOrdered 优先级排序接口的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, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.// 第二步 执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessorspostProcessorNames 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.// 最后 执行剩余的BeanDefinitionRegistryPostProcessorsboolean 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.// 调用到目前为止处理的所有处理器的 postProcessBeanFactory() 回调// 这里会有一个疑问 postProcessBeanFactory()不是下面很多行代码负责执行吗咋这里就执行了// 首先 registryProcessors是上面实现了子类接口那么父类肯定也给重写那么这里先调用// 其次 regularPostProcessors到目前位置有数据肯定是框架启动需要的后置处理器,也要先执行invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {// Invoke factory processors registered with the context instance.// 否则执行框架启动需要的后置处理器invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}// 获取所有的 BeanFactoryPostProcessor 后置处理器String[] postProcessorNames beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,// Ordered, and the rest.ListBeanFactoryPostProcessor priorityOrderedPostProcessors new ArrayList();ListString orderedPostProcessorNames new ArrayList();ListString 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.// 第一步 执行实现 PriorityOrdered 接口的 BeanFactoryPostProcessorssortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.// 第二步 执行实现 Ordered 接口的 BeanFactoryPostProcessorsListBeanFactoryPostProcessor 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.// 第三步 执行剩余的ListBeanFactoryPostProcessor 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();}d 重要Debug 如下截图所示Spring框架负责解析Configuration配置类的是后置处理器ConfigurationClassPostProcessor它会负责扫描各种类把bean包装成BeanDefinition存入IOC容器具体后续会介绍ConfigurationClassPostProcessor 6 registerBeanPostProcessors() 顾名思义注册Bean后置处理器它负责拦截Bean的创建这样我们就可以通过该拦截对Bean添加自定义逻辑例如Aop功能就是通过注解添加了一个后置处理器然后在创建Bean的时候对其进行代理达到增强的目的 protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }获取所有的BeanPostProcessor后置处理器先注册PriorityOrdered优先级接口的BeanPostProcessor再注册Ordered接口的最后注册没有实现任何优先级接口的最终注册MergedBeanDefinitionPostProcessor注册一个ApplicationListenerDetector public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {// 1.获取所有实现 BeanPostProcessor 接口的后置处理器String[] postProcessorNames beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);// 2.记录数量 框架中已经存在的 稍后会注入的数量 下一行代码注入的1个后置处理器int beanProcessorTargetCount beanFactory.getBeanPostProcessorCount() 1 postProcessorNames.length;// 新注册的处理器 BeanPostProcessorChecker 主要用于记录信息beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// Separate between BeanPostProcessors that implement PriorityOrdered,// Ordered, and the rest.// 3.分类存储// 实现PriorityOrdered接口的ListBeanPostProcessor priorityOrderedPostProcessors new ArrayList();ListBeanPostProcessor internalPostProcessors new ArrayList();// 实现Ordered接口的name集合ListString orderedPostProcessorNames new ArrayList();// 定义普通的name集合ListString 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);}}// 4.先注册实现 PriorityOrdered 接口的// First, register the BeanPostProcessors that implement PriorityOrdered.sortPostProcessors(priorityOrderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// 5.次之注册实现 Ordered 接口的// Next, register the BeanPostProcessors that implement Ordered.ListBeanPostProcessor orderedPostProcessors new ArrayList(orderedPostProcessorNames.size());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);// 5.最后注册普通的后置处理器// Now, register all regular BeanPostProcessors.ListBeanPostProcessor nonOrderedPostProcessors new ArrayList(nonOrderedPostProcessorNames.size());for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);// 6.注册实现了 MergedBeanDefinitionPostProcessor 接口的// Finally, re-register all internal BeanPostProcessors.sortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);// Re-register post-processor for detecting inner beans as ApplicationListeners,// moving it to the end of the processor chain (for picking up proxies etc).// 7.重新注册用于将内部 bean 检测为 ApplicationListeners 的后处理器将其移动到处理器链的末尾用于获取代理等beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }7 initMessageSource() 国际化 MessageSource是负责国际化功能的下面的代码大体很简单如果已经存在国际化组件就一顿操作处理没有就注册个新的 那么想一下之前怎么可能会有该bean那肯定是开发人员自定义的国际化组件如果存在则在第5步的时候已经解析完毕执行到该方法肯定就可以获取到 那么在把下面这个方法概述一下如果开发人员自定义了国际化组件那就用自己写的按照固定的格式处理一下否则就用默认的国际化组件 这同样体现了Spring框架良好的扩展机制后续会编写单独的文章介绍MessageSource protected void initMessageSource() {ConfigurableListableBeanFactory beanFactory getBeanFactory();// 如果存在该bean则代表开发人员自定义了国家化组件if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {this.messageSource beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);// Make MessageSource aware of parent MessageSource.if (this.parent ! null this.messageSource instanceof HierarchicalMessageSource) {HierarchicalMessageSource hms (HierarchicalMessageSource) this.messageSource;if (hms.getParentMessageSource() null) {// Only set parent context as parent MessageSource if no parent MessageSource// registered already.hms.setParentMessageSource(getInternalParentMessageSource());}}if (logger.isTraceEnabled()) {logger.trace(Using MessageSource [ this.messageSource ]);}}else { // 否则使用默认的国际化组件// Use empty MessageSource to be able to accept getMessage calls.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 ]);}} }8 initApplicationEventMulticaster() 下面这个方法大体逻辑和第7步一致如果存在该bean则代表开发人员自定义了该功能则处理一下否则注册一个默认的 ApplicationEventMulticaster是Spring中事件广播器接口负责事件的广播发布。 通过名字可以看出它就是一个广播站可以把监听器注册到我这里来有事件通过我进行发布。也可以理解为MQ种的发布-订阅模式监听器在这里进行订阅有消息通过我进行发布 protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory getBeanFactory();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 {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() ]);}} }ApplicationEventMulticaster 上面看懂了该组件的功能这里看接口就好理解了负责注册监听器的负责发布事件的 public interface ApplicationEventMulticaster {// 注册监听器void addApplicationListener(ApplicationListener? listener);void addApplicationListenerBean(String listenerBeanName);// 移除监听器void removeApplicationListener(ApplicationListener? listener);void removeApplicationListenerBean(String listenerBeanName);void removeAllListeners();// 发布事件void multicastEvent(ApplicationEvent event);void multicastEvent(ApplicationEvent event, Nullable ResolvableType eventType);}9 onRefresh() 子类重写扩展 在特定上下文子类中初始化其他特殊bean protected void onRefresh() throws BeansException {// For subclasses: do nothing by default. }10 registerListeners() 在上面第8步注册了一个事件广播器该方法负责把监听器注册到里面 protected void registerListeners() {// 1.向事件分发器注册监听器这些是通过配置文件读取的// Register statically specified listeners first.for (ApplicationListener? listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);}// 2.向事件分发器注册外部加入的监听器但不实例化// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let post-processors apply to them!String[] listenerBeanNames getBeanNamesForType(ApplicationListener.class, true, false);for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);}// 3.发布早期的事件// Publish early application events now that we finally have a multicaster...SetApplicationEvent earlyEventsToProcess this.earlyApplicationEvents;this.earlyApplicationEvents null;if (earlyEventsToProcess ! null) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);}} }11 finishBeanFactoryInitialization() 通过名字可以看出是完成BeanFactory的初始化一个收尾方法相当于一个bean工厂大部分已经完成了还剩余零零散散的辅助bean需要依次注入 在这个方法中需要关注的是最后1行这里会实例化未设置懒加载的单例bean protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// 1.为此上下文初始化转换服务// 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 bean post-processor// (such as a PropertyPlaceholderConfigurer bean) registered any before:// at this point, primarily for resolution in annotation attribute values.// 2.如果之前没有注册任何 bean 后处理器例如 PropertyPlaceholderConfigurer bean则注册一个默认的嵌入值解析器此时主要用于注释属性值的解析if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal - getEnvironment().resolvePlaceholders(strVal));}// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.// 3.通过 getBean() 尽早的注册LoadTimeWeaverAwareString[] weaverAwareNames beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// Stop using the temporary ClassLoader for type matching. // 4.停止使用临时类加载器进行类型匹配beanFactory.setTempClassLoader(null);// Allow for caching all bean definition metadata, not expecting further changes. // 5.允许缓存所有 bean 定义元数据而不是期望进一步的更改beanFactory.freezeConfiguration();// 6.Instantiate all remaining (non-lazy-init) singletons.// 初始化未懒加载的单例beanbeanFactory.preInstantiateSingletons(); }a preInstantiateSingletons 子类DefaultListableBeanFactory重写了该方法 功能循环所有的Bean名称遍历判断然后实例化最后调用回调 // DefaultListableBeanFactory Overridepublic 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.// 1.获取全部的BeanNameListString beanNames new ArrayList(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...// 2.实例化所有非懒加载的单实例Beanfor (String beanName : beanNames) RootBeanDefinition bd getMergedLocalBeanDefinition(beanName);// 非抽象 单实例 非懒加载if (!bd.isAbstract() bd.isSingleton() !bd.isLazyInit()) {// 类型判断是否为FactoryBean, FactoryBean在后续章节也有讲解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((PrivilegedActionBoolean) ((SmartFactoryBean?) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit (factory instanceof SmartFactoryBean ((SmartFactoryBean?) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else {// 普通的Bean在这里直接获取getBean(beanName);}}}// Trigger post-initialization callback for all applicable beans...// 触发所有适用 bean 的初始化后回调for (String beanName : beanNames) {Object singletonInstance getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {SmartInitializingSingleton smartSingleton (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() ! null) {AccessController.doPrivileged((PrivilegedActionObject) () - {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}}}}12 finishRefresh() 上面已经把BeanFactory初始化完毕那么这个IOC容器就接近尾声了接下来就是一些后续工作 protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).// 清除上下文级资源缓存clearResourceCaches();// Initialize lifecycle processor for this context.// 为此上下文初始化生命周期处理器initLifecycleProcessor();// Propagate refresh to lifecycle processor first.getLifecycleProcessor().onRefresh();// Publish the final event.publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.LiveBeansView.registerApplicationContext(this); }ingleton) { SmartInitializingSingleton smartSingleton (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() ! null) { AccessController.doPrivileged((PrivilegedAction) () - { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } } ## 12 finishRefresh()上面已经把BeanFactory初始化完毕那么这个IOC容器就接近尾声了接下来就是一些后续工作java protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).// 清除上下文级资源缓存clearResourceCaches();// Initialize lifecycle processor for this context.// 为此上下文初始化生命周期处理器initLifecycleProcessor();// Propagate refresh to lifecycle processor first.getLifecycleProcessor().onRefresh();// Publish the final event.publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.LiveBeansView.registerApplicationContext(this); }
http://www.w-s-a.com/news/187371/

相关文章:

  • 公众微信绑定网站帐号优秀中文网页设计
  • 如何做漫画赚钱的网站企业网站管理系统c
  • 安康公司网站制作搜狗网站
  • 太仓住房与城乡建设局网站注册推广赚钱一个80元
  • wordpress 网站生成app企业网站改版的好处
  • 广州建站服务怎么让客户做网站
  • 南京手机网站设计公司wordpress导航页
  • 娄底市建设网站app网站开发小程序
  • 刷粉网站推广免费网站建设找王科杰信誉
  • 投标建设用地是哪个网站微信小程序多少钱
  • 做玄幻封面素材网站我国数字经济报告
  • 手机网站返回跳转wordpress带颜色的文字
  • 微信群领券网站怎么做创意广告图片
  • 跟我一起做网站嘉兴做网站哪家好
  • 上海知名建站公司山东住房和建设庭网站
  • 深圳市城乡建设部网站首页平台设计方案怎么做
  • 深圳美食教学网站制作wordpress列表图显示标题
  • 怎么做网址导航网站沈阳高端做网站建设
  • 棋牌网站开发需要多少钱整网站代码 带数据 免费 下载
  • 网站建设 sql 模版猎头用什么网站做单
  • 河北保定建设工程信息网站wordpress 远程缓存
  • 手机网站开发之列表开发win7网站开发教程
  • 楚雄市住房和城乡建设局网站廊坊企业网站建设
  • 东莞规划局官方网站wordpress添加文章页不显示图片
  • 做企业网站要哪些人员百度商城网站建设
  • c语言软件开和网站开发区别多产品的网站怎么做seo
  • 收益网站制作移动互联网应用的使用情况表格
  • 专业的手机网站建设公司哪家好同城信息网站建设
  • 参与做网站的收获国外网站服务器建设
  • 西宁网站建设报价cu君博规范网站kv如何做