一、概念的理解
要知道ApplicationContext首先要知道BeanFactory。BeanFactory就是生产bean的工厂,负责生产和管理各个bean实例。而ApplicationContext就是继承自BeanFactory,有个继承结构图画的糙,但是表达很明确:
1.1 ApplicationContext
首先要对ApplicationContext进行一定了解:
- 其主要解读为应用程序上下文
-
- 对Java程序来说,在运行测试类之前,首先要先加载程序的上下文,即进行加载程序需要的“运行环境”的配置
- 对Spring来说,如果要运行TestService这个Bean,就必须首先进行Spring环境配置,以此来配置TestService的上下文环境。
- 还有很重要的一点,源码解读过后,通过对ApplicationContext的理解逐渐加深,可以看出:
-
- ApplicationContext虽然继承自BeanFactory,但是它的执行过程中始终在内部实例化了一个BeanFactory,即一个DefaultListableBeanFactory,之后与BeanFactory相关的操作,都是通过该实例处理。
- 对该部分详细内容见下方3.1最后的分析
1.2 对Bean的理解
一直在说BeanFactory就是一个Bean容器,那如何理解Bean呢?
实际上,在代码层面,对开发者自己定义的bean,会被Spring转化为一个个BeanDefinition实例并存储在BeanFactory中。BeanDefinition的实例可以保存各种Bean信息。
二、表层源码解读
先进行一个总览:
本次源码解读从ClassPathXmlApplicationContext开始,首先来看一下源码:
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
@Nullable
private Resource[] configResources;
public ClassPathXmlApplicationContext() {
}
// 可以传入一个父类ApplicationContext,进行父子关系的配置
public ClassPathXmlApplicationContext(ApplicationContext parent) {
super(parent);
}
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
this(configLocations, true, null);
}
public ClassPathXmlApplicationContext(String[] configLocations, @Nullable ApplicationContext parent)
throws BeansException {
this(configLocations, true, parent);
}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {
this(configLocations, refresh, null);
}
// 使用给定的父类创建一个新的ClassPathXmlApplicationContext,从给定的XML文件加载定义
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
// 源码见源码块一
setConfigLocations(configLocations);
// 调用refresh()方法重建 ApplicationContext,源码见源码块二:
if (refresh) {
refresh();
}
}
public ClassPathXmlApplicationContext(String path, Class<?> clazz) throws BeansException {
this(new String[] {path}, clazz);
}
public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz) throws BeansException {
this(paths, clazz, null);
}
public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
Assert.notNull(paths, "Path array must not be null");
Assert.notNull(clazz, "Class argument must not be null");
this.configResources = new Resource[paths.length];
for (int i = 0; i < paths.length; i++) {
this.configResources[i] = new ClassPathResource(paths[i], clazz);
}
refresh();
}
@Override
@Nullable
protected Resource[] getConfigResources() {
return this.configResources;
}
}
源码块一:setConfigLocations方法源码
// 传入多个配置路径,然后存储在配置文件数组中
public void setConfigLocations(@Nullable String... locations) {
if (locations != null) {
Assert.noNullElements(locations, "Config locations must not be 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;
}
}
源码块二:refresh方法源码
// 当已经创建了ApplicationContext后,可以通过refresh方法将原来的ApplicationContext销毁,然后重新执行初始化操作
@Override
public void refresh() throws BeansException, IllegalStateException {
// 给refresh操作加锁
synchronized (this.startupShutdownMonitor) {
// 为刷新上下文进行准备工作,设置它的启动日期、活动标志(即配置“已启动”状态),以及执行任何属性源的初始化。
prepareRefresh();
/**
* 源码注释:告诉子类刷新内部bean工厂
* 方法中调用refreshBeanFactory()方法进行Bean工厂的刷新,其专用于在所有初始化操作之前调用
* 然后调用getBeanFactory()方法来返回创建的新Bean工厂或者返回一个已经存在的BeanFactory
* 总:这步的主要作用是为了解析配置文件,解析为一个个Bean,然后注册到BeanFactory中
* 注意:这一步并没有进行Bean的初始化,只是提取配置信息,将其保存至注册中心
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
/**
* 源码注释:准备在上下文中使用的Bean工厂
* 该方法用于配置Bean工厂的一些内容,例如配置BeanFactory的ClassLoader,添加post-processors,以及手动注册几个特殊的Bean
* 解释下 BeanFactoryPostProcessor 和 BeanPostProcessor:
* 1、两个接口的作用相同,都是Spring的Bean后置处理器接口,用于在Bean的初始化前后提供可扩展的空间
* 2、不同点是:BeanFactoryPostProcessor是在实例化前被调用,而BeanPostProcessor是在实例化过程中使用
*/
prepareBeanFactory(beanFactory);
try {
/**
* postProcessBeanFactory()方法注释:
* 在标准初始化之后修改内部Bean工厂,此时Bean都已经被加载,但还没有实例化。
* 这步允许子类在某些ApplicationContext中注册特殊的BeanPostProcessors或者进行别的配置
*/
postProcessBeanFactory(beanFactory);
/**
* 源码注释:调用在上下文中注册为bean的工厂处理器
* 方法注释:
* 实例化并调用所有已注册的 BeanFactoryPostProcessor bean
* 如果给定顺序,则使用显式顺序注册。
* 注意:必须在单例实例化之前调用。
* 源码细节:
* 对BeanFactory进行遍历,进行addBeanPostProcessor以及setTempClassLoader
*/
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
/**
* 源码注释:注册拦截bean创建的bean处理器。
* 方法注释:实例化并注册所有 BeanPostProcessor bean,且必须在应用程序 bean 的任何实例化之前调用。
* 注意:到这里,Bean还是没有实例化
*/
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
/**
* 源码注释:初始化此上下文的消息源
* MessageSource解读:主要用于解析消息,并支持消息的参数化和国际化,这里就不做深入了解了
*/
initMessageSource();
/**
* 源码注释:为上下文初始化事件广播器(这里不展开看了)
*/
initApplicationEventMulticaster();
/**
* 源码注释:在特定的上下文子类中初始化其他特殊bean。
* 方法源码:
* 从方法源码中可以看出这是一个空实现,有点钩子方法的意思(有大佬直接解读为钩子方法,这里没理解)
* 设计模式中模板方法模式:
* 包括模板方法和基本方法(抽象方法、具体方法、钩子方法)
* 其中,钩子方法就是对于抽象方法或者接口中定义的一个方法,如果需要被调用,才设置为abstract,
* 如果不需要,则空实现,这样继承之后就不需要再实现不需要的方法了
*/
onRefresh();
/**
* 源码注释:检查侦听器bean并注册它们。(监听器不是重点)
* 方法注释:添加实现 ApplicationListener 作为侦听器的 bean。不影响其他能被添加,但不能作为bean的监听器。
*/
registerListeners();
/**
* 源码注释:实例化所有剩余的(非lazy-init)单例。
* 重点:本方法完成此上下文的bean工厂的初始化,初始化所有剩余的非lazy-init的Singleton beans
* BeanDefinition有一项配置就是void setLazyInit(boolean lazyInit);
*/
finishBeanFactoryInitialization(beanFactory);
// 最后一步:广播事件,ApplicationContext初始化完成
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁操作:销毁已经初始化的Singleton Beans,避免有些bean会一直占用资源
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
三、第二层解读——refresh
接下来再对refresh()的各个方法进行解读
3.1 第一步:创建Bean容器前的准备工作
准备工作通过prepareRefresh()方法,源码如下:
protected void prepareRefresh() {
// 记录启动时间
this.startupDate = System.currentTimeMillis();
// 配置active和closed属性
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
// Initialize any placeholder property sources in the context environment.
initPropertySources();
// 对xml配置文件进行校验
getEnvironment().validateRequiredProperties();
// 早期应用事件监听器,这个老版本的Spring是没有的
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// 早期应用事件收集器
this.earlyApplicationEvents = new LinkedHashSet<>();
}
3.2 第二步:创建Bean容器,加载并注册Bean
注意:这部分是在初始化Bean之前,进行BeanFactory的初始化以及加载和注册Bean。
首先是obtainFreshBeanFactory()方法
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 创建新的或重置已有的BeanFactory,加载和注册Bean
refreshBeanFactory();
// 将全新的BeanFactory返回
return getBeanFactory();
}
该方法最主要的步骤就是通过refreshBeanFactory()方法来创建新的或重置已有的BeanFactory,加载和注册Bean。该方法的源码:
protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
在AbstractApplicationContext中将其定义为一个抽象方法,让子类进行实现。继续找寻,从其子类AbstractRefreshableApplicationContext中找到该方法的一个实现,源码如下:
// 源码注释:
// 此实现执行此上下文的底层bean工厂的实际刷新,关闭以前的bean工厂(如果有)并为上下文生命周期的下一阶段初始化一个新的bean工厂。
@Override
protected final void refreshBeanFactory() throws BeansException {
/**
* 如果ApplicationContext已经加载过BeanFactory了,则销毁所有Bean,且关闭BeanFactory
* 解读:实际代码应用中,可以定义多个BeanFactory,但是这个判断条件只是判断当前的ApplicationContext是否有Bean工厂创建
*/
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
// BeanFactory序列化
beanFactory.setSerializationId(getId());
/**
* 设置属性:是否允许Bean覆盖,是否允许循环引用
* 针对BeanDefinition的覆盖问题:就是在配置文件中定义Bean时使用了相同的id或name
* 默认情况下,在同一配置文件中重复会报错,如果不是同一配置文件会发生覆盖
* 循环引用问题:默认是支持超过两个的bean之间循环引用
*/
customizeBeanFactory(beanFactory);
// 加载Bean到BeanFactory中
// 在AbstractXmlApplicationContext中有该函数的众多实现,很复杂
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
此处有一个细节点:为什么ApplicationContext实例化的是DefaultListableBeanFactory而不是其他的子类?
从本文最开始的BeanFactory继承图中可以看出DefaultListableBeanFactory对绝大部分子接口都有直接或间接地继承,处于最底端的它涵盖了大部分BeanFactory子接口的特有属性。
refreshBeanFactory()在关闭所有BeanFactory之后,就要对其进行重新创建和开启。其中涉及到两步关键操作:
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
首先是customizeBeanFactory(beanFactory),就是用于设置是否允许Bean覆盖和是否允许循环引用,源码如下:
// 该部分的代码很简单,只要配置中设定了该属性,if判断不为null,就会来设置Bean覆盖和循环引用
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
当然,在默认情况下,对于循环依赖而言,可以进行超过两个Bean之间的循环引用。Spring允许循环依赖的情况是不允许开发者在A类的构造方法中依赖B类,然后在B类的构造方法中再依赖A类的情况出现。
接下来就是关键的加载Bean的步骤——loadBeanDefinitions()。该方法将根据配置,加载Bean,将其放入BeanFactory中。
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
throws BeansException, IOException;
对该抽象方法找寻其主要实现,源码如下:
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {
//...
// 通过XmlBeanDefinitionReader加载bean定义
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// ①要为给定的BeanFactory创建一个新的XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// ②使用此上下文的资源加载环境配置bean定义读取器。
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// ③允许子类提供读取器的自定义初始化,然后继续实际加载bean定义
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
// 使用①创建的XmlBeanDefinitionReader加载bean。
// 注意:bean工厂的生命周期由refreshBeanFactory方法处理;因此这个方法只应该加载和注册bean定义。
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
// 初始化用于加载此上下文的 bean 定义的 bean 定义阅读器,当然主要还是用于子类复写
protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
reader.setValidating(this.validating);
}
//...
}
在loadBeanDefinitions()方法中,使用for循环不断遍历所有的resource,一个个进行配置文件读取。读取一个配置文件后,因为存在<context />、<aop />等多种标签,Spring会将所有标签绘制成DOM树,然后从树的根节点开始向下解析。读取过程从 AbstractXmlApplicationContext ——> XmlBeanDefinitionReader ——> DefaultBeanDefinitionDocumentReader。然后是解析过程,首先是<beans />标签的解析:
// 在给定的根<beans/>元素中注册每个 bean 定义。
protected void doRegisterBeanDefinitions(Element root) {
// 这里,定义parent是因为<beans />内部也是可以再定义<beans />的,需要进行递归解析
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
// 对profile属性的读取
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
preProcessXml(root);
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);
this.delegate = parent;
}
// 解析文档中根级别的元素:“import”、“alias”、“bean”
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
在bean标签的解析过程中,完成profile的读取后,又进入parseBeanDefinitions(root, this.delegate),进行解析文件中“import”、“alias”、“bean”等标签的解析。该方法内有两个分支,一个是parseDefaultElement(ele, delegate),一个是delegate.parseCustomElement(ele)。首先是parseDefaultElement方法:
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
doRegisterBeanDefinitions(ele);
}
}
从源码中可以看出,该方法主要针对import、alias、bean、beans标签进行解析。
3.2.1 bean属性注入
在这里,每个标签就不单独看了,拿出重点的bean标签作为范例,首先来看下用于解析bean标签的入口方法processBeanDefinition:
// 处理给定的 bean 元素,解析 bean 定义并将其注册到注册表
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// ele中存储着标签节点信息,将其中各种信息提取出来,然后放入BeanDefinitionHolder中
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// 解析自定义属性
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 进行bean注册
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// 注册完成后,发送注册事件
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
processBeanDefinition方法的第一步就是bean的属性解析及转换过程。
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
// 解析出两个最重要的属性:id和name
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
List<String> aliases = new ArrayList<>();
// 将name按照逗号、分号、空格进行切分,存储在字符串数组——别名列表中
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
// 规则:如果id为空,则将aliases别名列表中第一个元素作为唯一标识
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
if (logger.isTraceEnabled()) {
logger.trace("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
// 创建beanDefinition,并将bean的属性放入其中
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
// id和name都没有的话,执行if语句中的逻辑
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
beanName = this.readerContext.generateBeanName(beanDefinition);
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (logger.isTraceEnabled()) {
logger.trace("Neither XML 'id' nor 'name' specified - " +
"using generated bean name [" + beanName + "]");
}
}
catch (Exception ex) {
error(ex.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
parseBeanDefinitionElement方法最重要的两个方面:一是设定了有关如何选择唯一标识的很多规则细节,另一方面就是将bean的属性放入BeanDefinition中。
// 解析 bean 定义本身,而不考虑名称或别名。如果在解析 bean 定义期间出现问题,则可能返回null
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
try {
// 创建BeanDefinition,并设置类信息
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
// 将Bean的属性进行解析和放入BeanDefinition中
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
// 开始解析子元素,包括:meta、lookup-method、replaced-method、constructor-arg、property、qualifier
parseMetaElements(ele, bd);
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
parseConstructorArgElements(ele, bd);
parsePropertyElements(ele, bd);
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
catch (ClassNotFoundException ex) {
error("Bean class [" + className + "] not found", ele, ex);
}
catch (NoClassDefFoundError err) {
error("Class that bean class [" + className + "] depends on not found", ele, err);
}
catch (Throwable ex) {
error("Unexpected failure during bean definition parsing", ele, ex);
}
finally {
this.parseState.pop();
}
return null;
}
以上过程完成后,bean的属性就已经放入BeanDefinition中。接下来就是bean的注册过程了。
// 向给定的 bean 工厂注册给定的 bean 定义
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// 使用主名称,开始bean注册过程
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 如果有别名,还要根据别名再将bean注册一遍.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
// 首要过程就是根据主名称来进行bean注册
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
// bean名称记录,就是用于bean重名情况来进行bean覆盖操作所用
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
// 出现重名bean
if (existingDefinition != null) {
// bean覆盖没有开启的话,就会报错
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
// 用框架定义的bean覆盖用户自定义的bean
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
// 用新的bean覆盖旧的bean
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
// 同等的新bean覆盖旧的bean
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
// 没有出现重名bean
else {
// 判断是否有bean已经开始了初始化过程
if (hasBeanCreationStarted()) {
// 不能再修改启动时间集合元素(用于稳定迭代)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
// 使用ArrayList,按照bean配置的顺序保存每一个注册的bean的名字
this.beanDefinitionNames.add(beanName);
// 手动注册SingletonBean
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
// 重置bean定义缓存
resetBeanDefinition(beanName);
}
}
到这一步位置,就已经完成了bean的解析,并将bean配置转化为一个个BeanDefinition,并且完成了注册。
3.3 第三步:准备Bean容器
在完成bean的解析和初始化过后,就要执行prepareBeanFactory(beanFactory)方法来准备bean工厂
// 配置bean工厂的标准上下文特征,例如上下文的 ClassLoader 和后处理器。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置类加载器等
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 使用上下文回调配置bean工厂
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 以下依赖在自动装配时会忽略,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);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 注册早期的事件监听器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 特殊bean处理
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 如果没有配置,则手动注册默认的environment、systemProperties和systemEnvironment
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());
}
}
Bean容器准备好后,就是针对BeanFactoryPostProcessor、BeanPostProcessor等等的一系列注册以及实例化的操作。到目前为止,BeanFactory可以说已经创建完成了,并且所有实现了BeanFactoryPostProcessor和BeanPostProcessor接口的Bean也都完成了初始化。剩下没有初始化的就是Singleton Beans。
3.4 第四步:初始化所有Singleton Beans
最后的重点,就是finishBeanFactoryInitialization(beanFactory)来实例化所有剩余的没有设置懒加载的Singleton Beans。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
/**
* 转换服务:
* 使用ConversionService进行转换。其主要的使用场景是可以将前端传过来的参数转化为后端参数。
* 当后端Controller方法需要的是enum、Date等非基础类型,可以使用ConversionService进行转换
* 对ConversionService的初始化包装在beanFactory.getBean()方法中
*/
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));
}
// 如果没有bean后置处理器,则注册一个默认的解析器
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 初始化LoadTimeWeaverAware类型的beans——该部分主要是AspectJ相关内容
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用临时ClassLoader进行类型匹配
beanFactory.setTempClassLoader(null);
// 允许缓存所有bean定义元数据,而不需要进一步更改,这是初始化前最后的准备
beanFactory.freezeConfiguration();
// 开始初始化
beanFactory.preInstantiateSingletons();
}
3.4.1 bean的初始化过程
执行beanFactory.preInstantiateSingletons()开始初始化。实际的初始化是直接使用getBean()方法,而preInstantiateSingletons的其他操作主要就是针对配置了parent的父bean以及实现了SmartInitializingSingleton接口的bean进行的操作再区分。
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 初始化所有非懒加载的Singleton beans
for (String beanName : beanNames) {
// 合并parent指定的父bean的配置
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 排除abstract=true、非懒加载的Singleton bean
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 处理FactoryBean
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
// 普通Bean,直接调用getBean()方法初始化
else {
getBean(beanName);
}
}
}
// 回调实现了SmartInitializingSingleton接口的bean
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();
}
}
}
}
这里说一下FactoryBean。其适用于一个Bean的实例创建很复杂的场景。单独实现一个类来实现FactoryBean<?>接口,在这个类中对实例创建进行封装。实际注解使用过程中,@Bean注解将其看做简单的Bean即可,这样隐藏了代码细节,不需要做过多的考虑,实际效果一样的。
接下来就是bean的实例化:
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 拿到beanName
final String beanName = transformedBeanName(name);
Object bean;
// 主动检查单例缓存中是否有手动注册的单例,即检查是否已经创建过了
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 如果是普通bean,返回sharedInstance;如果是FactoryBean,返回创建的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 循环引用问题出现:如果已经创建过了beanName,抛异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 检查BeanDefinition是否存在于此容器中
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 如果不存在,就从父容器中检查
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 返回父容器的查询结果
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
// args=null代表这是一个查询请求,不需要创建bean
else if (args != null) {
// 委托给父对象,返回父容器的查询结果
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// 无参数->委托给标准getBean方法
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
// 如果typeCheckOnly为false,则将当前的beanName放入alreadyCreated集合中
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 先初始化所有depends-on中定义依赖的所有bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 循环依赖问题,报错
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册依赖关系
registerDependentBean(dep, beanName);
try {
// 初始化被依赖项
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 针对scope=singleton
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 针对scope=prototype
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 如果都不是,需要委托为专门的实现类处理
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 检查所需的类型是否与实际bean实例的类型匹配
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
上述代码中,实际创建bean的就是createBean(beanName, mbd, args)方法。而createBean()方法在AbstractBeanFactory接口中,实现该接口的就是AbstractAutowireCapableBeanFactory类。这就是@Autowire注解。
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 确保bean已经被解析
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 准备方法复写——涉及到bean标签的lookup-method属性和replaced-method属性
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 创建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
createBean()通过调用doCreateBean()来执行创建操作。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 第一步:实例化bean——此时还未填充属性
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 解决循环依赖问题
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject = bean;
try {
// 第二步:依赖注入——初始化bean实例,在这一步完成属性装配,来对实例化的bean进行赋值
populateBean(beanName, mbd, instanceWrapper);
// 第三步:执行bean的初始化方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
3.4.2 属性注入
这里又涉及到多个过程,本次主要针对属性注入来说说。该部分最主要的过程是populateBean(beanName, mbd, instanceWrapper)方法。
// 传入的mbd中存储了bean实例的所有属性
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// 在设置属性之前,给任何InstantiationAwareBeanPostProcessors机会修改bean的状态
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
// 处理自动装配类型——通过名字或者装配类型来找到所有属性值
// 注意:这里还会考虑实际的依赖关系
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 后置处理器,以@Autowired注解的形式来将属性注入bean
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 是否需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
// 如果@Autowired注解有属性值的配置,则进行处理
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 这里会处理对注解形式的注入
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
// 最后将所有得到的属性值设置给bean实例(注解的bean依赖注入除外,即主要是xml配置形式注入的属性)
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
现在使用较多的就是注解形式,对注解形式的属性注入,通过ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)。该方法的主要实现为AutowiredAnnotationBeanPostProcessor类。其中涉及到InjuctionMetadata类,其封装了依赖的bean与被依赖bean的信息。
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 定义了注入位置
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 开始注入操作
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
还有第二种就是通过xml配置形式注入的属性,通过applyPropertyValues(beanName, mbd, bw, pvs)方法注入。对xml配置形式来说,进行属性注入需要两步操作:一是需要进行转换,生成最终需要注入的类型的对象;剩下的就是进行注入操作。
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
// 配置转换,没有转换过则触发
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
// 属性名
String propertyName = pv.getName();
// 未转换前的值
Object originalValue = pv.getValue();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
// 转换后的值
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
// 转换完成
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// 属性注入,和之前的inject()方法类似
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
对转换操作来说,会根据参数类型:bean、Array、List、Set、Map、String等等不同类型进行具体的转换操作。