主要步骤:初始化listeners、环境信息初始化、创建和初始化context
一、初始化listeners
F:\mvnRespo\org\springframework\boot\spring-boot\1.5.2.RELEASE\spring-boot-1.5.2.RELEASE.ja#/META-INF/spring.factories
F:\mvnRespo\org\springframework\boot\spring-boot-autoconfigure\1.5.2.RELEASE\spring-boot-autoconfigure-1.5.2.RELEASE.jar#/META-INF/spring.factories
org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(ConfigurableEnvironment)
二、主要的listerners
org.springframework.boot.context.config.ConfigFileApplicationListener
org.springframework.boot.context.config.ConfigFileApplicationListener.onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent)
同时,此处会调用loader读取本地配置文件:
org.springframework.boot.context.config.ConfigFileApplicationListener.Loader.Loader(ConfigFileApplicationListener, ConfigurableEnvironment, ResourceLoader)
最终通过配置的PropertySourcesLoader.load()获取本地配置文件中的配置
三、创建context
org.springframework.boot.SpringApplication.createApplicationContext()
1、构造方法
org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext.AnnotationConfigEmbeddedWebApplicationContext()
2、创建各种预定义的PostProcessor和DefaultListableBeanFactory
ConfigurationClassPostProcessor:@Configuration
AutowiredAnnotationBeanPostProcessor:@Autowired、@Value、@Inject、@Lookup
RequiredAnnotationBeanPostProcessor:@Required
CommonAnnotationBeanPostProcessor:@PostConstruct、@PreDestroy、@Resource、@WebServiceRef、@EJB
PersistenceAnnotationBeanPostProcessor:@PersistenceContext、@PersistenceUnit
EventListenerMethodProcessor:@EventListener
DefaultEventListenerFactory:@EventListener
AnnotationAwareOrderComparator:@Order
ContextAnnotationAutowireCandidateResolver:@Lazy、@Qualifier、@Value
3、初始化
org.springframework.boot.SpringApplication.prepareContext(ConfigurableApplicationContext, ConfigurableEnvironment, SpringApplicationRunListeners, ApplicationArguments, Banner)
以springcloud-config为例:
读取远程配置完成
注意:通过springcloud-config获取配置时,不会通过org.springframework.boot.env.PropertiesPropertySourceLoader解析。
org.springframework.cloud.config.client.ConfigServicePropertySourceLocator.locate(Environment)获取远程仓库中的配置(具体看springcloud-config源码)
3、最重要部分
org.springframework.boot.SpringApplication.refreshContext(ConfigurableApplicationContext)
org.springframework.boot.SpringApplication.refresh(ApplicationContext)
org.springframework.context.support.AbstractApplicationContext.refresh()
调用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors通过该方法实现调用各个PostProcessor实现对beans的定义(bean的元信息,非初始化,没有生成实例):
主要在ConfigurationClassPostProcessor调用
org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)
org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(BeanDefinitionRegistry)
org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List<BeanFactoryPostProcessor>)
org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor>, BeanDefinitionRegistry)
org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)
org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(BeanDefinitionRegistry)
来源:
org.springframework.boot.SpringApplication.prepareContext(ConfigurableApplicationContext, ConfigurableEnvironment, SpringApplicationRunListeners, ApplicationArguments, Banner)
org.springframework.boot.SpringApplication.load(ApplicationContext, Object[])
org.springframework.boot.BeanDefinitionLoader.load()
org.springframework.boot.BeanDefinitionLoader.load(Object)
sources为刚开始public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
org.springframework.context.annotation.ConfigurationClassParser.parse(Set<BeanDefinitionHolder>)
org.springframework.context.annotation.ConfigurationClassParser.parse(AnnotationMetadata, String)
org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClass)
然后通过解析最开始传入的sources(启动类类名),通过
org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClass, SourceClass)解析出@PropertySource、@ComponentScan、@Import、@ImportResource、@Bean注解的类获取注册更多的beanName
1、org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClass, SourceClass)---》
2、org.springframework.context.annotation.ComponentScanAnnotationParser.parse(AnnotationAttributes, String)-----------------》3、org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(String...)
Set<BeanDefinitionHolder> scannedBeanDefinitions =this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
scanner.doScan(StringUtils.toStringArray(basePackages));
定义注册Bean:
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);将定义封装成一个ScopedProxyFactoryBean对象的声明(scoped proxy definition),并注册实际targetbean的声明并通过registerBeanDefinition(definitionHolder, this.registry);注册到上下文的工厂对象中
org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(String, BeanDefinition)
在getBean的时候并不会马上实例化targetbean,而是生成一个ScopedProxyFactoryBean对象
findCandidateComponents(String basePackage)
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
配置扫描到的配置类上属性注解:@Lazy、@Primary、@DependsOn、@Role、@Description到配置类上
org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor>, BeanDefinitionRegistry)会被多次调用去处理不同类型的PostProcessor
refresh:registerBeanPostProcessors(beanFactory)
org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(ConfigurableListableBeanFactory, AbstractApplicationContext)
org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh()---->org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer()
refresh:finishBeanFactoryInitialization(beanFactory);
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons()
(注:在@configuration配置类中,如果有@bean注解的方法,则改配置类作为@BEan对应方法的工厂)
// 获取FactoryBean实例,FactoryBean的定义beanName前面会加一个&符号
方法中最重要的逻辑在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(String)----》org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(String, Class<T>, Object[], boolean)-----》
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])-----------》>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(String, RootBeanDefinition, Object[])
instantiateUsingFactoryMethod(String, RootBeanDefinition, Object[])
这段代码之后就是解析在factory的类中获取某个bean实例的方法,通过反射执行该方法,以方法名作为beanName
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(String, RootBeanDefinition)
实例化完成后回到org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(String, RootBeanDefinition, Object[])
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(String, RootBeanDefinition, BeanWrapper)属性注入
@Scope注解的bean,在其他类中@autowired的时候,注入的是从之前的beanName生成的对应的ScopeProxyFactoryBean中getObject()出来的代理,并不是真正初始化的bean,只有单例非懒加载的bean才是注入实例化的bean。
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(PropertyValues, PropertyDescriptor[], Object, String)调用PostProcessor完成注入
org.springframework.beans.factory.annotation.InjectionMetadata.inject(Object, String, PropertyValues)
分成员注入和方法注入两种方式,以成员注入为例:
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement.inject(Object, String, PropertyValues)
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DependencyDescriptor, String, Set<String>, TypeConverter)
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DependencyDescriptor, String, Set<String>, TypeConverter)
1、获取需要注入的bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
addCandidateEntry(Map<String, Object>, String, DependencyDescriptor, Class<?>)
org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(String, Class<?>, BeanFactory)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(String, Class<T>)
org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(Object, String, String, RootBeanDefinition)
也就是说,当注入的bean的scope属性不为singlon的时候,是从之前实例化的beanName对应的ScopeProxyFactoryBean获取的Proxy对象,真正的bean此时还没有完成实例化
Aware初始化:
RootBeanDefinition)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(String, Object)完成实现了Aware接口的重写方法(@overwrite)的反射执行
主要调用
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(Object, String)
至此,非懒加载且scope为单例的bean完成实例化初始化
finishRefresh()
org.springframework.context.support.AbstractApplicationContext.finishRefresh()
发布上下文更新事件
publishEvent(new ContextRefreshedEvent(this));
以@RefreshScope为例:此时完成bean的实例化初始化(Bean的scope属性跟当前RefreshScope实例的scope属性值相等的)
org.springframework.cloud.context.scope.refresh.RefreshScope.start(ContextRefreshedEven
懒加载第一次调用实例化
org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor.intercept(Object, Method, Object[], MethodProxy)(这个类怎么进来?应该要看spring AOP源码)此处拦截方法调用
org.springframework.aop.target.SimpleBeanTargetSource.getTarget()
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(String)
剩下的流程就跟上面的流程差不多了,由于getBean()方法里不会有判断Lazy的地方,所有执行的都会生成实例并初始化
在springcloud config执行了refresh之后,不管scope属性是不是scope,不管是不是懒加载,都在第一次调用方法时被org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor.intercep拦截后才重新生成实例
beanName取值方式
1、@configuration,@compenent,@sprintApplication等注解的类
org.springframework.context.annotation.AnnotationBeanNameGenerator.generateBeanName(BeanDefinition, BeanDefinitionRegistry)
2、@bean注解的方法
org.springframework.context.annotation.ConfigurationClassEnhancer.BeanMethodInterceptor.intercept(Object, Method, Object[], MethodProxy)
关于应用中有同名的实例时,spring的默认策略是后者覆盖前者
org.springframework.context.annotation.ConfigurationClassEnhancer.BeanMethodInterceptor.intercept(Object, Method, Object[], MethodProxy)后半部分
此处的beanFactory即下面的DefaultListableBeanFactory
或者org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(String, BeanDefinition)
关于@ComponentScan和spring.factories的定义先后顺序,以及条件注解判断时机
检测到@EnableAutoConfiguration注解后调用EnableAutoConfigurationImportSelector,此时的调用和上面@CompentScan的执行不在同一个方法栈,由于EnableAutoConfigurationImportSelector继承AutoConfigurationImportSelector且实现order接口org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getOrder()(值为Ordered.LOWEST_PRECEDENCE - 1),因此,在@CompentScan扫描完其他的注解后,才开始通过ImportSelector读取spring.factories文件,结果是直接扫描的@configuration要比配置在spring.factories里的要先定义(非实例化)。
条件注解:
org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(BeanDefinitionRegistry)
org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(Set<ConfigurationClass>)
org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClass, TrackedConditionEvaluator)
最后通过org.springframework.context.annotation.ConditionEvaluator.shouldSkip(AnnotatedTypeMetadata, ConfigurationPhase)完成条件注解的判断逻辑。
因此如果@CompentScan扫描的@configuration上的条件注解的条件是配置在spring.factories的bean,那在定义spring.factories的bean之前,已经完成了对@CompentScan扫描的bean的定义,并且已经完成条件注解的过滤,此时在@CompentScan扫描的@configuration上的条件注解无效。
参考
http://m.blog.csdn.net/u013510838/article/details/75126299
http://www.cnblogs.com/dylan-java/p/7468336.html
http://blog.csdn.net/linuu/article/details/50865358
http://www.cnblogs.com/xrq730/p/6361578.html
http://www.cnblogs.com/xrq730/p/6363055.html