Spring容器初始化流程

本文详细介绍了Spring容器的初始化流程,包括初始化容器的后置处理器、注册BeanPostProcessors以及具体bean的创建过程。重点讲解了ConfigurationClassPostProcessor在处理@Configuration、@ComponentScan等注解时的角色,以及BeanDefinition的注册和Bean的创建、依赖注入的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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创建并注册:
具体的会初始化两类后置处理器

  1. BeanDefinitionRegistryPostProcessor 负责beanDefinition注册的后置处理器
  2. BeanFactoryPostProcessor 负责beanFactory容器的后置处理器

ConfigurationClassPostProcessor是BeanDefinitionRegistryPostProcessor的实现类
负责的配置类@Bean,@ComponentScan…等注解的解析封装成为beanDefinition
如果有多个BeanDefinitionRegistryPostProcessor的实现的话创建的顺序遵循

  1. 实现PriorityOrdered接口
  2. 实现Ordered接口
  3. 普通的实现类

以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(配置类的解析器)

  1. 首先看是否有贴component注解,有的话就解析当前类的内部类(内部类必须是@configuration或者@Bean才会创建)
  2. 看当前类是否有PropertySources注解,和配置文件相关的注解
  3. 看当前类是否是ComponentScans注解,解析packages,
  4. @Import ,importSelector ImportBeanDefinitionRegistrar类
  5. ImportResource类
  6. 解析@Bean
  7. 接口的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
    				}
    			}
    		}	
  1. 判断是否为factorybean?factoryBean可以看做是对Bean的一层封装,当我们在创建一些实现细节很复杂的逻辑的时候可以采用factoryBean的形式
    factoryBean的实现细节对上层不可见,我们调用applicationContext.getBean(factoryBean)的时候实际获取到的bean其实
    是factoryBean.getObject();真实对象其实是在getObject的时候才真正创建的,并将对象缓存到beanFactoryObject起来,下次再
    调用的时候直接从缓存中取。

  2. FACTORY_BEAN_PREFIX(&),标识符,当我们用applicationContext.getBean(&factoryBean)的时候获取到的
    factoryBean的实例,
    factoryBean的实例和普通bean的创建其实是一样的。
    只不过只有在调用get(factoryBean)的时候才会调用getObject方法,创建真实的实例,

  3. 普通类的创建

//直接来看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,按照创建顺序来说

  1. BeanDefinitionRegistryPostProcessor:主要是将我们要创建的bean封装成为beanDefinition的,同时也是容器最先初始化的处理器
    如:ConfigurationClassPostProcessor

  2. BeanFactoryPostProcessor:容器级别的后置处理器,主要是允许使用者修改BeanDefinition。慎用!!!

  3. 其余后置处理器:

     3.1  MergedBeanDefinitionPostProcessor 将创建好的bean和bean的属性等合并
    
     3.2  InstantiationAwareBeanPostProcessor 用于对初始化方法增强的后置处理器。
     	  提供了三个方法,postProcessBeforeInstantiation===》bean初始化方法前置增强方法,
     	  postProcessAfterInstantiation====》bean初始化方法后置增强的方法
     	  postProcessPropertyValues========》检查(required)bean属性以及赋值
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值