《Spring源码深度解析》
spring-framework-reference
前面的章节中都是以BeanFactory
接口以及它的默认实现类XmlBeanFactory
为例进行分析,
Spring中还提供了另一个接口ApplicationContext
,用于扩展BeanFactory
中现有的功能。
二者加载方式比较:
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));
ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext("beanFactoryTest.xml");
我们以ClassPathXmlApplicationContext
作为切入点,开始对整体功能进行分析。
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent){
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
设置配置路径
//org.springframework.context.support.AbstractRefreshableConfigApplicationContext
public void setConfigLocations(String[] locations) {
if (locations != null) {
this.configLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++) {
//
this.configLocations[i] = resolvePath(locations[i]).trim();
}
} else {
this.configLocations = null;
}
}
//使用环境变量中的值,替换path中特殊符号,如“$”
protected String resolvePath(String path) {
return getEnvironment().resolveRequiredPlaceholders(path);
}
如:
ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext("${xmlName}.xml");
使用命令:
java -DxmlName=beanFactoryTest xxMainClass
refresh() – AbstractApplicationContext.448
//org.springframework.context.support.AbstractApplicationContext
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//1. 准备刷新上下文环境
prepareRefresh();
//2. 初始化beanFactory,并对XML文件读取.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3. 对beanFactory进行各种填充,扩展
prepareBeanFactory(beanFactory);
//4. 子类覆盖方法做额外的处理 :: 当前为空实现。
postProcessBeanFactory(beanFactory);
//5. 执行BeanFactory各种PostProcessor处理器
invokeBeanFactoryPostProcessors(beanFactory);
//6. 注册拦截bean创建的 bean处理器,这里只是注册,真正调用是在getBean的时候。
registerBeanPostProcessors(beanFactory);
//7. 初始化上下文Message源,即不同语言的消息体(i18n)
initMessageSource();
//8. 初始化应用事件广播
initApplicationEventMulticaster();
//9. 留给子类来初始化其他bean :: 目前未空实现
onRefresh();
//10. 在所有注册bean中查找Listener bean,并注册到广播器中
registerListeners();
//11. 初始化剩下的 (non-lazy-init) 单例.
finishBeanFactoryInitialization(beanFactory);
//12. 最后:完成刷新过程,通知生命周期处理器LifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
finishRefresh();
}
}
1. prepareRefresh(); 初始化前准备
//org.springframework.context.support.AbstractApplicationContext
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
synchronized (this.activeMonitor) {
this.active = true;
}
//由子类扩展,目前实现为空:: 可在方法中进行个性化属性处理和设计
initPropertySources();
// 对所有的requiredProperties进行验证
// 通过实现ConfigurablePropertyResolver#setRequiredProperties方法,来对需要设置的requiredProperties
getEnvironment().validateRequiredProperties();
}
2. obtainFreshBeanFactory();加载BeanFactory
obtainFreshBeanFactory()
方法从字面理解是获取BeanFactory,ApplicationContext
是对BeanFactory的功能上的扩展,不但包含了BeanFactory所有的功能,还在其基础上添加了大量的扩展应用。
//org.springframework.context.support.AbstractApplicationContext
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//初始化BeanFactory,并进行xml文件读取,并将得到的BeanFactory记录在当前实体的属性中
refreshBeanFactory();
//返回当前实体的beanFactory属性
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
return beanFactory;
}
方法中核心处理逻辑委托给了refreshBeanFactory()
2.1 refreshBeanFactory
//org.springframework.context.support.AbstractRefreshableApplicationContext
@Override
protected final void refreshBeanFactory() throws BeansException {
//即判断: this.beanFactory != null,如果不为null,则需要销毁
if (hasBeanFactory()) {
//清空BeanFactory初始、实例化过程中产生的所有缓存:如singletonObjects,singletonFactorie等
destroyBeans();
//beanFactory设为null
closeBeanFactory();
}
//创建 DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//设置@Autowired 和 @Qualifier 注解解析器QualifierAnnotationAutowireCandidateResolver
customizeBeanFactory(beanFactory);
//初始化DocumentReader,并进行XML文件读取解析
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
2.1.1 customizeBeanFactory
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
//设置是否允许注册名称相同的不同bean,后一个会覆盖前一个
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
//设置是否允许循环依赖
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
//设置@Autowired 和 @Qualifier 注解的解析器QualifierAnnotationAutowireCandidateResolver
beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
}
这里扩展了AutowireCandidateResolver,
在创建bean实例属性注入时即调用
populateBean() --> autowireByType() --> resolveDependency() --> doResolveDependency()方法时
,
执行
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
默认使用的是SimpleAutowireCandidateResolver
2.1.2 loadBeanDefinitions():
//org.springframework.context.support.AbstractXmlApplicationContext
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//为指定的beanFactory 创建 XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 对BeanDefinitionReader 设置环境变量,ResourceLoader
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// 对BeanDefinitionReader进行设置,可由----子类覆盖,实现
initBeanDefinitionReader(beanDefinitionReader);
//最后执行loadBeanDefinitions()进行配置文件的读取
loadBeanDefinitions(beanDefinitionReader);
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
//读取Resource
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
//读取locations, String
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
3.prepareBeanFactory() 功能扩展
在进入prepareBeanFactory()
之前,Spring已经完成了对配置的解析,ApplicationContext在功能上的扩展在此方法内完成:
//org.springframework.context.support.AbstractApplicationContext
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置classLoader
beanFactory.setBeanClassLoader(getClassLoader());
//设置beanFactory的表达式语言处理器,默认可使用#{bean.xxx},增加对Spel表达式的支持
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
//为beanFactory增加一个默认的propertyEidtor,这个主要是对bean的属性等设置管理的一个工具
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//增加多种BeanPostProcessor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//设置几个忽略自动装配的接口 --- 在ApplicationContextAwareProcessor中已经以了如下几种Aware
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.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 增加对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()));
}
// 注册默认的系统环境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语言的支持
spring在bean进行属性进行初始化时,会进行属性的填充时,Spring会调用
populateBean()-->applyPropertyValues() --> valueResolver = new BeanDefinitionValueResolver() --> valueResolver.resolveValueIfNecessary() --> evaluate() --> beanFactory.evaluateBeanDefinitionString() -->beanExpressionResolver.evaluate()
进行属性填充,
//org.springframework.beans.factory.support.AbstractBeanFactory
protected Object evaluateBeanDefinitionString(String value, BeanDefinition beanDefinition) {
if (this.beanExpressionResolver == null) {
return value;
}
Scope scope = (beanDefinition != null ? getRegisteredScope(beanDefinition.getScope()) : null);
//调用beanExpressionResolver.evaluate()解析
return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
}
SpEL表达式以#{...}
作为界定符,所有在大括号中的字符都被认为是SpEL,
<bean id="book1" class="spring.chap06.bean.Book">
<constructor-arg name="isbn" value="isbn"/>
<constructor-arg name="name" value="name"/>
<constructor-arg name="price" value="3.1"/>
<constructor-arg name="publishDate" value="2018-12-11"/>
</bean>
<bean id="book2" class="spring.chap06.bean.Book">
<constructor-arg name="isbn" value="#{book1.isbn}"/>
</bean>
2. 增加属性注册编辑器
Spring3.x源码分析(5)-bean加载1-总体分析 TypeConverter部分。
在Spring执行createBeanInstance()
三种方式创建bean实例(BeanWrapper
)时,会调用beanFactory.initBeanWrapper(bw);
//org.springframework.beans.factory.support.AbstractBeanFactory
private final Set<PropertyEditorRegistrar> propertyEditorRegistrars =new LinkedHashSet<PropertyEditorRegistrar>(4);
protected void initBeanWrapper(BeanWrapper bw) {
bw.setConversionService(getConversionService());
//遍历 propertyEditorRegistrars 调用.propertyEditorRegistrar.registerCustomEditors()方法
registerCustomEditors(bw);
}
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
注册了在此处注册的ResourceEditorRegistrar
,注册了一系列的常用属性编辑器。
//org.springframework.beans.support.ResourceEditorRegistrar
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, 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));
}
}
3. 添加ApplicationContextAwareProcessor处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
其实就是注册了一个BeanPostProcessor
.
//org.springframework.context.support.ApplicationContextAwareProcessor
class ApplicationContextAwareProcessor implements BeanPostProcessor {
//postProcessBeforeInitialization:实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务
//为实现如下诸多Aware接口的bean,执行setXXX方法,设置相关资源.
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if(
invokeAwareInterfaces(bean);
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
}
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);
}
}
}
}
4. 设置忽略依赖Interface
在上文的ApplicationContextAwareProcessor
注册后,已经做了特殊处理,那么Spring在bean的依赖注入时,忽略他们的注入。
5. 注册特殊Dependency
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//将上面四种类型对应的bean,注册到 DefaultListableBeanFactory.resolvableDependencies属性
//用来缓存已经解析的依赖类型,当bean解析依赖时,先从此缓存中获取。
private final Map<Class<?>, Object> resolvableDependencies = new HashMap<Class<?>, Object>(16);
4.postProcessBeanFactory()
允许由子类对beanFactory进行后处理,目前为空实现。
5. invokeBeanFactoryPostProcessors(beanFactory);–激活执行BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
执行激活注册的BeanFactoryPostProcessor.
先了解下BeanFactoryPostProcessor
接口,它跟BeanPostProcessor
类似,可以对bean定义(配置元数据)进行修改(如修改bean的scope,property等..
)。Spring IoC容器允许BeanFactoryPostProcessor
在容器实际实例化任何其他bean之前读取配置元数据,并修改它。还可以使用@Ordered注解
来控制多个BeanFactoryPostProcessor
的执行顺序。
BeanFactoryPostProcessor
的作用范围是整个容器级别的,只跟使用的容器有关。
5.1 BeanFactoryPostProcessor
a.接口定义
//org.springframework.beans.factory.config.BeanFactoryPostProcessor
public interface BeanFactoryPostProcessor {
//bean定义都已加载但未实例化时执行
//允许修改bean定义的属性 ---- 如:PropertyPlaceholderConfigurer
//甚至提前初始化bean
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
b.类图
c. BeanDefinitionRegistryPostProcessor
//继承自BeanFactoryPostProcessor
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
//扩展postProcessBeanDefinitionRegistry方法
//该方法允许动态添加BeanDefinition(同样,并不会实例化),通过BeanDefinitionRegistry注册到容器内.
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
5.2 invokeBeanFactoryPostProcessors()执行BeanFactoryPostProcessor
//org.springframework.context.support.AbstractApplicationContext
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<String>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//显示注册的:BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
//显示注册的: BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
//通过调用ApplicationContext.addBeanFactoryPostProcessor()显示注册的BeanFactoryPostProcessor
for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
//执行显示注册的:BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
//获取配置文件中定义的 BeanDefinitionRegistryPostProcessor
Map<String, BeanDefinitionRegistryPostProcessor> beanMap = beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false);
//通过配置文件注册的: BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans = new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());
OrderComparator.sort(registryPostProcessorBeans);
for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {
//执行配置文件注册的:BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry(registry);
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
//执行BeanFacotryPostProcessor.postProcessBeanFactory
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
//记录已经处理过的BeanDefinitionRegistryPostProcessor(显示注册+配置文件配置) + 显示注册的BeanFactoryPostProcessor
processedBeans.addAll(beanMap.keySet());
} else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
}
//获取配置的BeanFactoryPostProcessor: 这里无需
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 根据BeanFactoryPostProcessors实现PriorityOrdered,Ordered接口,分割为3部分
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
//如果前面已经执行过,则skip....
} else if (isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
//优先执行 implement PriorityOrdered.
OrderComparator.sort(priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
//其次执行 implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
OrderComparator.sort(orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
//最后执行 未实现PriorityOrdered && 也未实现 Ordered的 BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
}
private void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
5.3 demo
- 自定义BeanDefinitionRegistryPostProcessor解析`
@Test
public void test02() {
//false: 表示不执行refresh()
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"},false);
final String beanName = "book999";
//硬编码 注册BeanFactoryPostProcessor
applicationContext.addBeanFactoryPostProcessor(new BeanDefinitionRegistryPostProcessor() {
//动态注册 beanDefinition
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(Book.class);
beanDefinition.getPropertyValues().addPropertyValue("isbn", "dynamic_isbn_999");
beanDefinition.getPropertyValues().addPropertyValue("name", "dynamic_name_999");
beanDefinition.getPropertyValues().addPropertyValue("price", 12.34d);
System.out.println("动态添加beanDefinition:"+beanDefinition.getPropertyValues());
registry.registerBeanDefinition(beanName,beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
System.out.println("修改前:"+beanDefinition);
beanDefinition.getPropertyValues().addPropertyValue("isbn", "isbn2");
System.out.println("修改后:"+beanDefinition);
}
});
//手动执行refresh()
applicationContext.refresh();
Book book1 = applicationContext.getBean(beanName, Book.class);
System.out.println(book1); // Book(isbn=isbn2, name=dynamic_name_999, price=12.34, publishDate=null)
}
2. PropertyPlaceholderConfigurer解析
a.xml配置
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:a.properties</value>
<value>classpath*:b.properties</value>
</list>
</property>
</bean>
b.源码跟踪
PropertyPlaceholderConfigurer extends PlaceholderConfigurerSupport
PlaceholderConfigurerSupport extends PropertyResourceConfigurer
PropertyResourceConfigurer extends PropertiesLoaderSupport implements BeanFactoryPostProcessor
//org.springframework.core.io.support.PropertiesLoaderSupport
public abstract class PropertiesLoaderSupport {
private Resource[] locations;
private String fileEncoding;
private PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();
protected Properties mergeProperties() throws IOException {
Properties result = new Properties();
if (this.localOverride) {
loadProperties(result);
}
//略.....
return result;
}
protected void loadProperties(Properties props) throws IOException {
if (this.locations != null) {
for (Resource location : this.locations) {
PropertiesLoaderUtils.fillProperties( props, new EncodedResource(location, this.fileEncoding), this.propertiesPersister);
}
}
}
/////////////////////////////////////////////////////////////////////////////
//org.springframework.beans.factory.config.PropertyResourceConfigurer ;
public abstract class PropertyResourceConfigurer extends PropertiesLoaderSupport
implements BeanFactoryPostProcessor, PriorityOrdered {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
try {
//调用父类:mergeProperties()方法,获取Properties
Properties mergedProps = mergeProperties();
// properties转换
convertProperties(mergedProps);
//子类实现:processProperties
processProperties(beanFactory, mergedProps);
}
catch (IOException ex) {
throw new BeanInitializationException("Could not load properties", ex);
}
}
}
public abstract class PlaceholderConfigurerSupport extends PropertyResourceConfigurer
implements BeanNameAware, BeanFactoryAware {
public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";
public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";
public static final String DEFAULT_VALUE_SEPARATOR = ":";
private String beanName;
protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
StringValueResolver valueResolver) {
BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);
String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
for (String curName : beanNames) {
// 不解析当前bean自身
// 仅解析当前beanfactory:: springmvc容器无法获取 父容器的<PropertyPlaceholderConfigurer>配置的属性,必须在mvc容器中再次配置方可使用。
if (!(curName.equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) {
BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(curName);
visitor.visitBeanDefinition(bd);
}
}
// New in Spring 2.5: resolve placeholders in alias target names and aliases as well.
beanFactoryToProcess.resolveAliases(valueResolver);
// New in Spring 3.0: resolve placeholders in embedded values such as annotation attributes.
beanFactoryToProcess.addEmbeddedValueResolver(valueResolver);
}
}
public class PropertyPlaceholderConfigurer extends PlaceholderConfigurerSupport {
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
throws BeansException {
StringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(props);
doProcessProperties(beanFactoryToProcess, valueResolver);
}
}
c. 执行时序图
6. registerBeanPostProcessors–注册BeanPostProcessor
registerBeanPostProcessors()
注册BeanPostProcessor**(注意:这里是注册并不执行)**
之前有专门章节解析BeanPostProcessor
,当时就已经提到beanfactory必须硬编码注册BeanPostProcessor
factory.addBeanPostProcessor(new XXXBeanPostProcessor());
,而ApplicationContext
则可以扫描bean容器,自动发现&&注册,就是在此方法中实现的。
由于之前已经详细的解析过BeanPostProcessor
,这里大致叙述下registerBeanPostProcessors()
执行的过程:
//org.springframework.context.support.AbstractApplicationContext
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//1. 寻找容器中的BeanPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//2. 根据不同策略:划分priorityOrderedPostProcessors
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
//3.排序,执行
OrderComparator.sort(priorityOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
//略....
}
private void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
7. initMessageSource-初始化消息资源
//org.springframework.context.support.AbstractApplicationContext
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//从容器中寻找 beanName="messageSource" 的bean
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
} else {
// else,使用默认的DelegatingMessageSource,并注册到容器中
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
//注册到容器中
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
}
}
demo
a.注册messageSource
<!-- beanname 必须为 messageSource -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<!-- basename默认从classpaths下寻找, value值不带后缀名-->
<value>m1</value>
<value>m2</value>
</list>
</property>
</bean>
b.添加属性文件
c. test
@Test
public void test03() {
ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext("applicationContext.xml");
Object args[] = new Object[]{"特朗普"};
String msg = factory.getMessage("welcome",args , Locale.CHINA); //欢迎您:特朗普
System.out.println(msg);
}
8. initApplicationEventMulticaster–初始化事件广播器
结合10.registerListeners注册监听器
一并讲解。
9. onRefresh();
模板方法,可有子类重写,用来添加特定的上下文刷新工作。当前为空实现
10. registerListeners–注册监听器
10.1 demo
a.新建事件
public class MyApplicationEnvent extends ApplicationEvent {
private String msg ;
public MyApplicationEnvent(Object source,String msg) {
super(source);
this.msg = msg;
}
public void print(){
System.out.println("事件触发:"+msg);
}
}
b.注册特定的事件监听
public class MyApplicationEnventListener implements ApplicationListener<MyApplicationEnvent> {
@Override
public void onApplicationEvent(MyApplicationEnvent event) {
System.out.println("Listener监听到:"+event+"事件");
event.print();
}
}
c.注册时间监听
<bean class="spring.chap06.listener.MyApplicationEnventListener"/>
d.发布事件
@Test
public void test04() {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
context.publishEvent(new MyApplicationEnvent("hello","trump"));
}
10.2 initApplicationEventMulticaster()–初始化广播器
//org.springframework.context.support.AbstractApplicationContext
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//自定义广播器,必须命名为 “applicationEventMulticaster”
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
} else {
//else,则使用SimpleApplicationEventMulticaster,然后注册到beanFactory中
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
}
}
a. ApplicationEventMulticaster接口定义
//org.springframework.context.event.ApplicationEventMulticaster
public interface ApplicationEventMulticaster {
//花式:添加、移除 listener监听器
void addApplicationListener(ApplicationListener listener);
void addApplicationListenerBean(String listenerBeanName);
void removeApplicationListener(ApplicationListener listener);
void removeApplicationListenerBean(String listenerBeanName);
void removeAllListeners();
//广播指定的event类型事件给特定的listeners
void multicastEvent(ApplicationEvent event);
}
b. SimpleApplicationEventMulticaster
//org.springframework.context.event.SimpleApplicationEventMulticaster
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
private Executor taskExecutor;
//listener 增加移除的方法由AbstractApplicationEventMulticaster实现,这里不再赘述
@SuppressWarnings("unchecked")
public void multicastEvent(final ApplicationEvent event) {
//遍历所有支持event类型的 listener
for (final ApplicationListener listener : getApplicationListeners(event)) {
Executor executor = getTaskExecutor();
//如果配置了 executor,则使用线程池执行
if (executor != null) {
executor.execute(new Runnable() {
public void run() {
listener.onApplicationEvent(event);
}
});
} else {
//else 直接执行
listener.onApplicationEvent(event);
}
}
}
}
10.3 registerListeners–注册监听器
//org.springframework.context.support.AbstractApplicationContext
protected void registerListeners() {
// 硬编码注册的ApplicationListener
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
//注册FactoryBeans中的ApplicationListener,这里无需初始化listener,由 post-processors初始化。
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
}
11.finishBeanFactoryInitialization–初始化非延迟加载单例
//org.springframework.context.support.AbstractApplicationContext
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//a. ConversionService设置
//CONVERSION_SERVICE_BEAN_NAME = "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));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
//Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
//b.冻结bean定义,注册的bean定义将不被允许修改或进一步处理
beanFactory.freezeConfiguration();
//c.初始化(non-lazy-init)单例--- 将所有的单例bean,提前进行实例化
beanFactory.preInstantiateSingletons();
}
这里重点分析下:
11.1 ConversionServic设置
在之前文章,讲述TypeConverter
时,有提到TypeConverter实现类 通常使用PropertyEditor来实现类型转换,而PropertyEditor不是线程安全的,所以TypeConverter也不是线程安全的。Spring提供了ConversionService()来替换PropertyEditor转换
//org.springframework.core.convert.converter.Converter
public interface Converter<S, T> {
//将源S类型转换为 目标类型T
T convert(S source);
}
//org.springframework.core.convert.ConversionService
public interface ConversionService {
//是否支持转换
boolean canConvert(Class<?> sourceType, Class<?> targetType);
boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);
<T> T convert(Object source, Class<T> targetType);
Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
}
demo
a. 定义Converter
public class String2DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
try {
return new SimpleDateFormat("yyyy-mm-dd").parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
b.注册ConversionServiceFactory(beanname必须为"conversionService")
<!-- beanname 必须为 conversionService -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="spring.chap06.converter.String2DateConverter"/>
</list>
</property>
</bean>
12. finishRefresh
finishRefresh
完成此上下文的刷新,调用LifecycleProcessor.onRefresh()
方法并发布.
//org.springframework.context.support.AbstractApplicationContext
protected void finishRefresh() {
//a.初始化LifecycleProcessor
initLifecycleProcessor();
//b.启动所有Lifecycle的bean
getLifecycleProcessor().onRefresh();
//c. 发布ContextRefreshedEvent 事件
publishEvent(new ContextRefreshedEvent(this));
//
LiveBeansView.registerApplicationContext(this);
}
12.1 initLifecycleProcessor
//org.springframework.context.support.AbstractApplicationContext
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor"
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
} else {
//默认使用: DefaultLifecycleProcessor
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
}
}
Lifecycle接口定义
它定义了三个方法,非常简单不再赘述
//org.springframework.context.Lifecycle
public interface Lifecycle {
void start();
void stop();
boolean isRunning();
}
LifecycleProcessor接口定义
//org.springframework.context.LifecycleProcessor
public interface LifecycleProcessor extends Lifecycle {
void onRefresh();
void onClose();
}
12.2 lifecycleProcessor.onRefresh()
这里以默认的DefaultLifecycleProcessor
为例,它的执行逻辑代码如下:
//org.springframework.context.support.DefaultLifecycleProcessor
public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactoryAware {
private volatile boolean running;
public void start() {
startBeans(false);
this.running = true;
}
protected Map<String, Lifecycle> getLifecycleBeans() {
Map<String, Lifecycle> beans = new LinkedHashMap<String, Lifecycle>();
//获取所有实现Lifecycle接口的beanNames
String[] beanNames = this.beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
for (String beanName : beanNames) {
//转换beanName
String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
//判断条件略.....
Lifecycle bean = this.beanFactory.getBean(beanNameToCheck, Lifecycle.class);
if (bean != this) {
beans.put(beanNameToRegister, bean);
}
}
return beans;
}
private void startBeans(boolean autoStartupOnly) {
//获取LifecycleBeans
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {
Lifecycle bean = entry.getValue();
//判断逻辑省略
int phase = getPhase(bean);
LifecycleGroup group = phases.get(phase);
group.add(entry.getKey(), bean);
}
if (phases.size() > 0) {
List<Integer> keys = new ArrayList<Integer>(phases.keySet());
Collections.sort(keys);
for (Integer key : keys) {
//LifecycleGroup.start()最终调用 doStart方法
phases.get(key).start();
}
}
}
private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {
Lifecycle bean = lifecycleBeans.remove(beanName);
//省略其他....
bean.start();
}
}
12.3 publishEvent
//org.springframework.context.support.AbstractApplicationContext
public void publishEvent(ApplicationEvent event) {
getApplicationEventMulticaster().multicastEvent(event);
if (this.parent != null) {
this.parent.publishEvent(event);
}
}