SpringMVC运行流程
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发的。
新建一个maven项目,实现一个SpringMVC测试用例:
- ①在pom.xml中导入相关依赖:
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发的。
新建一个maven项目,实现一个SpringMVC测试用例:
SpringAOP的概述和使用已经在之前的文章中讲过,此篇文章就根据一个测试用例简单介绍基于注解的SpringAOP的原理。测试用例如下:
1 | <dependency> |
Spring监听器在使用过程中可以监听到某一事件的发生,进而对事件做出相应的处理。下面先创建一个自定义监听器(实现ApplicationListener接口的bean)做测试。
1 | public class MyApplicationListener implements ApplicationListener<ApplicationEvent> { |
首先创建一个测试案例,导入Spring相关依赖:
1 | <dependency> |
注解版测试用例如下:
1 | public class User { |
1 | @Configuration |
1 | public class MainTest { |
xml版测试用例如下:
1 | <?xml version="1.0" encoding="UTF-8"?> |
1 | public class MainTest { |
AnnotationConfigApplicationContext(IOC容器)的有关继承树如图:
DefaultListableBeanFactory(Bean工厂)的有关继承树如图:
Spring中后置处理器的作用:
Spring中创建对象包括:
Spring中Aware接口的作用:
Spring中提供的各种接口:
打断点进入new ClassPathXmlApplicationContext(“beans.xml”)构造器:
1 | public ClassPathXmlApplicationContext(String configLocation) throws BeansException { |
1 | public ClassPathXmlApplicationContext( |
①调用父类构造方法,进行相关的对象创建等操作。
1 | public AbstractXmlApplicationContext(@Nullable ApplicationContext parent) { |
1 | public AbstractRefreshableConfigApplicationContext(@Nullable ApplicationContext parent) { |
1 | public AbstractRefreshableApplicationContext(@Nullable ApplicationContext parent) { |
1 | public AbstractApplicationContext(@Nullable ApplicationContext parent) { |
1 | public AbstractApplicationContext() { |
1 | protected ResourcePatternResolver getResourcePatternResolver() { |
②设置应用程序上下文的配置路径。
1 | //AbstractRefreshableConfigApplicationContext类中,此方法将解析后的配置文件路径放进AbstractRefreshableConfigApplicationContext类的成员变量String[] configLocations数组中 |
1 | protected String resolvePath(String path) { |
分成两步,第一步获取环境变量。
1 | @Override |
1 | protected ConfigurableEnvironment createEnvironment() { |
1 | //父类AbstractEnvironment的构造方法 |
1 | //子类StandardEnvironment实现的customizePropertySources方法 |
第二步处理一些必需的占位符。
1 | @Override |
1 | @Override |
1 | private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) { |
1 | public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) { |
1 | //PropertyPlaceholderHelper类中 |
1 | //placeholderResolver.resolvePlaceholder(placeholder)方法中会调用PropertySourcesPropertyResolver类中的getPropertyAsRawString()方法 |
1 | @Nullable |
③进入AbstractApplicationContext类的refresh()方法,处理逻辑和注解版的类似,后面详细介绍。
打断点进入new AnnotationConfigApplicationContext(MainConfig.class)构造器:
1 | public AnnotationConfigApplicationContext(Class<?>... componentClasses) { |
①进入this()调用的是无参构造器:
1 | public AnnotationConfigApplicationContext() { |
②接着进入AnnotationConfigApplicationContext.register(componentClasses)通过AnnotatedBeanDefinitionReader的register方法实现注解bean的读取,register方法重点完成了bean配置类本身的解析和注册,处理过程可以分为以下几个步骤:
1 | public void register(Class<?>... componentClasses) { |
③接着进入refresh()方法,其在父类在AbstractApplicationContext中实现,作用是加载或者刷新当前的配置信息,如果已经存在spring容器,则先销毁之前的容器,重新创建spring容器,载入bean定义,完成容器初始化工作。
1 | @Override |
打断点进入AbstractApplicationContext.prepareRefresh()方法,即刷新上下文前的预处理:
1 | protected void prepareRefresh() { |
①设置容器启动时间。
②设置关闭状态为false。
③设置活跃状态为true。
④调用AbstractApplicationContext.initPropertySources(),即初始化一些属性设置。子类自定义个性化的属性设置方法(即可以自定义一个AnnotationConfigApplicationContext的子类并重写initPropertySources())。
1 | /** |
重写例子:
⑤调用getEnvironment().validateRequiredProperties(),获取Environment对象(之前已经创建过了),并加载当前系统的同性值到Environment对象中。在getEnvironment()中会实例化StandardEnvironment,实例化时会调用父类AbstractEnvironment的构造方法,此父类构造方法会调用空方法customizePropertySources(this.propertySources),实际调用的是子类StandardEnvironment实现好的customizePropertySources(this.propertySources)方法,如下:
1 | @Override |
validateRequiredProperties()用于验证requiredProperties中的环境变量是否存在,不存在则抛出异常:
1 | //AbstractPropertyResolver类中 |
⑥调用this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners)准备监听器和this.earlyApplicationEvents = new LinkedHashSet<>()准备事件的集合对象,保存容器中的一些早期的事件,当以后事件派发器创建完成后将这些早期事件派发出去,默认为空的集合。
打断点进入AbstractApplicationContext.obtainFreshBeanFactory()方法,作用是返回bean工厂。
1 | protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { |
注解版
①调用GenericApplicationContext.refreshBeanFactory(),即刷新【创建】BeanFactory。
1 | // 注解版,GenericApplicationContext.refreshBeanFactory() |
②调用GenericApplicationContext.getBeanFactory(),即返回刚才GenericApplicationContext创建的BeanFactory对象,此时返回的BeanFactory都只是一些默认的设置。
③将创建的BeanFactory【DefaultListableBeanFactory】返回。
xml版
①调用AbstractRefreshableApplicationContext.refreshBeanFactory(),即刷新【创建】BeanFactory。
1 | //xml版,AbstractRefreshableApplicationContext.refreshBeanFactory() |
①调用AbstractRefreshableApplicationContext.createBeanFactory()创建一个Bean工厂DefaultListableBeanFactory。
1 | protected DefaultListableBeanFactory createBeanFactory() { |
②设置序列化id:this.beanFactory.setSerializationId(this.getId())。
1 | public void setSerializationId(@Nullable String serializationId) { |
③定制beanFactory,设置相关属性包括是否允许覆盖同名称的不同定义的对象以及循环依赖。
1 | protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { |
这里子类可以扩展实现customizeBeanFactory方法,涉及两个属性,一是allowBeanDefinitionOverriding:是否允许覆盖同名称的不同定义的对象;二是allowCircularReferences:是否允许bean之间存在循环依赖。
④执行loadBeanDefinitions(beanFactory)初始化documentReader,并进行xml解析。
1 | @Override |
①这里会通过调用beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this))给beanDefinitionReader设置ResourceEntityResolver用于加载本地的校验文件。
1 | public ResourceEntityResolver(ResourceLoader resourceLoader) { |
1 | public DelegatingEntityResolver(@Nullable ClassLoader classLoader) { |
1 | public PluggableSchemaResolver(@Nullable ClassLoader classLoader) { |
②最后调用loadBeanDefinitions(beanDefinitionReader)开始完成beanDefinition的加载。
1 | protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { |
由于ClassPathXmlApplicationContext的构造方法没有传入paths,所以getConfigResources()返回null,不会执行第一个if块;而之前已经设置过ConfigLocations,所以getConfigLocations()不为null,执行第二个if块即reader.loadBeanDefinitions(configLocations)。
1 | @Override |
执行到count += loadBeanDefinitions(location)解析第一个配置文件。
1 | @Override |
1 | public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException { |
这里面获取到Resource数组后调用loadBeanDefinitions(resources)循环获取Resource进行解析。
1 | @Override |
执行到count += loadBeanDefinitions(resource)解析第一个Resource。
1 | @Override |
1 | public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { |
这里执行doLoadBeanDefinitions(inputSource, encodedResource.getResource())进入了核心的解析步骤。
1 | protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) |
在获取到xml文件的document对象(包含node父子节点信息)后,会接着调用registerBeanDefinitions(doc, resource)读取document对象里的节点信息。
1 | public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { |
接着调用documentReader.registerBeanDefinitions(doc, createReaderContext(resource))完成具体解析过程。
1 | @Override |
1 | @SuppressWarnings("deprecation") // for Environment.acceptsProfiles(String...) |
调用parseBeanDefinitions(root, this.delegate)利用delegate从Document的根节点开始往下解析。
1 | /** |
由于解析到的<bean>标签是默认名称空间里的,所以执行parseDefaultElement(ele, delegate)。
1 | private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { |
1 | protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { |
①首先调用delegate.parseBeanDefinitionElement(ele)完成解析。
1 | @Nullable |
1 | @Nullable |
里面调用parseBeanDefinitionElement(ele, beanName, containingBean)进行对bean标签进行详细解析。
1 | @Nullable |
②接着调用BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())向ioc容器注册解析得到的beanDefinition的地方。
1 | public static void registerBeanDefinition( |
①调用registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition())将bean的信息添加到beanDefinitionMap中一以及记录beanName。
1 | @Override |
②调用registry.registerAlias(beanName, alias)注册所有的别名,将别名放到Map<String, String> aliasMap中。
1 | @Override |
1 | @Override |
③调用getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder))在beanDefinition向ioc容器注册完成之后,发送消息。
②返回当前实体的beanFactory属性。
打断点进入AbstractApplicationContext.prepareBeanFactory(beanFactory)方法,即BeanFactory的预准备工作。
1 | protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { |
打断点进入AbstractApplicationContext.postProcessBeanFactory(beanFactory)方法,即进行准备工作完成后的后置处理工作,此方法是空的,子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置。
1 | protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { |
打断点进入AbstractApplicationContext.invokeBeanFactoryPostProcessors(beanFactory)方法,即实例化并且执行所有已经注册了的BeanFactoryPostProcessor(BeanFactory的后置处理器)的方法。其内部执行实现了BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor这两个接口的Processor。两个接口的关系如下图:
1 | protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { |
主要执行PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法。
1 | public static void invokeBeanFactoryPostProcessors( |
①初始化存放BeanFactoryPostProcessor集合。
②遍历传入的beanFactoryPostProcessors集合。
③获取实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,排序后并执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry(registry)方法。(这里的后置处理器ConfigurationClassPostProcessor解析出了配置类里自定义的bean)。
④获取实现了Ordered接口的BeanDefinitionRegistryPostProcessor,排序后并执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry(registry)方法。
⑤最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry(registry)方法,与上面类似因此不再赘述。
⑥遍历执行registryProcessors(存放BeanDefinitionRegistryPostProcessor集合)中的postProcessBeanFactory(beanFactory)方法。
⑦遍历执行regularPostProcessors(存放普通的BeanFactoryPostProcessor集合)中的postProcessBeanFactory(beanFactory)方法。
⑧获取到所有BeanFactoryPostProcessor的实现类并根据排序接口顺序执行,和上面类似(③④⑤)。
⑨清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType), 因为后置处理器可能已经修改了原始元数据,例如,替换值中的占位符等。
如果是注解版,invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)中执行ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(registry)的方法完成bean的扫描操作,其中重点执行了processConfigBeanDefinitions(registry)方法。
1 | @Override |
1 | public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { |
该方法中,完成了以下操作:
我们需要关心的是对@ComponentScan注解的处理:即parser.parse(candidates)。
1 | public void parse(Set<BeanDefinitionHolder> configCandidates) { |
1 | protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException { |
1 | protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException { |
1 | protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) |
这里会解析ComponentScans和ComponentScan注解,ComponentScans是多个ComponentScan的组合,开发中很少使用,我们重点分析ComponentScan,this.conditionEvaluator.shouldSkip是解析时检查一些依赖信息,这里之所以用了for循环解析,是因为可能会解析出多处ComponentScan标注信息,继续看ComponentScanAnnotationParser#parse方法,核心的思想是,从beanDefinition中,获取到componentScan注解的basePackages,即:要扫描的包信息。
1 | public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) { |
1 | protected Set<BeanDefinitionHolder> doScan(String... basePackages) { |
我们要关注的是第一步这里:findCandidateComponents(basePackage)
这个方法中,就是完成了真正的所谓的自动扫描。
1 | public Set<BeanDefinition> findCandidateComponents(String basePackage) { |
1 | private Set<BeanDefinition> scanCandidateComponents(String basePackage) { |
需要注意的是:这里有两个isCandidateComponent方法,但是完成的功能不同。
isCandidateComponent(metadataReader):这个方法是在未生成beanDefinition对象之前,从includeFilter和excludeFilter中进行过滤。
1 | protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException { |
isCandidateComponent(sbd):是在生成beanDefinition对象之后,判断当前bean是否满足注入的要求。
1 | protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) { |
打断点进入AbstractApplicationContext.registerBeanPostProcessors(beanFactory)方法,即注册BeanPostProcessor(Bean的后置处理器)。例如:DestructionAwareBeanPostProcessor、InstantiationAwareBeanPostProcessor、SmartInstantiationAwareBeanPostProcessor、MergedBeanDefinitionPostProcessor【放在List<BeanPostProcessor> internalPostProcessors】。不同接口类型的BeanPostProcessor,在Bean创建前后的执行时机是不一样的,主要用在bean实例化之后,执行初始化方法前后允许开发者对bean实例进行修改,Spring中的bean后置处理器继承关系如下图:
1 | protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { |
1 | public static void registerBeanPostProcessors( |
1 | private static void registerBeanPostProcessors( |
1 | @Override |
①初始化存放Processor集合。
②将所有BeanPostProcessor分门别类放进各个集合。
③将实现了PriorityOrdered优先级接口的BeanPostProcessor进行排序并注册(把每一个BeanPostProcessor添加到BeanFactory中,beanFactory.addBeanPostProcessor(postProcessor))。如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,则将ppName对应的Bean实例添加到internalPostProcessors中。
④将实现了Ordered优先级接口的BeanPostProcessor进行排序并注册(把每一个BeanPostProcessor添加到BeanFactory中,beanFactory.addBeanPostProcessor(postProcessor))。如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,则将ppName对应的Bean实例添加到internalPostProcessors中。
⑤最后注册没有实现任何优先级接口的BeanPostProcessor(把每一个BeanPostProcessor添加到BeanFactory中,beanFactory.addBeanPostProcessor(postProcessor))。如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,则将ppName对应的Bean实例添加到internalPostProcessors中。
⑥对所有的MergedBeanDefinitionPostProcessor进行排序并注册(把每一个BeanPostProcessor添加到BeanFactory中,beanFactory.addBeanPostProcessor(postProcessor))。
⑦注册一个后置处理器ApplicationListenerDetector,其用来监听某个bean是不是监听器。在Bean初始化完成之后,如果Bean是单例的则并且bean instanceof ApplicationListener则加入到this.applicationListeners中(this.applicationContext.addApplicationListener((ApplicationListener<?>) bean));在Bean销毁之前,如果Bean是一个ApplicationListener,则会从ApplicationEventMulticaster(事件广播器)中提前删除。
1 | class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor { |
**打断点进入AbstractApplicationContext.initMessageSource()**,用来设置国际化资源相关的调用,将实现了MessageSource接口的bean存放在ApplicationContext的成员变量中,先看是否有此配置,如果有就实例化,否则就创建一个DelegatingMessageSource实例的bean。
1 | protected void initMessageSource() { |
打断点进入AbstractApplicationContext.initApplicationEventMulticaster()方法,即初始化并注册事件派发器。Spring的监听器机制包含事件、事件发布者、事件监听器:
1 | protected void initApplicationEventMulticaster() { |
打断点进入AbstractApplicationContext.onRefresh()方法,是个空方法,即子类可以重写这个方法,在容器刷新的时候可以自定义逻辑。
1 | protected void onRefresh() throws BeansException { |
打断点进入AbstractApplicationContext.registerListeners()方法,即将所有项目里面的ApplicationListener注册进容器。只是将一些特殊的监听器注册到广播组中,那些在bean配置文件中实现了ApplicationListener接口的类还没有实例化,所以此时只是将listenerBeanNames保存到了广播组中,将这些监听器注册到广播组中的操作时在bean的后置处理器中完成的,那时候bean的实例化已经完成了。
1 | protected void registerListeners() { |
打断点进入AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory)方法,即初始化所有剩下的单实例bean。
1 | protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { |
重点是执行DefaultListableBeanFactory类中的preInstantiateSingletons()方法初始化剩下的单实例bean。
①获取容器中的所有Bean。
1 | @Override |
②获取Bean的定义信息:RootBeanDefinition。
1 | //根据beanDefinitionNames根据父节点和节点进行组装为整体的RootBeanDefinition |
1 | protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { |
③判断Bean判断是否非抽象,单例,非延迟加载。
1 | if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { |
①判断是否是FactoryBean,即是否是实现FactoryBean接口的Bean。如果使用BeanFactory接口。那么必须严格遵守SpringBean的生命周期。从实例化到初始化到before和after。此流程很复杂且麻烦。需要一种更加便捷简单的方式创建,所以有了FactoryBean,它不需要遵循此创建顺序。
1 | if (isFactoryBean(beanName)) { |
②如果不是工厂Bean。利用getBean(beanName)创建对象:
1 | else { |
1 | @Override |
①执行transformedBeanName()方法,该方法将doGetBean的参数name转换成容器中真实的beanName(获取容器中真实beanName)(传递过来的name有三种可能,一个是原始的beanName,一个是加了&的,一个是别名。所以我们要统一将其转换 ) 。
1 | //通过三种形式获取beanName |
②执行getSingleton()方法,该方法将尝试从单例缓存集合里获取bean实例。 尝试从一级缓存(singletonObjects)中获取完备的Bean,如果没有则尝试从二级缓存earlySingletonObjects这个存储还没进行属性添加操作的Bean实例缓存中获取,如果一二级缓存都没有,查看该bean是否允许被循环引用,是则从三级缓存singletonFactories这个ObjectFactory实例的缓存里尝试获取创建此Bean的单例工厂实例,后调用工厂getObject()获取bean实例后存入二级缓存,从三级缓存中移除,返回bean。
1 | // Eagerly check singleton cache for manually registered singletons. |
1 | @Override |
1 | @Nullable |
③如果先前已经创建过单例Bean的实例,并且调用的getBean方法传入的参数为空,则执行if里面的逻辑。
1 | //如果先前已经创建过单例Bean的实例,并且调用的getBean方法传入的参数为空 |
④如果缓存中获取不到,开始Bean的创建对象流程。如果scope为prototype并且显示还在创建中,则基本是循环依赖的情况,直接抛出异常。
1 | // Fail if we're already creating this bean instance: |
⑤从当前容器中找不到指定名称的bean,此时递归去parentFactory查找。
1 | // Check if bean definition exists in this factory. |
⑥标记当前bean已经被创建。
1 | //typeCheckOnly是用来判断调用getBean()是否仅仅是为了类型检查获取bean,而不是为了创建Bean |
⑦获取Bean的定义信息。
1 | //将父类的BeanDefinition与子类的BeanDefinition进行合并覆盖 |
⑧获取当前Bean依赖的其他Bean,如果有按照getBean()把依赖的Bean先创建出来。
1 | // Guarantee initialization of beans that the current bean depends on. |
⑨启动单实例Bean的创建流程。 在这里需要注意,回调函数createBean(beanName, mbd, args)的调用发生在getSingleton()的singletonFactory.getObject()中。
1 | // Create bean instance. |
①getSingleton方法如下:
1 | public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { |
②调用AbstractAutowireCapableBeanFactory.createBean(beanName, mbd, args)。
1 | @Override |
①调用AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(beanName, mbdToUse),即让BeanPostProcessor【InstantiationAwareBeanPostProcessor】先拦截返回代理对象(此BeanPostProcessor在创建bean之前就提前执行了)。此方法先触发postProcessBeforeInstantiation(),如果有返回值则触发postProcessAfterInitialization()。
1 | @Nullable |
②如果前面的InstantiationAwareBeanPostProcessor没有返回代理对象,调用AbstractAutowireCapableBeanFactory.doCreateBean(beanName, mbdToUse, args)进入bean的正式创建流程。
①声明包装类,判断对象是否为单例对象,如果是的话,则factorybean的容器中移除掉。
1 | // Instantiate the bean. |
②利用工厂方法或者对象的构造器创建出Bean实例。即调用AbstractAutowireCapableBeanFactory.createBeanInstance(beanName, mbd, args)方法。
1 | if (instanceWrapper == null) { |
1 | protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { |
③调用AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)方法,即调用后置处理器MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName)方法,这里主要是为了后面填充Bean属性做一些前置准备,比如说@Autowrited
,@Value
, @Resource
,@Lazy
等的前置处理工作就是在这个节点上触发的。
1 | protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) { |
③将实例化好的bean包装成单例工厂添加到三级缓存中,这一步主要是处理循环依赖,同时也为我们提供了一个解决方案的切入口。
1 | boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && |
④【bean属性赋值】调用AbstractAutowireCapableBeanFactory.populateBean(beanName, mbd, instanceWrapper)方法给Bean属性赋值。
①【赋值前】判断该bean是否进行属性填充。主要是寻找所有实现了InstantiationAwareBeanPostProcessor
的实例,并访问其postProcessAfterInstantiation()
方法,如果返回的是false这跳过属性填充逻辑。
1 | //判断bean是否需要创建 |
②【赋值前】访问各个处理器获取PropertyValues(但有些处理器直接进行了填充),通过InstantiationAwareBeanPostProcessor
实例的 postProcessProperties()
方法或postProcessPropertyValues()
方法来获取PropertyValues为后续的填充属性做准备。
1 | for (BeanPostProcessor bp : getBeanPostProcessors()) { |
③【赋值中】将后置处理器返回的PropertyValues(属性的值)给bean的属性赋值。 它的填充方式是通过访问属性set方法,所以需要你保证必须有属性对应的set方法才行。
1 | if (pvs != null) { |
⑤【bean初始化】调用AbstractAutowireCapableBeanFactory.initializeBean(beanName, exposedObject, mbd)方法。
①执行Aware接口方法(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware等),即调用invokeAwareMethods(beanName, bean)。
1 | private void invokeAwareMethods(final String beanName, final Object bean) { |
②执行后置处理器初始化之前的方法,即调用applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName),即调用此方法内的postProcessBeforeInitialization()方法。其中又包含一个特例,如果有同学了解过Bean初始化的几种手段的话,应该知道一个注解@PostConstruct
,这种初始化的手段是在前置通知中完成的。实现类是CommonAnnotationBeanPostProcessor
。
1 | @Override |
③执行初始化方法,即调用invokeInitMethods(beanName, wrappedBean, mbd)。
①判断是否是InitializingBean接口的实现,执行接口规定的初始化。
1 | boolean isInitializingBean = (bean instanceof InitializingBean); |
②判断是否自定义初始化方法,执行自定义初始化方法。
1 | if (mbd != null && bean.getClass() != NullBean.class) { |
④执行后置处理器初始化之后的方法,即调用applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName),即调用此方法内的postProcessAfterInitialization()方法。
1 | @Override |
⑥注册Bean的销毁方法,即调用registerDisposableBeanIfNecessary(beanName, bean, mbd)方法。 就是看下bean是否实现了DisposableBean接口,如果有,等bean销毁的时候调用其方法。
1 | protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { |
④所有Bean都利用getBean创建完成以后,检查所有的Bean是否是实现了SmartInitializingSingleton接口的,如果是则执行afterSingletonsInstantiated()。
1 | // Trigger post-initialization callback for all applicable beans... |
打断点进入AbstractApplicationContext.finishRefresh()方法,完成BeanFactory的初始化创建工作,IOC容器就创建完成。
1 | protected void finishRefresh() { |
①清除资源缓存。
1 | public void clearResourceCaches() { |
②调用initLifecycleProcessor(),即初始化和生命周期有关的后置处理器,默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】,如果没有new DefaultLifecycleProcessor()加入到容器。
1 | protected void initLifecycleProcessor() { |
③拿到前面定义的生命周期处理器(监听BeanFactory的生命周期),回调onRefresh(),将刷新完毕事件传播到生命周期处理器。即调用getLifecycleProcessor().onRefresh()。
1 | @Override |
1 | private void startBeans(boolean autoStartupOnly) { |
④发布容器刷新完成事件,即推送上下文刷新完毕事件到相应的监听器。调用publishEvent(new ContextRefreshedEvent(this))。
1 | protected void publishEvent(Object event, @Nullable ResolvableType eventType) { |
总结Spring容器启动流程: