阿里巴巴官方技术号,关于阿里的技术创新均将呈现于此 |
|
阿里开发者 · 微调碾压RAG?大模型意图识别工程化实践 · 昨天 |
|
白鲸出海 · 专注被美图“抛弃”的女性变美赛道,这家公司扭 ... · 2 天前 |
|
腾讯 · 初八,开工大吉! · 3 天前 |
|
阿里开发者 · 从铜线到云端:网络技术的跨越与未来趋势 · 3 天前 |
|
百度智能云 · 国内首个!百度成功点亮昆仑芯三代万卡集群,将 ... · 4 天前 |
阿里妹导读
一、问题
5、 Spring 容器设计思想?
二、关键词
三、全文概要
Spring 容器本质上就是一个存放了一个个描述不同对象属性和方法的定义单元,需要使用的时候就通过反射机制把对象创建好,再将描述的属性初始化。其中涉及了一系列精妙的设计模式和实现思路,这给我们写标准的优质代码提供了绝佳的模板。本文力求讨论 Spring 容器最核心的机制,用最少的代码讲清楚 Spring 容器的本质。
四、架构
4.1 Spring 整体架构
上图是 Spring 框架的整体架构,从架构图我们可以看出来 Spring 的根基就是core container,就是我们说的IOC容器。在此基础上才有AOP,DATA和WEB的繁荣,本章我们讨论的是 Spring 家族 的基石, Spring 容器,也就是我们上文提到的IOC容器。所有其他的 Spring 组件都是在容器上构建出来的,所以我们暂时去掉所有其他的组件功能介绍,只讨论IOC容器。
Spring 容器最核心的三个jar包是bean,context,core。bean是 Spring 基石,一切皆为bean,context维护了应用的上下文,如果bean是演员,那么context就是舞台,而core则是道具。
4.1 上下文ApplicationConext
publicinterfaceApplicationContextextendsEnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver{
String getId();
String getApplicationName();
String getDisplayName();
longgetStartupDate();
ApplicationContext getParent();
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
ConfigurableApplicationContext:继承了生命周期管控能力,同时继承ApplicationConext,拓展了context的环境,事件等写的属性。
AbstractApplicationContext:大部分的能力在该类定义实现,该类继承类加载能力接口DefaultResourceLoader和读写context的ConfigurableApplicationContext,ioc容器启动的流程详细解析该类。
GenericApplicationContext:通用上下文。
AnnotationConfigApplicationContext:注解可配置上下文。
GenericGroovyApplicationContext:groovy配置文件上下文。
GenericXmlApplicationContext:通用xml配置文件上下文。
StaticApplicationContext:消息可读取上下文。
AbstractRefreshableApplicationContext:可刷新可配置化上下文。
AbstractRefreshableConfigApplicationContext:可刷新可配置化上下文。
AbstractXmlApplicationContext:xml配置文件类型的上下文。
ClassPathXmlAp-plicationContext:终端类路径xml上下文。
FileSystemXmlApplicationContext:文件系统xml上下文。
4.2 BeanFactory
Spring 的世界一切皆为bean。
BeanDefinitionRegistry: 定义
DefaultListableBeanFactory这个收敛了所以上层的能力,具体包含核心的BeanDefinitionRegistry和BeanFactory,也就是bean的定义和生产bean的工厂。
五、过程
容器启动核心过程如下图,包含容器读取配置文件后创建对象,然后对象属性初始化的过程:
5.1 启动容器
我们要探究 Spring 最核心的容器原理,就要先排除其他高级属性的干扰,只依赖最少的jar包来构建工程,然后一步步跟踪容器启动的过程。
构建工程:新建java工程,引入最少所需依赖的 Spring 包;
新建测试启动类Application
package com.alibaba.spring;
import com.alibaba.spring.beans.Producer;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Lin ZhenHua
*/
public class Application{
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Producer producer = context.getBean(Producer.class);
System.out.println("running the test case with name = " + producer.getCount());
}
}
新建spring配置文件
"1.0" encoding="UTF-8"?>
"http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
"producer" class="com.alibaba.spring.beans.Producer">
"count" value="10" />
执行结果
七月 10, 2018 11:31:16 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5197848c: startup date [Tue Jul 10 11:31:16 CST 2018]; root of context hierarchy
七月 10, 2018 11:31:17 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
running the test case with name = 10
经过以上几个步骤,我们成功地将配置文件里面描述的对象,通过 Spring 的IOC容器创建了出来,而且不需要再使用new的形式来创建对象,下面我们将深入解析IOC容器的工作流程。
5.2 入口
创建 Spring 容器上下文对象,调用ClassPathXmlApplicationContext构造函数,传入配置文件路径参数;
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
/**
* loading the definitions
* from the given XML file and automatically refreshing the context
*/
publicClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
publicClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh(); //核心方法
}
}
调用refresh()方法启动IOC容器;
/**
* Load or refresh the persistent representation of the configuration
*/
public void refresh() throws BeansException, IllegalStateException {
//容器重启同步监控锁,防止刷新进行到一半被重复执行
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//填充配置文件占位符,记录容器启动时间和启动状态
prepareRefresh();
//完成配置文件定义到注册表登记bean的流程,此时对象还未被创建
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//配置类加载器,定制特殊bean,添加BeanPostProcessor可供回调
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//工厂加载完配置,初始化之前回调PostProcessBeanFactory,作为工厂扩展功能
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//调用上文注册的扩展接口PostProcessBeanFactory的实现,为扩展接口为列表类型
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// bean扩展:postProcessBeforeInitialization和postProcessAfterInitialization
//分别在Bean初始化之前和初始化之后得到执行
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//初始化MessageSource对象,国际化
initMessageSource();
// Initialize event multicaster for this context.
//初始化事件广播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//临时钩子方法,提供一些初始化完成前的特殊操作,传送门
onRefresh();
// Check for listener beans and register them.
//注册监听器
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//实例化工厂注册表里面的bean(懒加载的除外,用到才实例化)
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
//初始化生命周期,广播事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
5.3 准备工作
容器初始化之前的初始化工作;
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true );
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment
//初始化占位符
initPropertySources();
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
//校验配置文件
getEnvironment().validateRequiredProperties();
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet
(); }
5.4 创建BeanFactory
创建BeanFactory,这个是整个IOC容器启动流程的两大核心模块之一;
//AbstractApplicationContext.java
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//关闭旧工厂,创建新工厂
refreshBeanFactory();
//返回创建的新工厂
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
重置BeanFactory,存在则销毁,不存在则创建;
//AbstractRefreshableApplicationContext.java 120
@Override
protectedfinalvoidrefreshBeanFactory() throws BeansException {
//存在BeanFactory()则销毁,即清除工厂里面Map存放的对象
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//返回新建的DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
//工厂标识id
beanFactory.setSerializationId(getId());
//设置容器是否允许对象覆盖,循环依赖
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
创建BeanFactory,构造出子类对象DefaultListableBeanFactory,从前文架构部分我们可以看出这个类的重要地位,里面涵盖了工厂BeanFactory,对象定义BeanDefinition,和注册表AliasRegistry的能力,是一个完整的对象工厂,下文就是使用该工厂将配置文件的信息转换为类定义信息,再进行对象创建,属性赋值。
//AbstractRefreshableApplicationContext.java 199
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
5.5 读取配置文件
读取xml配置文件
//AbstractXmlApplicationContext.java 80
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
//实例化一个工厂类的XML文件阅读器
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
//开启xml文件校验,可在实现的子类关闭
initBeanDefinitionReader(beanDefinitionReader);
//beanDefinitionReader阅读器加载资源文件
loadBeanDefinitions(beanDefinitionReader);
}
加载资源文件
//AbstractXmlApplicationContext.java 120
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
//configLocations最终解析成资源对象configResources,效果跟上面分支一样
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
循环加载所有资源文件
//AbstractBeanDefinitionReader.java 177
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int counter = 0;
for (Resource resource : resources) {
counter += loadBeanDefinitions(resource);
}
return counter;
}
阅读器从资源对象获取路径,读取配置文件
//XmlBeanDefinitionReader.java 303
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource));
}
//XmlBeanDefinitionReader.java 314
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isInfoEnabled()) {
logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}
//使用ThreadLocal存放配置文件路径
Set
currentResources = this.resourcesCurrentlyBeingLoaded.get(); if (currentResources == null) {
currentResources = new HashSet
(4); this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!currentResources.add(encodedResource)) {
thrownew BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//打开文件流,读取文件内容
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
inputStream.close();
}
}
catch (IOException ex) {
thrownew BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
读取配置文件内容
//XmlBeanDefinitionReader.java 388
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
//xml文件生成Document文件数
Document doc = doLoadDocument(inputSource, resource);
return registerBeanDefinitions(doc, resource);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (SAXParseException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
}
catch (SAXException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"XML document from " + resource + " is invalid", ex);
}
catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Parser configuration exception parsing XML from " + resource, ex);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"IOException parsing XML document from " + resource, ex);
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Unexpected exception parsing XML document from " + resource, ex);
}
}
5.6 注册对象
注册对象,将XML配置文件描述的Bean转换到BeanFactory的注册表上,返回增量的bean数量;
//XmlBeanDefinitionReader.java 505
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
//注册表已存在Definition数量(对象的描述)
int countBefore = getRegistry().getBeanDefinitionCount();
//将doc树的bean定义注册到工厂类的注册表属性
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
document阅读器,将已经转成内存document的对象加载到注册表上;
//DefaultBeanDefinitionDocumentReader.java 90
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
doRegisterBeanDefinitions(root);
}
遍历document逐个解析xml标签;
//DefaultBeanDefinitionDocumentReader.java 116
protected void doRegisterBeanDefinitions(Element root) {
// Any nested
elements will cause recursion in this method. In // order to propagate and preserve
default-* attributes correctly, // keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback purposes,
// then ultimately reset this.delegate back to its original (parent) reference.
// this behavior emulates a stack of delegates without actually necessitating one.
BeanDefinitionParserDelegate parent = this.delegate;
//创建解析DOM树对象的工具BeanDefinitionParserDelegate
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
//如果不包含
标签则略过该操作,非必要方法,略过 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.isInfoEnabled()) {
logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
preProcessXml(root);//预留方法,解析前的扩展操作
parseBeanDefinitions(root, this.delegate);//核心方法,解析DOM树
postProcessXml(root);//预留方法,解析后的扩展操作
this.delegate = parent;
}
5.7 解析配置文件
解析内存的DOM文件树;
//DefaultBeanDefinitionDocumentReader.java 161
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;
//包含http://www.springframework.org/schema/beans的为默认命名空间
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
//非默认命名空间的有
、 、 等 delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
解析默认命名空间的标签;
//DefaultBeanDefinitionDocumentReader.java 182
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
elseif (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
elseif (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);//解析命名空间为bean的标签
}
elseif (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
解析标签细节,新建BeanDefinition包装类,持有BeanDefinition引用,beanName和别名;
//DefaultBeanDefinitionDocumentReader.java 298
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//将DOM树对象转化为BeanDefinition包装类bdHolder
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
//BeanDefinitionParserDelegate.java 427
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
//BeanDefinitionParserDelegate.java 436
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
List
aliases = new ArrayList (); if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
if (logger.isDebugEnabled()) {
logger.debug("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
//DOM树标签映射到BeanDefinition对象
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
beanName = this.readerContext.generateBeanName(beanDefinition);
// Register an alias for the plain bean class name, if still possible,
// if the generator returned the class name plus a suffix.
// This is expected for Spring 1.2/2.0 backwards compatibility.
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (logger.isDebugEnabled()) {
logger.debug("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;
}
//BeanDefinitionParserDelegate.java 521
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
try {
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
//创建BeanDefinition对象,设置对应类名
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
//将xml里面的标签一一解析到BeanDefinition对象
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
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;
}
至此我们已经成功将单个xml配置文件里面的标签属性映射到BeanDefinitionHolder对象里面,接下来是把BeanDefinition对象登记到工厂的注册表里面;
//BeanDefinitionReaderUtils.java 143
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
//通过beanName注册definitionHolder的BeanDefinition对象到注册表
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
//如果有别名也一并注册
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
注册BeanDefinition对象;
//DefaultListableBeanFactory.java 793
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);
}
}
BeanDefinition oldBeanDefinition;
//我们奋斗这么久就是为了吧xml转换为Definition然后put到beanDefinitionMap
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
//新的xml获取出来的应该为空
if (oldBeanDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
}
elseif (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (this.logger.isWarnEnabled()) {
this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
elseif (!beanDefinition.equals(oldBeanDefinition)) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
//初始化的过程,应该不允许实例化
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List
updatedDefinitions = new ArrayList (this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set
updatedSingletons = new LinkedHashSet (this.manualSingletonNames); updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
//最核心的一步,就是beanDefinitionMap增加beanDefinition
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
5.8 对象实例化
到了这一步,我们已经完整的把所有xml配置文件里面定义的对象转化到BeanFactory里面的beanDefinitionMap,但是此时IOC容器还没开始实例化这些对象,接下来就是实例化的过程。回顾一下我们分析入口的refresh()方法,里面的finishBeanFactoryInitialization(beanFactory)就是对象的实例化过程,我们重点来分析这个方法的流程。
完成对象实例化入口
// AbstractApplicationContext.java 834
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
//JVM动态织入第三方模块
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);
// Allow for caching all bean definition metadata, not expecting further changes.
//冻结配置文件,避免重复读取
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
//实例化非懒加载对象
beanFactory.preInstantiateSingletons();
}
单例对象预实例化
//DefaultListableBeanFactory.java 728
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List
beanNames = new ArrayList (this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
//合并具有父子关系的对象
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {//通常不是工厂bean
final FactoryBean> factory = (FactoryBean>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction
() { @Override
public Boolean run() {
return ((SmartFactoryBean>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);//进入实例化bean
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
实例化工厂里面定义的对象
//AbstractBeanFactory.java 196
publicObject getBean(String name) throws BeansException {
returndoGetBean(name, null, null, false);
}
//AbstractBeanFactory.java 235
protected
T doGetBean( final String name, final Class
requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
//返回的实例化对象,等待赋值
Object bean;
// Eagerly check singleton cache for manually registered singletons.
//从目标MAP里面获取实例化对象,检查是否已经实例化过
Object sharedInstance = getSingleton(beanName);
//如果存在则不需要再实例化,首次实例化为空,进入下个判断
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//判断该beanName是否被实例化为prototype或者被创建中,如果是则抛异常
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
thrownew BeanCurrentlyInCreationException(beanName);
}
//判断bean的定义是否存在工厂里面
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
//激动的说时刻到来,开始准备实例化bean了
try {
//获取bean的定义对象
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//优先实例化所要依赖的对象
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
//如果所要依赖的对象反过来还要依赖自己,形成了循环依赖,就抛异常,这里不允许循环依赖
if (isDependent(beanName, dep)) {
thrownew BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
thrownew BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//创建单例对象
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory
@Override
public Object getObject() throws BeansException {
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);
}
//同理创建prototype类型的对象,非单例,创建出来后不再维护生命周期
elseif (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) {
thrownew IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory
@Override
public Object getObject() throws BeansException {
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;
}
}
//最后检查对象的类型是否一致
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
//AbstractAutowireCapableBeanFactory.java 447
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//确保对象对应的类被加载进内存
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//为AOP做的钩子
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);
}
//终于到了创建对象了,还有完没完啊。。。
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
//AbstractAutowireCapableBeanFactory.java 504
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//从工厂bean缓存容器里面移除
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//为空说明不是工厂bean,可以直接创建对象
if (instanceWrapper == null) {
//这一步是真正的创建对象,看来还没完没了啊。。。。
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//经过漫长的过程,我们终于得到我们心心念念的bean了,坑爹。。。
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
//创建完bean后的一些特殊操作
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;
}
}
//解析循环依赖的逻辑,比较复杂,后面有时间再研究
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
//该方法两大重头戏,上面createBeanInstance是创建对象,populateBean是初始化属性值
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
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;
}
elseif (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set
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;
}
真正的bean实例化动作
//AbstractAutowireCapableBeanFactory.java 1061
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
//确保对象对应的类被加载了
// Make sure bean class is actually resolved at this point.
Class> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
thrownew BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
//工厂方法实例化
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
//无参数构造方法实例化
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
//有入参的构造方法实例化
// Need to determine the constructor...
Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
//我们选简单一点的无参数构造方法实例化
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
//AbstractAutowireCapableBeanFactory.java 1138
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction
@Override
public Object run() {
//获取实例化策略,这会可是实实在在的实例化了
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
}, getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
thrownew BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
//SimpleInstantiationStrategy.java 59
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (bd.getMethodOverrides().isEmpty()) {
Constructor> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction
>() { @Override
public Constructor> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
//构造方法反射实例化
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
//BeanUtils.java 138
public static
T instantiateClass(Constructor ctor, Object... args) throws BeanInstantiationException {Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
//核心核心!终于重bean里面获取类,类的构造方法,然后反射new除了对象,好累。
return ctor.newInstance(args);
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
5.9 对象属性初始化
经过漫长漫长的过程,我们终于把配置文件里面定义的bean,千辛万苦的读取了对应的class,抽取出构造函数,然后通过反射new除了对象,但是此时的对象还是空空如也,需要我们把预设置的值初始化进去,这也是最后一步了。
//AbstractAutowireCapableBeanFactory.java 1207
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
//获取所有的属性值
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
thrownew BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
//出现BeanPostProcessors又是钩子,给出各种特殊操作
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
//通过name属性来装配
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
//通过type属性来装配
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return
|
阿里开发者 · 微调碾压RAG?大模型意图识别工程化实践 昨天 |
|
白鲸出海 · 专注被美图“抛弃”的女性变美赛道,这家公司扭亏为盈了 2 天前 |
|
腾讯 · 初八,开工大吉! 3 天前 |
|
阿里开发者 · 从铜线到云端:网络技术的跨越与未来趋势 3 天前 |
|
百度智能云 · 国内首个!百度成功点亮昆仑芯三代万卡集群,将于近日点亮3万卡集群 4 天前 |
|
腾讯新国风 · 处世丨与其多颗心,不如少根筋 8 年前 |
|
V保险 · 看完这7张图,99%的人会在40岁之前买重大疾病保险... 7 年前 |
|
气质女人 · 一搭丨明天穿什么 ? 7 年前 |
|
每日健康知识 · 老年人最好不要和子女住一起的5个理由,所有人都该看看! 7 年前 |
|
养花大全 · 必学 | 别说你买不起院子,阳台就能造一个! 7 年前 |