《Spring源码深度解析》:ClassPathXmlApplicationContext初始化步骤

ClassPathXmlApplicationContext的初始化过程是调用AbstractApplicationContext#refresh()方法实现的。
1.准备工作:对系统属性及环境变量的初始化及验证。

2.初始化BeanFactory,并进行XML文件读取,将得到的BeanFactory记录在当前实体的属性中。
(1)实例化DefaultListableBeanFactory;
(2)指定序列化ID;
(3)定制BeanFactory相关属性,包括是否允许覆盖同名称的不同定义的对象(allBeanDefinitionOverriding)和是否允许bean之间循环依赖(allowCircularReference);
(4)加载BeanDefinition,初始化XmlBeanDefinitionReader,使用XmlBeanDefinitionReader读取XML;
(5)使用全局变量记录BeanFactory类实例。

3.功能拓展。
(1)增加对SPEL语言的支持。
(2)增加对属性编辑器ResourceEditorRegistrar的支持。
(3)注册ApplicationContextAwareProcessor,增加对内置类EnvironmentAware/EmbeddedValueResolverAware/ResourceLoaderAware/ApplicationEventPublisherAware/MessageSourceAware/ApplicationContextAware的信息注入。
(4)设置忽略的接口和注册固定依赖的属性。
(5)将相关环境变量及属性注册以单例模式注册。

4.调用BeanFactoryPostProcessor。
(1)调用BeanDefinitionRegistryPostProcessor子类的postProcessBeanDefinitionRegistry()方法;
(2)调用BeanDefinitionRegistryPostProcessor子类的postProcessBeanFactory()方法;
(3)调用其他BeanFactoryPostProcessor子类的postProcessBeanFactory()方法;

5.注册BeanPostPrcessor。
(1)注册所有实现PriorityOrdered的BeanPostProcessor。
(2)注册所有实现Ordered的BeanPostProcessor。
(3)注册所有无序的BeanPostProcessor。
(4)注册所有MergedBeanDefinitionPostProcessor类型的BeanPostProcessor。注册时会先移除相同的后处理器,再重新注册,保证唯一性。

6.初始化消息资源
如果Spring配置了id为messageSource的MessageSource子类,保存到AbstractApplicationContext#messageSource属性中,后面调用getMessageSource()方法可以直接获取。如果Spring没有配置,会默认实例化一个DelegatingMessageSource对象保存到AbstractApplicationContext#messageSource属性中。

7.初始化ApplicationEventMulticaster
如果用户自定义了事件广播器,那么就使用用户自定义的事件广播器;如果用户没有自定义事件广播器,那么就使用默认的SimpleApplicationEventMulticaster。

8.注册监听器

9.初始化非延迟加载单例

10.finishRefresh

对环境变量属性进行验证

AbstractApplicationContext#prepareRefresh()方法主要调用了2个方法:
(1)AbstractApplicationContext的子类可以重写父类的initPropertySources()方法,用于个性化的设置。
(2)validateRequiredProperties()方法是对属性进行验证。

protected void prepareRefresh() {
    
    
	......
	// Initialize any placeholder property sources in the context environment.
	initPropertySources();

	// Validate that all properties marked as required are resolvable:
	// see ConfigurablePropertyResolver#setRequiredProperties
	getEnvironment().validateRequiredProperties();
	......
}

定义一个子类覆盖父类的initPropertySources()方法:

public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {
    
    

    public MyClassPathXmlApplicationContext(String path) {
    
    
        super(path);
    }

    protected void initPropertySources() {
    
    
        getEnvironment().setRequiredProperties("name");
    }
}

@Test
public void testRefresh() {
    
    
    ApplicationContext applicationContext = new MyClassPathXmlApplicationContext("xml/spring.xml");
    System.out.println(applicationContext.getEnvironment().getProperty("name"));
}

抛出异常:org.springframework.core.env.MissingRequiredPropertiesException: The following properties were declared as required but could not be resolved: [name]
Spring从系统环境变量中查找name这个参数,找不到旧抛出了异常。

在IDEA中配置运行的环境变量:在这里插入图片描述
运行结果输出:liufeifei

QualifierAnnotationAutowireCandidateResolver @Autowired和@Qualifier注解

SPEL

StandardBeanExpressionResolver用来进行SPEL标签解析
AbstractAutowireCapableBeanFactory#applyPropertyValues()方法通过构造BeanDefinitionValueResolver实例进行属性值解析;通过AbstractBeanFactory的evaluateBeanDefinitionString完成SPEL解析。

protected Object evaluateBeanDefinitionString(@Nullable String value, @Nullable BeanDefinition beanDefinition) {
    
    
	if (this.beanExpressionResolver == null) {
    
    
		return value;
	}

	Scope scope = null;
	if (beanDefinition != null) {
    
    
		String scopeName = beanDefinition.getScope();
		if (scopeName != null) {
    
    
			scope = getRegisteredScope(scopeName);
		}
	}
	return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
}

属性编辑器

//AbstractApplicationContext#prepareBeanFactory()方法
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    
    
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
}

//ResourceEditorRegistrar#registerCustomEditors()方法
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));
	}
}

在bean的实例化后会调用ResourceEditorRegistrar#registerCustomEditor()方法进行批量的通用属性编辑器注册。注册后,在属性填充环节就可以直接使用这些编辑器进行属性解析。

//AbstractAutowireCapableBeanFactory#instantiateBean()方法
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
	try {
		Object beanInstance;
		if (System.getSecurityManager() != null) {
			beanInstance = AccessController.doPrivileged(
					(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
					getAccessControlContext());
		}
		else {
			beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
		}
		BeanWrapper bw = new BeanWrapperImpl(beanInstance);
		initBeanWrapper(bw);
		return bw;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
	}
}

//AbstractBeanFactory#initBeanWrapper()方法
protected void initBeanWrapper(BeanWrapper bw) {
	bw.setConversionService(getConversionService());
	registerCustomEditors(bw);
}

注册ApplicationContextAwareProcessor

ApplicationContextAwareProcessor实现了BeanPostProcessor接口。在Bean初始化过程中,会调用BeanPostProcessor#postProcessBeforeInitialization()方法和BeanPostProcessor#postProcessAfterInitialization()方法。ApplicationContextAwareProcessor没有覆写父类的postProcessAfterInitialization()方法。

如果bean是EnvironmentAware/EmbeddedValueResolverAware/ResourceLoaderAware/ApplicationEventPublisherAware/MessageSourceAware/ApplicationContextAware的子类,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 {
    
    
		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);
	}
}

设置忽略依赖

//AbstractApplicationContext#prepareBeanFactory()
//设置忽略自动装配的接口
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、ResourceLoader、ApplicationEventPublisher和ApplicationContext类型就会将beanFactory实例注入进去。
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);

调用BeanFactoryPostProessor

IOC容器允许BeanFactoryPostProessor在容器实际实例化任何其他bean之前读取配置元数据,并修改它。如果想要控制BeanFactoryPostProessor的执行顺序,在实现BeanFactoryPostProessor接口的同时,实现Ordered接口。

当Spring加载任何实现了BeanFactoryPostProcessor接口的bean的配置时,都会在bean工厂载入所有bean的配置之后执行postProcessBeanFactory方法。

PropertyResourceConfigurer实现了BeanFactoryPostProcessor接口,BeanFactory会在实例化bean之前获得配置信息,从而能够正确解析bean描述文件中的变量引用。

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
	try {
    
    
		Properties mergedProps = mergeProperties();

		// Convert the merged properties, if necessary.
		convertProperties(mergedProps);

		// Let the subclass process the properties.
		processProperties(beanFactory, mergedProps);
	}
	catch (IOException ex) {
    
    
		throw new BeanInitializationException("Could not load properties", ex);
	}
}

自定义一个BeanFactoryPostProcessor实现类,用于屏蔽敏感字段(如password)的返回值。遍历每个BeanDefinition的属性,如果属性名称在需要隐藏返回值的集合中,就返回"****",否则,不进行特殊处理。

public class ObscenityRemovingBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    

    private Set<String> obscenties;

    public void setObscenties(Set<String> obscenties) {
    
    
        this.obscenties = obscenties;
    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
        for (String beanName : beanDefinitionNames) {
    
    
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
            List<PropertyValue> propertyValueList = beanDefinition.getPropertyValues().getPropertyValueList();
            for (int i = 0; i < propertyValueList.size(); i++) {
    
    
                PropertyValue propertyValue = propertyValueList.get(i);
                String name = propertyValue.getName();
                if(obscenties.contains(name)) {
    
    
                    propertyValue.setConvertedValue("****");
                    TypedStringValue value = (TypedStringValue) propertyValue.getValue();
                    System.out.println(" value is " + value.getValue());
                    System.out.println(" convertedValue is " + propertyValue.getConvertedValue());
                }
            }
        }
    }
}

<bean class="springTest.ObscenityRemovingBeanFactoryPostProcessor" id="obscenityRemovingBeanFactoryPostProcessor">
     <property name="obscenties">
         <set>
             <value>password</value>
         </set>
     </property>
 </bean>

BeanFactoryPostProcessor调用顺序

接口BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口。

BeanFactoryPostProcessor的调用顺序如下:

(1)先调用BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry()方法。
a.如果调用AbstractApplicationContext#getBeanFactoryPostProcessors()方法获得的后处理器是BeanDefinitionRegistryPostProcessor的子类,调用postProcessBeanDefinitionRegistry()方法。
b.获取XML注册的BeanDefinitionRegistryPostProcessor子类,优先调用实现了PriorityOrdered接口的后处理器的postProcessBeanDefinitionRegistry()方法。
c.次优先调用实现了Ordered接口的后处理器的postProcessBeanDefinitionRegistry()方法。
d.最后调用其他未调用的BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry()方法。

(2)再调用BeanFactoryPostProcessor#postProcessBeanFactory()方法。
a.会先调用BeanDefinitionRegistryPostProcessor#postProcessBeanFactory()方法,包括调用AbstractApplicationContext#getBeanFactoryPostProcessors()方法获得的实现了BeanDefinitionRegistryPostProcessor接口的后处理器,以及XML注册的BeanDefinitionRegistryPostProcessor子类;
b.再调用AbstractApplicationContext#getBeanFactoryPostProcessors()方法获得的后处理器的postProcessBeanFactory()方法。
c.获取XML注册的BeanFactoryPostProcessor子类,优先调用实现了PriorityOrdered接口的后处理器的postProcessBeanFactory()方法。
d.次优先调用实现了Ordered接口的后处理器的postProcessBeanFactory()方法。
e.最后调用其他未调用的BeanFactoryPostProcessor#postProcessBeanFactory()方法。

public class ArgsBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    
    

    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    
    
        System.out.println("ArgsBeanDefinitionRegistryPostProcessor>>>postProcessBeanDefinitionRegistry");
    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("ArgsBeanDefinitionRegistryPostProcessor>>>postProcessBeanFactory");
    }
}

public class ArgsBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("ArgsBeanFactoryPostProcessor>>>postProcessBeanFactory");
    }
}

public class OrderedBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, Ordered {
    
    

    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    
    
        System.out.println("OrderedBeanDefinitionRegistryPostProcessor>>>postProcessBeanDefinitionRegistry");
    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("OrderedBeanDefinitionRegistryPostProcessor>>>postProcessBeanFactory");
    }

    public int getOrder() {
    
    
        return 0;
    }
}

public class OrderedBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {
    
    

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("OrderedBeanFactoryPostProcessor>>>postProcessBeanFactory");
    }

    public int getOrder() {
    
    
        return 0;
    }
}

public class PriorityOrderedBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
    
    

    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    
    
        System.out.println("PriorityOrderedBeanDefinitionRegistryPostProcessor>>>postProcessBeanDefinitionRegistry");
    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("PriorityOrderedBeanDefinitionRegistryPostProcessor>>>postProcessBeanFactory");
    }

    public int getOrder() {
    
    
        return 0;
    }
}

public class PriorityOrderedBeanFactoryPostProcessor implements BeanFactoryPostProcessor, PriorityOrdered {
    
    

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("PriorityOrderedBeanFactoryPostProcessor>>>postProcessBeanFactory");
    }

    public int getOrder() {
    
    
        return 0;
    }
}

public class XmlBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    
    

    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    
    
        System.out.println("XmlBeanDefinitionRegistryPostProcessor>>>postProcessBeanDefinitionRegistry");
    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("XmlBeanDefinitionRegistryPostProcessor>>>postProcessBeanFactory");
    }
}

public class XmlBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("XmlBeanFactoryPostProcessor>>>postProcessBeanFactory");
    }
}

<bean id="orderedBeanDefinitionRegistryPostProcessor"
      class="springTest.beanFactorProstProcessor.OrderedBeanDefinitionRegistryPostProcessor"></bean>
<bean id="priorityOrderedBeanDefinitionRegistryPostProcessor"
      class="springTest.beanFactorProstProcessor.PriorityOrderedBeanDefinitionRegistryPostProcessor"></bean>
<bean id="xmlBeanDefinitionRegistryPostProcessor"
      class="springTest.beanFactorProstProcessor.XmlBeanDefinitionRegistryPostProcessor"></bean>
<bean id="orderedBeanFactoryPostProcessor"
      class="springTest.beanFactorProstProcessor.OrderedBeanFactoryPostProcessor"></bean>
<bean id="priorityOrderedBeanFactoryPostProcessor"
      class="springTest.beanFactorProstProcessor.PriorityOrderedBeanFactoryPostProcessor"></bean>
<bean id="xmlBeanFactoryPostProcessor"
      class="springTest.beanFactorProstProcessor.XmlBeanFactoryPostProcessor"></bean>

 @Test
 public void tesBeanFactoryPostProcessor() {
    
    
     ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(new String[]{
    
    "xml/spring.xml"}, false, null);
     ArgsBeanFactoryPostProcessor argsBeanFactoryPostProcessor = new ArgsBeanFactoryPostProcessor();
     classPathXmlApplicationContext.addBeanFactoryPostProcessor(argsBeanFactoryPostProcessor);
     ArgsBeanDefinitionRegistryPostProcessor argsBeanDefinitionRegistryPostProcessor = new ArgsBeanDefinitionRegistryPostProcessor();
     classPathXmlApplicationContext.addBeanFactoryPostProcessor(argsBeanDefinitionRegistryPostProcessor);
     classPathXmlApplicationContext.refresh();
 }

执行结果:
ArgsBeanDefinitionRegistryPostProcessor>>>postProcessBeanDefinitionRegistry
PriorityOrderedBeanDefinitionRegistryPostProcessor>>>postProcessBeanDefinitionRegistry
OrderedBeanDefinitionRegistryPostProcessor>>>postProcessBeanDefinitionRegistry
XmlBeanDefinitionRegistryPostProcessor>>>postProcessBeanDefinitionRegistry
ArgsBeanDefinitionRegistryPostProcessor>>>postProcessBeanFactory
PriorityOrderedBeanDefinitionRegistryPostProcessor>>>postProcessBeanFactory
OrderedBeanDefinitionRegistryPostProcessor>>>postProcessBeanFactory
XmlBeanDefinitionRegistryPostProcessor>>>postProcessBeanFactory
ArgsBeanFactoryPostProcessor>>>postProcessBeanFactory
PriorityOrderedBeanFactoryPostProcessor>>>postProcessBeanFactory
OrderedBeanFactoryPostProcessor>>>postProcessBeanFactory
XmlBeanFactoryPostProcessor>>>postProcessBeanFactory

#BeanPostProcessorChecker
PostProcessorRegistrationDelegate#registerBeanPostProcessors()方法注册了BeanPostProcessorChecker。BeanPostProcessorChecker实现了BeanPostProcessor接口,覆写了父类的postProcessAfterInitialization()方法。当Spring配置的后处理器还没有被注册就开始了bean的初始化,就会打印postProcessAfterInitialization方法的日志信息。

public Object postProcessAfterInitialization(Object bean, String beanName) {
    
    
	if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) &&
			this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
    
    
		if (logger.isInfoEnabled()) {
    
    
			logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() +
					"] is not eligible for getting processed by all BeanPostProcessors " +
					"(for example: not eligible for auto-proxying)");
		}
	}
	return bean;
}

@Setter
@ToString
public class UserFactoryBean implements FactoryBean<User> {
    
    

    private String name;
    private int age;
    private Date birthday;
    private String password;

    public User getObject() throws Exception {
    
    
        User user = new User(name, age);
        return user;
    }

    public Class<?> getObjectType() {
    
    
        return User.class;
    }

    public boolean isSingleton() {
    
    
        return true;
    }

}

public class MyBeanPostProcessor implements BeanPostProcessor, Ordered {
    
    

    @Autowired
    private UserFactoryBean userFactoryBean;

    @Autowired
    private ApplicationContext applicationContext;

    public int getOrder() {
    
    
        return 0;
    }

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    
    
        System.out.println("MyBeanPostProcessor>>>postProcessBeforeInitialization>>>" + beanName);
        System.out.println("MyBeanPostProcessor>>>postProcessBeforeInitialization>>>" + userFactoryBean);
        return null;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    
    
        System.out.println("MyBeanPostProcessor>>>postProcessAfterInitialization》》" + beanName);
        System.out.println("MyBeanPostProcessor>>>postProcessAfterInitialization>>>" + userFactoryBean);
        UserFactoryBean factoryBean = new UserFactoryBean();
        factoryBean.setAge(10);
        factoryBean.setBirthday(new Date());
        factoryBean.setName("liufeifei");
        factoryBean.setPassword("123");
        return factoryBean;
    }
}

<bean id="autowiredAnnotationBeanPostProcessor" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"></bean>
<bean id="myBeanPostProcessor" class="springTest.beanPostProcessor.MyBeanPostProcessor"></bean>

MyBeanPostProcessor在属性注入的时候想要拿到一个UserFactoryBean依赖,需要提前进行初始化,这个依赖是用@Autowired解析的,如果希望得到的值不是null,需要在Spring配置中加入AutowiredAnnotationBeanPostProcessor注册。AutowiredAnnotationBeanPostProcessor实现了Priority接口,会先于自定义的MyBeanPostProcessor注册。

MessageSource

在Spring配置MessageSource,bean对应的id一定得是messageSource。

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
        <list>
            <value>properties/message/messages</value>
        </list>
    </property>
</bean>

AbstractApplicationContext#initMessageSource()方法主要功能是提取配置中定义的messageSource,并将其记录在Spring的容器中。如果没有配置资源文件,Spring提供默认的配置DelegatingMessageSource。通过读取并将自定义资源文件配置记录在容器中,就可以在获取资源文件的时候直接使用了。

常量MESSAGE_SOURCE_BEAN_NAME对应的值是messageSource,从BeanFactory中获取实例名为messageSource的MessageSource的子类。如果不存在这样的实例,Spring实例化一个DelegatingMessageSource,保存到属性messageSource中。调用getMessageSource()方法可以获得messageSource对象。

public static final String MESSAGE_SOURCE_BEAN_NAME = "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 + "]");
		}
	}
}

//AbstractApplicationContext#getMessageSource()
private MessageSource getMessageSource() throws IllegalStateException {
    
    
	if (this.messageSource == null) {
    
    
		throw new IllegalStateException("MessageSource not initialized - " +
				"call 'refresh' before accessing messages via the context: " + this);
	}
	return this.messageSource;
}

初始化ApplicationEventMulticaster

AbstractApplicationContext#initApplicationEventMulticaster()方法,

public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";

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 {
    
    
		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() + "]");
		}
	}
}

当产生Spring事件的时候会默认使用SimpleApplicationEventMulticaster的multicastEvent来广播事件,遍历所有监听器,并使用监听器中的onApplicationEvent方法进行监听器的处理。对于每个监听器都可以获取产生的事件,但是否处理则由事件监听器决定。

//SimpleApplicationEventMulticaster#multicastEvent()
@Override
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);
		}
	}
}

private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    
    
	try {
    
    
		listener.onApplicationEvent(event);
	}
	catch (ClassCastException ex) {
    
    
		String msg = ex.getMessage();
		if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
    
    
			// Possibly a lambda-defined listener which we could not resolve the generic event type for
			// -> let's suppress the exception and just log a debug message.
			Log logger = LogFactory.getLog(getClass());
			if (logger.isTraceEnabled()) {
    
    
				logger.trace("Non-matching event type for listener: " + listener, ex);
			}
		}
		else {
    
    
			throw ex;
		}
	}
}

注册监听器

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);
		}
	}
}

参考资料

spring4.1.4扩展的各种玩法之一-如何自定义系统环境变量并验证
spring4.0之后,自定义属性编辑器的配置变化
Spring IoC源码学习:invokeBeanFactoryPostProcessors 详解
注意BeanPostProcessor启动时对依赖Bean的“误伤”陷阱(is not eligible for getting processed by all…)

猜你喜欢

转载自blog.csdn.net/u012734723/article/details/109788371