Spring Boot【原理分析】(2)——ApplicationContext
2016-12-05 17:17
435 查看
一、类结构图
二、初始化refresh
上文中refresh(context);会执行AbstractApplicationContext.refresh()。
源码:
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
1.invokeBeanFactoryPostProcessors();
有两个BeanFactoryPostProcessor
另外,从BeanFactory中获取BeanDefinitionRegistryPostProcessor
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
(1)ConfigurationClassPostProcessor先扫描现有bean中的@Configuration 类,如果为空,将不再继续扫描。如果非空,使用ConfigurationClassParser进行解析。
ConfigurationClassParser源码:
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { // Recursively process any member (nested) classes first processMemberClasses(configClass, sourceClass); // Process any @PropertySource annotations for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) { if (this.environment instanceof ConfigurableEnvironment) { processPropertySource(propertySource); } else { logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment"); } } // Process any @ComponentScan annotations AnnotationAttributes componentScan = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ComponentScan.class); if (componentScan != null && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { // The config class is annotated with @ComponentScan -> perform the scan immediately Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); // Check the set of scanned definitions for any further config classes and parse recursively if necessary for (BeanDefinitionHolder holder : scannedBeanDefinitions) { if (ConfigurationClassUtils.checkConfigurationClassCandidate(holder.getBeanDefinition(), this.metadataReaderFactory)) { parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName()); } } } // Process any @Import annotations processImports(configClass, sourceClass, getImports(sourceClass), true); // Process any @ImportResource annotations if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) { AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class); String[] resources = importResource.getAliasedStringArray("locations", ImportResource.class, sourceClass); Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader"); for (String resource : resources) { String resolvedResource = this.environment.resolveRequiredPlaceholders(resource); configClass.addImportedResource(resolvedResource, readerClass); } } // Process individual @Bean methods Set<MethodMetadata> beanMethods = sourceClass.getMetadata().getAnnotatedMethods(Bean.class.getName()); for (MethodMetadata methodMetadata : beanMethods) { configClass.addBeanMethod(new BeanMethod(me 4000 thodMetadata, configClass)); } // Process default methods on interfaces for (SourceClass ifc : sourceClass.getInterfaces()) { beanMethods = ifc.getMetadata().getAnnotatedMethods(Bean.class.getName()); for (MethodMetadata methodMetadata : beanMethods) { if (!methodMetadata.isAbstract()) { // A default method or other concrete method on a Java 8+ interface... configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } } } // Process superclass, if any if (sourceClass.getMetadata().hasSuperClass()) { String superclass = sourceClass.getMetadata().getSuperClassName(); if (!superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) { this.knownSuperclasses.put(superclass, configClass); // Superclass found, return its annotation metadata and recurse return sourceClass.getSuperClass(); } } // No superclass -> processing is complete return null; }
ConfigurationClassParser解析过程
1.子类递归
2.@PropertySource
3.ComponentScanAnnotationParser扫描所有@Component (@Configuration,@Controller,@RestController,@ControllerAdvice,@Repository,@Service)类,递归解析这些类。并注册BeanDefinition。
4.@Import
5.@ImportResource
6.@Bean
7.Interface中的@Bean
8.父类循环解析
上述解析的结果都储存在
Set<ConfigurationClass>
(2)ConfigurationClassBeanDefinitionReader解析ConfigurationClass转换为BeanDefinition,包括自身,BeanMethod,@ImportResource,@Import。
XmlBeanDefinitionReader解析@ImportResource的xml文件。并注册BeanDefinition
2.finishBeanFactoryInitialization(beanFactory);
实例化所有bean
构造完一个bean后,会用AutowiredAnnotationBeanPostProcessor检查所有@Autowired依赖属性,并构建相应的bean。
bean装载过程:
1. 实例化;
2. 设置属性值;(包括依赖注入)
3. 如果实现BeanNameAware接口,调用setBeanName设置Bean的ID或者Name;
4. 如果实现BeanClassLoaderAware接口,调用setBeanClassLoader设置ClassLoader;
5. 如果实现BeanFactoryAware接口,调用setBeanFactory 设置BeanFactory;
6. 如果实现ApplicationContextAware,调用setApplicationContext设置ApplicationContext
7. 调用BeanPostProcessor的预先初始化方法(包含@PostConstruct);
8. 调用InitializingBean的afterPropertiesSet()方法;
9. 调用定制init-method方法;
10. 调用BeanPostProcessor的后初始化方法;AOP代理类通过AspectJAwareAdvisorAutoProxyCreator生成。
初始化bean源码:
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { // Aware接口调用 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 调用BeanPostProcessor.postProcessBeforeInitialization() wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 调用InitializingBean.afterPropertiesSet() // 调用自定义init-method invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // 调用BeanPostProcessor.postProcessAfterInitialization() wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
3.finishRefresh();
调用Lifecycle.start(),更加依赖递归调用start依赖的bean。
相关文章推荐
- spring boot应用启动原理分析
- Spring Boot【原理分析】(1)——SpringApplication
- spring boot应用启动原理分析
- spring boot jar的启动原理分析
- spring boot 启动原理分析
- Spring Boot应用启动原理分析(转)
- Spring Boot实战与原理分析视频课程 共27课
- spring boot应用启动原理分析
- spring boot启动原理步骤分析
- spring boot应用启动原理分析
- Spring Boot实战与原理分析
- Spring Boot WAR包运行原理分析
- spring boot应用启动原理分析
- Spring Boot实战与原理分析视频教程
- Spring Boot 启动原理分析
- spring boot应用启动原理分析
- spring boot启动原理分析
- SpringBoot运行原理的分析:
- spring boot 运行jsp原理分析
- spring boot应用启动原理分析