Spring容器初始化流程
//容器启动类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class)
点进去可以看到有两个方法
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
//将配置类封装成为beanDefinition,然后放到DefaultListableBeanFactory容器内的
//private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);缓存中
register(annotatedClasses);
//进行容器的初始化工作
refresh();
}
具体refresh的逻辑
// Allows post-processing of the bean factory in context subclasses.
//允许在上下文子类中对bean工厂进行后处理 默认空实现
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//将工厂processors创建并注册到容器中
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//注册用于拦截bean创建的beanProcessors
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.
//初始化所有非懒加载的单利bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
//发布对应的事件
finishRefresh();
一、初始化容器的后置处理器
首先看invokeBeanFactoryPostProcessors(beanFactory)
顾名思义是将工厂相关的processors创建并注册:
具体的会初始化两类后置处理器
- BeanDefinitionRegistryPostProcessor 负责beanDefinition注册的后置处理器
- BeanFactoryPostProcessor 负责beanFactory容器的后置处理器
ConfigurationClassPostProcessor是BeanDefinitionRegistryPostProcessor的实现类
负责的配置类@Bean,@ComponentScan…等注解的解析封装成为beanDefinition
如果有多个BeanDefinitionRegistryPostProcessor的实现的话创建的顺序遵循
- 实现PriorityOrdered接口
- 实现Ordered接口
- 普通的实现类
以PriorityOrdered举例:
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//如果是实现PriorityOrdered的话,
//beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)
//创建bean,getBean方法后续再说。。。。。
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
可以看到ConfigurationClassPostProcessor就是实现了PriorityOrdered的
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware
创建好了processor之后循环遍历postProcessBeanFactory方法
以ConfigurationClassPostProcessor举例:
ConfigurationClassPostProcessor中有个ConfigurationClassParser(配置类的解析器)
- 首先看是否有贴component注解,有的话就解析当前类的内部类(内部类必须是@configuration或者@Bean才会创建)
- 看当前类是否有PropertySources注解,和配置文件相关的注解
- 看当前类是否是ComponentScans注解,解析packages,
- @Import ,importSelector ImportBeanDefinitionRegistrar类
- ImportResource类
- 解析@Bean
- 接口的default方法 java8
//上述所有操作判断需要创建的bean的话都会封装成为一个ConfigurationClass类,并放入集合中。而componentScan扫描到的
类会直接同时封装成为一个definitionHolder并并调用registerBeanDefinition(definitionHolder, this.registry);
存放到map容器Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256)中
,解析完成之后调用this.reader.loadBeanDefinitions(configClasses);将这些bean按照类型不同
if (configClass.isImported()) {//若是import,封装成为BeanDefinition,并注册
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
//若是@Bean,封装成为BeanDefinition,并注册
loadBeanDefinitionsForBeanMethod(beanMethod);
}
//若是@importedResources封装成为BeanDefinition并注册
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
//若是实现ImportBeanDefinitionRegistrar类封装成为BeanDefinition并注册
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
二、registerBeanPostProcessors
顾名思义是注册创建拦截bean创建的processors:
这里的创建逻辑其实和上一步的逻辑一致,只是创建的是BeanPostProcessor的实现类。我们如果有需要在bean的初始化之前和之后做一些增强操作
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName+"----postProcessBeforeInitialization");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName+"----postProcessAfterInitialization");
return bean;
}
}
三、我们来看下具体bean的创建流程
//初始化所有非懒加载的单利bean
finishBeanFactoryInitialization(beanFactory);
我们看下这步操作之前的结果
所有的beanProcessors都已经创建完成,并放入集合中存储List beanPostProcessors = new CopyOnWriteArrayList<>();
所有需要创建的bean都会被封装成为beanDefinition并放入map集合中
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
所以我们可以知道spring保持单例的机制就是基于map。
//好了继续
回到finishBeanFactoryInitialization方法,内部真实调用的方法为:
// Instantiate all remaining (non-lazy-init) singletons.实例所有非懒加载的单例bean,多例实在调用getBean的时候才会创建实例
beanFactory.preInstantiateSingletons();
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) { -------------------------------------1
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); -------2
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);----------------------------------------------3
}
}
}
-
判断是否为factorybean?factoryBean可以看做是对Bean的一层封装,当我们在创建一些实现细节很复杂的逻辑的时候可以采用factoryBean的形式
factoryBean的实现细节对上层不可见,我们调用applicationContext.getBean(factoryBean)的时候实际获取到的bean其实
是factoryBean.getObject();真实对象其实是在getObject的时候才真正创建的,并将对象缓存到beanFactoryObject起来,下次再
调用的时候直接从缓存中取。 -
FACTORY_BEAN_PREFIX(&),标识符,当我们用applicationContext.getBean(&factoryBean)的时候获取到的
factoryBean的实例,
factoryBean的实例和普通bean的创建其实是一样的。
只不过只有在调用get(factoryBean)的时候才会调用getObject方法,创建真实的实例, -
普通类的创建
//直接来看bean的创建流程
org.springframework.beans.factory.support.AbstractBeanFactory
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
bean的创建底层是采用的反射,找到bean定义的构造器,如果没有的话就采用无参构造
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
创建好的bean会存放到单例bean 的map中Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);,其实我们调用context.getBean(class)其实现逻辑也是从这个map中通过key找到object
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
当我们将bean创建完成之后,
当bean创建完成了之后就开始bean的依赖注入与初始化工作了。首先会先经过mergeBeanDefinitionPostProcessor的后置处理,
这个后置处理主要的作用是对我们创建好的bean的依赖注入进行支持,将我们的依赖封装成为InjectionMetadata,并缓存起来。
我们以对@autowired和@value提供支持的AutowiredAnnotationBeanPostProcessor为例
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
ReflectionUtils.doWithLocalFields(targetClass, field -> {
//遍历所有的field,找到带有@autowired和@value的字段,然后封装成为AutowiredFieldElement
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
//找到所有方法带有@autowired和@value的方法,然后封装成为AutowiredMethodElement
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
//最终将所有的方法和字段封装成为InjectionMetadata返回
return new InjectionMetadata(clazz, elements);
}
最终将返回的InjectionMetadata放到缓存中this.injectionMetadataCache.put(cacheKey, metadata);
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);//bean的属性赋值
exposedObject = initializeBean(beanName, exposedObject, mbd);//调用bean的初始化方法
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
populateBean对bean的属性注入,完成我们的di操作,我们看下比较常见三种属性的注入,以OrderController为例:
@Controller
public class OrderController implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Autowired
private OrderService orderService;
@Value("${server.port}")
private String port;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
可以看到OrdrController中有@autowired注入,以及@value还有就是实现了applicatonContext接口,会自动将容器对象注入当前bean中
属性的注入也是后置处理器作用的,InstantiationAwareBeanPostProcessor接口的子类,AutowiredAnnotationBeanPostProcessor同时也是InstantiationAwareBeanPostProcessor的子类
调用postProcessProperties,首先会去缓存中查询InjectionMetadata,若没有缓存则会重新走封装InjectionMetadata流程,然后对bean执行属性注入操作。
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//找到对应的注解
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//属性注入方法,具体逻辑是解析属性类调用反射的field.set(bean, value);来对属性赋值
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
ApplicationContextAware接口并不是在populateBean接口中完成的,而是在initializeBean(bean)中调用的
我们看下具体的实现逻辑:
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
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()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
首先执行beanPostProcessors的初始化前置处理方法,在前置处理方法的实现逻辑非常简单,就是遍历所有的processors的
postProcessBeforeInitialization()方法。我们自定义的beanPostProcessor被调用执行前置和后置的方法
ApplicationContextAware对应的Processor为ApplicationContextAwareProcessor
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
//最终调用我们实现的setApplicaitonContext方法将容器对象设置到bean中
}
初始化方法是我们在@Bean(initMethod = “init”,destroyMethod = “destroy”)中定义的init方法
初始化后置方法和前置方法逻辑相似,同样是在遍历处理器的过程中调用后置处理方法。这里略过。
简单说下spring内部的beanPostProcessor,按照创建顺序来说
-
BeanDefinitionRegistryPostProcessor:主要是将我们要创建的bean封装成为beanDefinition的,同时也是容器最先初始化的处理器
如:ConfigurationClassPostProcessor -
BeanFactoryPostProcessor:容器级别的后置处理器,主要是允许使用者修改BeanDefinition。慎用!!!
-
其余后置处理器:
3.1 MergedBeanDefinitionPostProcessor 将创建好的bean和bean的属性等合并 3.2 InstantiationAwareBeanPostProcessor 用于对初始化方法增强的后置处理器。 提供了三个方法,postProcessBeforeInstantiation===》bean初始化方法前置增强方法, postProcessAfterInstantiation====》bean初始化方法后置增强的方法 postProcessPropertyValues========》检查(required)bean属性以及赋值