4、prepareBeanFactory()
接着上篇中的内容,这个方法主要用作工厂的扩展主要做了以下的事情:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
//设置BeanFactory的classLoader为当前Context的classLoader
beanFactory.setBeanClassLoader(getClassLoader());
//1.设置BeanFactory的表达式语言处理器、默认可以使用#{bean.xxx}的形式来调用相关属性信息
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//2.添加属性注册编辑器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
//3.添加ApplicationContextAwareProcessor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//4.设置了几个忽略自动装配的接口
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
// //5.设置了几个自动装配的特殊规则
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
// 增加对AspectJ的支持
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
//添加默认的系统环境bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
1.增加SpEL表达式的功能
2.增加属性注册编辑器
3.添加ApplicationContentAwareProcessor处理器
4.设置忽略依赖
5.注册依赖
- 增加SpEl表达式的支持
Spring表达式语言全称为“Spring Expression Language”,缩写为“SpEL”,类似于Struts2x中使用的OGNL表达式语言,能在运行时构建复杂表达式、存取对象图属性、对象方法调用等等,并且能与Spring功能完美整合,如能用来配置Bean定义。可以看下我的另一篇语雀https://www.yuque.com/docs/share/42571bfe-09fd-45dd-9f05-bbb88e2d0753?# 《SPEL表达式》
在源码中我们可以看到通过代码beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()))
设置语言解析器,就可以对SpEL进行解析了。
- 增加属性注册编辑器
属性注册编辑器主要是注入时为了可以将字符串类型转化成想要的属性类型,前面介绍BeanWapper的时候也介绍过,这里主要将Spring内置的属性编辑器添加到工厂,下面来举个例子自定义一个属性编辑器:
public class UserManager {
private Date dataValue;
public Date getDataValue() {
return dataValue;
}
public void setDataValue(Date dataValue) {
this.dataValue = dataValue;
}
@Override
public String toString() {
return "UserManager{" +
"dataValue=" + dataValue +
'}';
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userManager" class="com.zp.example05.UserManager">
<property name="dataValue">
<value>2013-03-15</value>
</property>
</bean>
</beans>
public class Test01 {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("a03.xml");
UserManager userManager = (UserManager) context.getBean("userManager");
System.out.println(userManager);
}
}
比如当前UserManager
的dataValue
属性是date类型的我们在设置属性时传递了一个字符串类型那么属性注入时就会报错,而属性属性注册编辑器就是为了解决这一问题。
Spring提供了两种方式去解决这种问题:
1.使用自定义属性编辑器
public class DatePropertyEditor extends PropertyEditorSupport {
public String format="yyyy-MM-dd";
public void setFormat(String format) {
this.format = format;
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
System.out.println("text"+text);
SimpleDateFormat simpleDateFormat=new SimpleDateFormat(format);
try {
Date parse = simpleDateFormat.parse(text);
this.setValue(parse);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date" value="com.zp.example05.DatePropertyEditor"/>
</map>
</property>
</bean>
<bean id="datePropertyEditor" class="com.zp.example05.DatePropertyEditor"></bean>
2.注册Spring自带的属性编辑器
public class DatePropertyEditorRegistrar implements PropertyEditorRegistrar {
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(Date.class,new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
}
}
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="propertyEditorRegistrars">
<list>
<bean class="com.zp.example05.DatePropertyEditorRegistrar"></bean>
</list>
</property>
</bean>
这里我们回到主线beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
的代码可以看到主要是为容器添加一些属性编辑注册器,这里我们看下ResourceEditorRegistrar
中会通过registry.registerCustomEditor
注册一些属性编辑器,类似于我们自定义的配置流程让Spring在属性填充环节可以使用这些属性编辑器去进行属性的解析。
public void registerCustomEditors(PropertyEditorRegistry registry) {
ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
doRegisterEditor(registry, Resource.class, baseEditor);
doRegisterEditor(registry, ContextResource.class, baseEditor);
doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
doRegisterEditor(registry, Path.class, new PathEditor(baseEditor));
doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor));
doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));
ClassLoader classLoader = this.resourceLoader.getClassLoader();
doRegisterEditor(registry, URI.class, new URIEditor(classLoader));
doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));
doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader));
if (this.resourceLoader instanceof ResourcePatternResolver) {
doRegisterEditor(registry, Resource[].class,
new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader, this.propertyResolver));
}
}
/**
* Override default editor, if possible (since that's what we really mean to do here);
* otherwise register as a custom editor.
*/
private void doRegisterEditor(PropertyEditorRegistry registry, Class<?> requiredType, PropertyEditor editor) {
if (registry instanceof PropertyEditorRegistrySupport) {
((PropertyEditorRegistrySupport) registry).overrideDefaultEditor(requiredType, editor);
}
else {
registry.registerCustomEditor(requiredType, editor);
}
}
- 添加ApplicationContextAwareProcessor
添加了属性编辑器以后,就会通过代码beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
添加了一个Bean的后处理器ApplicationContextAwareProcessor
我们都知道Bean 的后处理器是对bean的扩展这里我们暂时不分析在何时调用主要来看下这个后处理器的功能。
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
return bean;
}
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
//这里为实现了aware的接口去注入想要的资源
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
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);
}
}
通过这个代码我们就明白添加这个后处理器可以为实现了Aware接口的类去添加想要的资源,只不过这里只是加入这个后处理器还不是调用的时候。
- 设置忽略依赖
当Spring将 ApplicationContextAwareProcessor
注册后,那么一些实现Aware接口的类已经不是普通的Bean了,所以在Spring在依赖注入的时候忽略他们。
//设置了几个忽略自动装配的接口
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
- 注册依赖
Spring中有了忽略依赖的功能,当然也会有注册依赖的功能
// //设置了几个自动装配的特殊规则
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
当注册了依赖解析后,例如当注册了对BeanFactory.class的解析依赖后,当bean的属性注入的时候,一旦检测到属性为BeanFactory类型就会将beanFactory的实例注册进去。
5、invokeBeanFactoryPostProcessors()
BeanFactory作为Spring中容器功能的基础,用于存在所有已经加载的Bean,为了保证程序的高可扩展性,Spring针对BeanFactory做了大量的扩展,BeanFactoryPostProcessor接口跟BeanPostProcessor类似。
BeanFactory的后处理主要通过两个方法postProcessBeanDefinitionRegistry()
和postProcessBeanFactory()
方法分别在BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口中并且BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor接下来我们看下这两个方法都有什么作用。
postProcessBeanDefinitionRegistry()
从名字中我们不难看出这个方法主要用作工厂后处理添加一些BeanDefinition的,下面举个例子。
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
//定义一个字符串类型的bean
AbstractBeanDefinition userNameBdf = BeanDefinitionBuilder.
genericBeanDefinition(String.class).
addConstructorArgValue("zp").
getBeanDefinition();
//将userNameBdf注册到spring容器中
registry.registerBeanDefinition("zp", userNameBdf);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
//测试
public class Test01 {
public static void main(String[] args) {
GenericApplicationContext context=new GenericApplicationContext();
context.addBeanFactoryPostProcessor(new MyBeanDefinitionRegistryPostProcessor());
context.refresh();
for (String beanDefinitionName : context.getBeanDefinitionNames()) {
System.out.println("beanDefinition=="+beanDefinitionName);
}
}
}
了解了postProcessBeanDefinitionRegistry()
的作用我们再来看下postProcessBeanFactory()
方法,这个方法主要用作beanFactory后处理时用来修改Bean的定义信息的。
<bean id="bfpp" class="com.zp.example06.ObscenityRemovingBeanFactoryPostProcessor">
<property name="obscenties">
<set>
<value>SB</value>
<value>ZZ</value>
</set>
</property>
</bean>
<bean id="simpleBean" class="com.zp.example06.SimpleBean">
<property name="name" value="sb"></property>
<property name="password" value="zz"></property>
</bean>
//这里用BeanFactoryPostProcessor作替换bean定义中的一些敏感信息
public class ObscenityRemovingBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
private Set<String> obscenties;
public ObscenityRemovingBeanFactoryPostProcessor(){
this.obscenties=new HashSet<>();
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
BeanDefinition bd = beanFactory.getBeanDefinition(beanDefinitionName);
StringValueResolver stringValueResolver = new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
if (isObscene(strVal)) return "******";
return strVal;
}
};
BeanDefinitionVisitor beanDefinitionVisitor = new BeanDefinitionVisitor(stringValueResolver);
beanDefinitionVisitor.visitBeanDefinition(bd);
}
}
public boolean isObscene(Object value){
String potentialObscenity = value.toString().toUpperCase();
return this.obscenties.contains(potentialObscenity);
}
public void setObscenties(Set<String> obscenties){
this.obscenties.clear();
for (String obscenty : obscenties) {
this.obscenties.add(obscenty.toUpperCase());
}
}
}
//测试
public class Test02 {
public static void main(String[] args) {
ConfigurableListableBeanFactory context=new XmlBeanFactory(new ClassPathResource("a06.xml"));
BeanFactoryPostProcessor bfpp = (BeanFactoryPostProcessor) context.getBean("bfpp");
//手动调用下postProcessBeanFactory
bfpp.postProcessBeanFactory(context);
System.out.println(context.getBean("simpleBean"));
}
}
这里我们主要通过postProcessBeanFactory()
方法去修改BeanDefinition中敏感的词汇。
知道了postProcessBeanDefinitionRegistry()
和postProcessBeanFactory()
的作用,回到主流程源码的invokeBeanFactoryPostProcessors()
方法中
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
//对BeanDefinitionRegistry类型的处理
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
/*1 处理手动添加的BeanFactoryPostProcessor*/
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//1.1 调用手动添加的BeanDefinitionRegistryPostProcessor, 并添加到存储它的集合中,
// 该集合名字为: registryProcessors
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
//1.2 存储手动添加的BeanFactoryPostProcessor
//该集合名称为registryProcessors
else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
// 这个list是用来存储spring内置的BeanFactoryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
/* 2 首先执行BeanDefinitionRegistryPostProcessor类型且实现了PriorityOrdered接
口的后置处理器. 默认执行spring内置BeanDefinitionRegistryPostProcessor
后置处理器(ConfigurationClassPostProcessor), 这个后置处理器执行完之后,
所有能被扫描出来的bean都以BeanDefinition的方式注册到bean工厂了
*/
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 3 紧接着执行BeanDefinitionRegistryPostProcessor类型且实现了Ordered接口的后置处理器
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
//4 最后,调用所有其他的BeanDefinitionRegistryPostProcessors直到没有其他的出现为止
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
/*
* 5 执行regularPostProcessors和registryProcessors数据结构中
BeanFactoryPostProcessor类型的后置处理器(在此处执行
ConfigurationClassPostProcessor类的postProcessBeanFactory方法, 主要是
为全配置类生成了cglib代理类的Class对象, 并修改它的beanDefinition信息为代理类的信息
* */
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
//这里是调用非手动添加的BeanFactoryPostProcessor后置处理器, 即使用了@Component注解
// 因为在上一步调用ConfigurationClassPostProcessor这种类型(BeanDefinitionRegistryBeanFactory)的后置处理器时, 对包已经扫描成功,
// 并将扫描出来的类信息封装成ScannedGenericBeanDefinition的BeanDefinition了, 所以根据类型找出的来的bean包括以注解的方式注册的
// BeanFactoryPostProcessor,但也包括ConfigurationClassPostProcessor, 因为它实现的BeanDefinitionRegistryBeanFactory接口也
// 继承了BeanFactoryPostProcessor接口
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
//解析实现了PriorityOrdered接口的BeanFactoryPostProcessor并按顺序执行
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
//解析实现了Ordered接口的BeanFactoryPostProcessor并按顺序执行
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
//调用实现了没有实现PriorityOrdered和Ordered接口的BeanFactoryPostProcessor的后置处理器
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
//清除缓存的合并bean定义,因为后处理器可能有
//修改原始元数据,例如替换值中的占位符。
beanFactory.clearMetadataCache();
通过源码我们看到以下的主体流程也比较清晰,可以分为如下的步骤:
1.调用手动添加的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法。
2.调用配置的和内置的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法,先执行PriorityOrdered接口排序的再执行order接口排序的,最后调用这两种都未实现的。
3.调用BeanDefinitionRegistryPostProcessor(包括手动添加的、配置)和BeanFactoryPostProcessor(手动添加的)的postProcessBeanFactory()方法。
4.调用BeanFactoryPostProcessor(配置的例如@Component)的postProcessBeanFactory()方法。
在上面的源代码中我们提到过Spring内置的ConfigurationClassPostProcessor工厂后处理器,这个后处理器是一个十分重要的后处理器,我们平时用到的@Configuration、@ComponentScan、@Import、@ImportResource、@PropertySource都是通过这个后处理器的postProcessBeanDefinitionRegistry()
去解析并注册到BeanDefinitionMap中,接下来我们一期来看下这个后处理器的源码。
- ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()
* Derive further bean definitions from the configuration classes in the registry.
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
//保证只被执行一次
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
//主体逻辑代码
processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
//创建存放BeanDefinitionHolder的集合
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//获取所有已经注册的BeanDefinition名称
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
/**1.这里为配置类装配configurationClass属性,并且加入到配置类集合中**/
// checkConfigurationClassCandidate()会判断一个是否是一个配置类,如果是会为BeanDefinition设置属性为lite或者full。
// 如果加了@Configuration且配置proxyBeanMethods代理为true则为full
// 如果被标注@Bean,@Component,@ComponentScan,@Import,@ImportResource这些注解,则为lite。
//lite和full均表示这个BeanDefinition对应的类是一个配置类
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
//此处主要从缓存中获取Bean名称的生成器实例
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// Parse each @Configuration class
// 解析所有加了@Configuration注解的类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
/**2.这里开始解析配置类**/
// 解析配置类,在此处会解析配置类上的注解(ComponentScan扫描出的类,@Import注册的类,以及@Bean方法定义的类)
// 注意:这一步只会将加了@Configuration注解以及通过@ComponentScan注解扫描的类才会加入到BeanDefinitionMap中
// 通过其他注解(例如@Import、@Bean)的方式,在parse()方法这一步并不会将其解析为BeanDefinition放入到BeanDefinitionMap中,而是先解析成ConfigurationClass类
// 真正放入到map中是在下面的this.reader.loadBeanDefinitions()方法中实现的
parser.parse(candidates);
// 将解析完的Configuration配置类进行校验,1、配置类不能是final,2、@Bean修饰的方法必须可以重写以支持CGLIB
parser.validate();
// 获取所有的bean,包括扫描的bean对象,@Import导入的bean对象
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
// 清除掉已经解析处理过的配置类
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
// 判断读取器是否为空,如果为空的话,就创建完全填充好的ConfigurationClass实例的读取器
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
/**3.将扫描到的所有beanDefinition注册到容器的BeanDefinitionMap中**/
// 核心方法,将完全填充好的ConfigurationClass实例转化为BeanDefinition注册入IOC容器
this.reader.loadBeanDefinitions(configClasses);
// 添加到已经处理的集合中
alreadyParsed.addAll(configClasses);
candidates.clear();
// 这里判断registry.getBeanDefinitionCount() > candidateNames.length的目的是为了知道reader.loadBeanDefinitions(configClasses)这一步有没有向BeanDefinitionMap中添加新的BeanDefinition
// 如果有,registry.getBeanDefinitionCount()就会大于candidateNames.length
// 这样就需要再次遍历新加入的BeanDefinition,并判断这些bean是否已经被解析过了,如果未解析,需要重新进行解析
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
// 如果有未解析的类,则将其添加到candidates中,这样candidates不为空,就会进入到下一次的while的循环中
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
主要逻辑分为以下四步:
1.判断是否为@Configuration、@ComponentScan、@Import、@ImportResource、@PropertySource修饰的配置类并设置好ConfigurationClass属性为full还是lite加入集合。
2.解析配置类集合中的配置类,解析被这些注解标注的类这一步只会将加了@Configuration注解以及通过@ComponentScan注解扫描的类才会加入到BeanDefinitionMap中。
3.将完全填充好的ConfigurationClass实例转化为BeanDefinition注册入IOC容器主要处理@import、@Bean等。
4.判断第三步中注入到BeanDefinitionMap中BeanDefinition是否已经被解析过,如果没有被解析过,那么需要继续解析。
- ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)
public static boolean checkConfigurationClassCandidate(
BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
// 获取bean定义信息中的class类名
String className = beanDef.getBeanClassName();
if (className == null || beanDef.getFactoryMethodName() != null) {
return false;
}
// 通过注解注入的db都是AnnotatedGenericBeanDefinition,实现了AnnotatedBeanDefinition
// spring内部的bd是RootBeanDefinition,实现了AbstractBeanDefinition
// 此处主要用于判断是否归属于AnnotatedBeanDefinition
AnnotationMetadata metadata;
if (beanDef instanceof AnnotatedBeanDefinition &&
className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
// Can reuse the pre-parsed metadata from the given BeanDefinition...
metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
}
// 判断是否是spring中默认的BeanDefinition
else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
// Check already loaded Class if present...
// since we possibly can't even load the class file for this Class.
// 如果class实例是下面四种类或接口的子类、父接口等任何一种情况,直接返回
Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||
BeanPostProcessor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
EventListenerFactory.class.isAssignableFrom(beanClass)) {
return false;
}
// 为给定类创建新的AnnotationMetadata实例,可能通过xml配置包扫描的情况
metadata = AnnotationMetadata.introspect(beanClass);
}
//如果上述两种情况都不符合
else {
try {
// 获取className的MetadataReader实例
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
// 读取底层类的完整注释元数据,包括带注解方法的元数据
metadata = metadataReader.getAnnotationMetadata();
}
catch (IOException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Could not find class file for introspecting configuration annotations: " +
className, ex);
}
return false;
}
}
// 获取bean定义的元数据被@Configuration注解标注的属性字典值
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
// 如果bean被@Configuration注解标注,且属性proxyBeanMethods为true(使用代理模式),则将bean定义记为full
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
// 如果bean被@configuration注解标注或者被注解@Component,@ComponentScan、@Import、@ImportResource或者@Bean标记的方法,则将bean定义标记为lite
else if (config != null || isConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
return false;
}
// It's a full or lite configuration candidate... Let's determine the order value, if any.
// bean定义是一个标记为full或lite的候选项,如果设置order则设置order属性值
Integer order = getOrder(metadata);
if (order != null) {
// 设置bean定义的order值
beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}
return true;
}
这个方法主要针对主体逻辑第一步,判断当前容器中的BeanDefinition是否为配置类,并且设置configurationClass属性为full或者lite,这个属性在生成代理的时候需要用到。
- ConfigurationClassParser.parse()
public void parse(Set<BeanDefinitionHolder> configCandidates) {
// 循环遍历configCandidates
for (BeanDefinitionHolder holder : configCandidates) {
// 获取BeanDefinition
BeanDefinition bd = holder.getBeanDefinition();
try {
// 根据BeanDefinition类型的不同,调用parse不同的重载方法,实际上最终都是调用processConfigurationClass()方法
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
this.deferredImportSelectorHandler.process();
}
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
// 判断是否跳过解析,基于@Conditional标签判断该对象是否要跳过
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
if (configClass.isImported()) {
if (existingClass.isImported()) {
existingClass.mergeImportedBy(configClass);
}
// Otherwise ignore new imported config class; existing non-imported class overrides it.
return;
}
else {
// Explicit bean definition found, probably replacing an import.
// Let's remove the old one and go with the new one.
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
// Recursively process the configuration class and its superclass hierarchy.
// SourceClass的意义:简单的包装类,目的是为了以统一的方式去处理带有注解的类,不管这些类是如何加载的
SourceClass sourceClass = asSourceClass(configClass, filter);
do {
// 解析各种注解
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
// 将解析的配置类存储起来
this.configurationClasses.put(configClass, configClass);
}
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
// @Configuration标注了@Component
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
// 递归处理内部类,因为内部类也是一个配置类,配置类上有@configuration注解,该注解继承@Component,if判断为true,调用processMemberClasses方法,递归解析配置类中的内部类
processMemberClasses(configClass, sourceClass, filter);
}
// Process any @PropertySource annotations
// 如果配置类上加了@PropertySource注解,那么就解析加载properties文件,并将属性添加到spring上下文中
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// Process any @ComponentScan annotations
// 处理@ComponentScan或者@ComponentScans注解,并将扫描包下的所有bean转换成填充后的ConfigurationClass
// 此处就是将自定义的bean加载到IOC容器,因为扫描到的类可能也添加了@ComponentScan和@ComponentScans注解,因此需要进行递归解析
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// 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 needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
//如果有扫描到配置类的话继续解析
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// Process any @Import annotations
// 处理@Import注解
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// Process any @ImportResource annotations
// 处理@ImportResource注解,导入spring的配置文件
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
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
// 处理加了@Bean注解的方法,将@Bean方法转化为BeanMethod对象,保存再集合中
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// Process default methods on interfaces
// 处理接口的默认方法实现,从jdk8开始,接口中的方法可以有自己的默认实现,因此如果这个接口的方法加了@Bean注解,也需要被解析
processInterfaces(configClass, sourceClass);
// Process superclass, if any
// 解析父类,如果被解析的配置类继承了某个类,那么配置类的父类也会被进行解析
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !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;
}
这里主要针对主体逻辑的第二步,这里主要对支持的各种注解进行解析,具体实现细节这里等有时间可以再一个一个看目前先了解个大概。
- ConfigurationClassBeanDefinitionReader.loadBeanDefinitions()
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
//TrackedConditionEvaluator用于条件判断@Conditional
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
// 循环调用loadBeanDefinitionsForConfigurationClass方法
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
//条件判断,某些beanDefinition在解析阶段不符合条件应当被移除
//shouldSkip会解析对配置类上的@conditional注解进行解析并调用注解中类的条件判断逻辑
if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
// 如果一个bean是通过@Import(ImportSelector)的方式添加到容器中的,那么此时configClass.isImported()返回的是true
// 而且configClass的importedBy属性里面存储的是ConfigurationClass就是将bean导入的类
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
// 判断当前的bean中是否含ImportBeanDefinitionRegistrar有@Bean注解的方法,如果有,需要把这些方法产生的bean放入到BeanDefinitionMap当中
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// 将@ImportResource引入的资源注入IOC容器
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 如果bean上存在@Import注解,且import的是一个实现了ImportBeanDefinitionRegistrar接口,
//则执行ImportBeanDefinitionRegistrar的registerBeanDefinitions()方法
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
这里针对主体逻辑第三步,将import导入的配置类的加入到BeanDefinitionMap中并且将当前配置类的BeanMethod转化为BeanDefinition。
第四步因为在postProcessBeanDefinitionRegistry()
主体逻辑代码中这里就不再次展开了主要为了进行循环处理第三步中引入的一些配置类。
6、registerBeanPostProcessors()
这个方法主要用来注册BeanPostProcessor
,这里的分析和 invokeBeanFactoryPostProcessors()
中类似,但是相比之下更加简单。因为这里不需要考虑硬编码的问题。 registerBeanPostProcessors
将 BeanPostProcessor
初始化后并将其 保存到了AbstractBeanFactory#beanPostProcessors
,方便之后对 BeanPostProcessor
的调用。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//根据类型获取所有的BeanPostProcessor名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
//注册BeanPostProcessorChecker,记录信息消息
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
//可能会有些情况当Spring 的配置中的后处理器还没有被注册就已经开始了bean的实例化,便会打印出BeanPostProcessorChecker 中设定的信息
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 保存实现了PriorityOrderd 接口的 后处理器
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 保存MergedBeanDefinitionPostProcessor 后处理器
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// 保存实现了Orderd 接口的 后处理器
List<String> orderedPostProcessorNames = new ArrayList<>();
// 保存没有实现任何排序接口的后处理器
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 按照规则筛选出不同的后处理器保存到集合中
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
// 对实现了PriorityOrderd 接口的 后处理器 进行排序
// 注册,实际上就是保存到 AbstractBeanFactory#beanPostProcessors 集合中。在getBean使用的时候直接拿取该属性即可
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
// 下面逻辑类似,注册实现order接口的后处理器
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
//注册所有常规的beanpostprocessor。
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
// 创建了 BeanPostProcessor 实例
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
// 注册MergedBeanDefinitionPostProcessor
// registerBeanPostProcessors 方法会先移除已存在的 BeanPostProcessor 随后重新加入。
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
//重新注册用于检测内部bean的后处理器为applicationlistener,
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
相较于invokeBeanFactoryPostProcessors
方法,这里并没有考虑打硬编码的后处理器的顺序问题。其原因在于invokeBeanFactoryPostProcessors
中不仅要实现BeanFactoryPostProcessor
的注册功能,还需要完成激活(执行对应方法)操作,所以需要载入配置中的定义并进行激活。而对于BeanPostProcessor
并不需要马上调用,并且硬编码方式实现的功能是将后处理器提取并调用,这里了并不需要调用,所以不需要考虑硬编码问题。这里只需要将配置文件中的BeanPostProcessor
创建之后出来并注册进行BeanFactory
中即可。需要注意 : 这里虽然没有调用 BeanPostProcessor
,但是 BeanPostProcessor
的实例已经通过 beanFactory.getBean()
创建完成。
7、initMessageSource
这个方法比较简单初始化messageSource
在上面ApplicationContext对比BeanFactroy时可以看到messageSource
主要用于解析消息,并且支持消息参数化和国际化。
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
// 获取自定义资源文件。这里可以看出使用了硬编码
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
// 如果用户没有配置,则使用默认的的资源文件
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
8、initApplicationEventMulticaster
初始化事件发布器、逻辑和initMessageSource
大体相同:
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 如果用户自定义了事件广播器,则使用用户自定义
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
// 否则使用默认的事件广播器 SimpleApplicationEventMulticaster
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
在 SimpleApplicationEventMulticaster
中有一段代码如下,可以看到,当Spring事件产生的时候,默认会使用SimpleApplicationEventMulticaster#multicastEvent
方法来广播事件,遍历所有的监听器,并使用监听器中的 onApplicationEvent 方法来进行监听事件的处理(通过 invokeListener 方法激活监听方法)。而对于每个监听器来说,其实都可以获取到产生的事件,但使用进行处理由监听器自己决定。
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
9、onRefresh()
在AbstractApplicationContext
中onRefresh
方法是空实现,作为给子类预留的扩展点,留给子类初始化其他的bean。比如在Springboot 中会刷新 调用 ServletWebServerApplicationContext#onRefresh
方法。
protected void onRefresh() {
super.onRefresh();
try {
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
在createWebServer()
中会启动Tomcat服务器
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
// 获取 webServer 工厂类,因为webServer 的提供者有多个:JettyServletWebServerFactory、TomcatServletWebServerFactory、UndertowServletWebServerFactory
ServletWebServerFactory factory = getWebServerFactory();
// 获取webserver。其中启动了tomcat
this.webServer = factory.getWebServer(getSelfInitializer());
}
else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context", ex);
}
}
// 初始化资源
initPropertySources();
}
10、registerListeners()
这个方法也比较简单,用于注册监听器和发布一些早先的监听事件。
protected void registerListeners() {
// Register statically specified listeners first.
//注册硬编码的事件发布器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
//配置文件注册的监听处理器
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
//发布之前保存的需要发布的事件
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
11、finishBeanFactoryInitialization()
这一步是整个模板方法中最重要的一步,主要做了以下几步:
1.对 ConversionService 的设置。通过 ConversionService 的配置可以很轻松完成一些类型转换工作。如果不了解ConversionService的作用可以看下这篇博https://blog.csdn.net/f641385712/article/details/90702928。
2.冻结所有的bean定义 。到这一步,也就说所有的bean定义已经定型了,不可被修改了,也正式可以缓存bean的元数据了。
3.初始化剩下的非惰性单实例。ApplicationContext 实现的默认行为就是启动时将所有单例 bean提前进行实例化。提前实例化意味着作为初始化过程的一部分,ApplicationContext 实例会创建并配置所有的单例bean。而这个实例化的过程就是在 preInstantiateSingletons 中完成的。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 是否存在硬编码的类型是 ConversionService的Bean。那么将其设置为 conversionService
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
//如果没有值解析器注册一个值解析器,用于格式为${name}的所有占位符替换为返回值
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
//初始化LoadTimeWeaverAware bean,以便尽早注册它们的转换器。
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
//getBean()
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
//冻结所有bean定义,表明已注册的bean定义,将不会被进一步修改或后处理。
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
//实例化所有剩余的(非lazy-init)单例。
beanFactory.preInstantiateSingletons();
}
在这里面,容器创建了所有的非惰性单实例(之所以不创建原型bean,是因为原型bean没必要进行缓存,每次使用直接创建即可)
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
// 获取所有 beanName
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
// 获取合并后的 BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非抽象 && 单例 && 非惰性加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判断是否是 FactoryBean 类型
if (isFactoryBean(beanName)) {
// 如果是 Factorybean 则 拼接 & 前缀获取bean
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
// 判断是否要立即初始化Bean。对于 FactoryBean,可能并不需要立即初始化其getObject 方法代理的对象。
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());
}
// 如果需要立即初始化,则初始化bean
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
// 非 FactoryBean 类型直接获取bean
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 触发所有适用bean的初始化后回调。 这里实际上是触发 SmartInitializingSingleton#afterSingletonsInstantiated 方法
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
关于实例创建(getBean)的解析由于逻辑较为复杂、也较为重要。放到了后面去解析。
12、finishRefresh
这个方法的作用也比较明了主要用于当完成这个上下文的刷新,清除一些资源缓存并且调用LifecycleProcessor的 onRefresh()方法,并发布ContextRefreshedEvent事件。
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
//清除上下文级资源缓存(例如ASM元数据扫描)。
clearResourceCaches();
// Initialize lifecycle processor for this context.
//初始化此上下文的生命周期处理器
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
//将刷新传播到生命周期处理器
getLifecycleProcessor().onRefresh();
// Publish the final event.
// 当完成ApplicationContext 初始化的时候,要通过Spring 中的事件发布机制来发出ContextRefreshedEvent 的事件,以保证对应的监听器可以做进一步的逻辑处理。
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
// 注册 ApplicationContext
LiveBeansView.registerApplicationContext(this);
}