一般手动启动spring容器和获取Bean实例我们会写如下代码:
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("testBean.xml",getClass()));
MyTestBean bean = (MyTestBean) bf.getBean("myTestBean");
或者是
ApplicationContext beans=new ClassPathXmlApplicationContext("classpath:application-customTag.xml");
User user=(User)beans.getBean("testBean");
第一行代码是启动spring容器;第二行代码是获取Bean实例;
那么这两行代码底层做了哪些事情呢,我们慢慢道来。
由图1可大致知道主要做了哪些事:
1.1 通过new ClassPathResource("testBean.xml",getClass())加载配置,返回Resource;
加载资源有多种方式,如:ClassPathResource、FileSystemResource、UrlResource等
1.2 通过new XmlBeanFactory(Resource resource)启动spring容器
一级主要代码:
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
调用XmlBeanDefinitionReader的loadBeanDefinitions进行一级分析配置,其中XmlBeanDefinitionReader对资源的阅读器,spring源码中很多xxxReader的方法,通过该阅读器读取bean配置存放在BeanDefiniton中。
二级主要代码:
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource));
}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Loading XML bean definitions from " + encodedResource);
}
//通过属性来记录已经加载的资源
Set currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
//从encodedResource中获取已经封装 Resource对象并从中获取输入输入流
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
//InputSource并不是Spring中的类,它的全路径为org.xml.sax.InputSource
//为XML实体的单个输入源,字节流
InputSource inputSource = new InputSource(inputStream);//
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
/**
* the SAX InputSource to read from the resource descriptor for the XML file
* 返回:the number of bean definitions found
*/
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
inputStream.close();
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
大致所做的事情是:
1.对传进来的Resource进行编码,类似加密
2.将编码后的Resource转化成字节输入流
3.通过InputSource inputSource = new InputSource(inputStream);生成一个InputSource,它的全路径为org.xml.sax.InputSource
用来对XML资源进行解析
4.调用int doLoadBeanDefinitions(inputSource, encodedResource.getResource())准备对配置进行解析
三级主要代码:
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
}
该方法主要做三件事:
1.获取对XML文件的验证模式
2.加载XML文件,并得到对应的Document
3.根据Document注册Bean信息
其中Document doc = doLoadDocument(inputSource, resource);做前两件事情
代码为:
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
getValidationModeForResource(resource), isNamespaceAware());
}
其中getValidationModeForResource(resource)进行XML文件格式的验证;
EntityResolver的作用是项目本身就可以提供一个如何寻找DTD声明的方法,即由程序来实现寻找DTD声明的过程,比如我们将DTD文件放到项目中某处,在实现时直接将此文档读取并返回给SAX即可。这样就避免了通过网络来寻找相应的声明。
查找顺序:如果本地有,则不进行网络查找;本地没有,则进行网络查找,spring将DTD和XSD文件放在了项目中,防止网络查找时网络异常
int count = registerBeanDefinitions(doc, resource);做最后一件事情
代码为:
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//使用DefaultBeanDefinitionDocumentReader实例化BeanDefinitionDocumentReader
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
//在实例化BeanDefinitionDocumentReader时候会将BeanDefinitionRegistry传入,默认使用继承自DefaultListableBeanFactory的子类
//记录统计前BeanDefinition的加载个数
int countBefore = getRegistry().getBeanDefinitionCount();
//加载及注册bean
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
//返回记录本次加载的BeanDefinition个数
return getRegistry().getBeanDefinitionCount() - countBefore;
}
主要代码是int count = registerBeanDefinitions(doc, resource);注册BeanDefinitions,一个Bean内容存在一个BeanDefinition中,通过注册功能相当于将这些BeanDefinition存入内存中,以便用的时候获取。
后续主要代码:
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//使用DefaultBeanDefinitionDocumentReader实例化BeanDefinitionDocumentReader
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
//在实例化BeanDefinitionDocumentReader时候会将BeanDefinitionRegistry传入,默认使用继承自DefaultListableBeanFactory的子类
//记录统计前BeanDefinition的加载个数
int countBefore = getRegistry().getBeanDefinitionCount();
//加载及注册bean
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
//返回记录本次加载的BeanDefinition个数
return getRegistry().getBeanDefinitionCount() - countBefore;
}
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
doRegisterBeanDefinitions(doc.getDocumentElement());
}
protected void doRegisterBeanDefinitions(Element root) {
//BeanDefinitionParserDelegate为BeanDefinition分析器委派类
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
//获取profile属性,profile是的属性,可以与web.xml配合使用部署两套配置来适用于测试环境和生产环境
//这样可以方便的进行切换不同环境,最常用的是更换不同的数据库
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
//如果 定义了profile属性
if (StringUtils.hasText(profileSpec)) {
/**
* profile属性值可能是多个,如:profile="dev,prod",tokenizeToStringArray是将profile字符串转换
* 成字符数组
*/
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
// We cannot use Profiles.of(...) since profile expressions are not supported
// in XML config. See SPR-12458 for details.
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;
}
}
}
/**
* 解析前处理(空函数),运用了设计模式中的模板模式,如果继承自DefaultBeanDefinitionDocumentReader
* 的子类需要在Bean解析前后做一些处理的话,那么只需要重写这个方法就可以了(postProcessXml也是一样的)
*/
preProcessXml(root);
//解析
parseBeanDefinitions(root, this.delegate);
//解析后处理(空函数)
postProcessXml(root);
this.delegate = parent;
}
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
//对Beans的处理
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)) {
//默认命令空间,对bean处理,如
//BEANS_NAMESPACE_URI = "http://www.springframework.org/schema/beans";
parseDefaultElement(ele, delegate);
}
else {
//自定义命令空间,对bean处理,如:
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
//解析import标签
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}//解析alias标签
/**
*
*
*
*在对bean进行定义时,除了使用id属性来指定名称之外,为了提供多个名称,可以使用alias标签来指定。而所有的这些名称都
*指向同一个bean
*/
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}//解析bean标签
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}//解析beans标签
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// 循环递归解析
doRegisterBeanDefinitions(ele);
}
}
@Nullable
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
//获取对应的命名空间如:http://www.cb.com/schema/user
String namespaceUri = getNamespaceURI(ele);
if (namespaceUri == null) {
return null;
}
//根据命名空间找到对应的NamespaceHandler,如:
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
//此时的handler已经被实例化为自定义的Handler实例
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
注:在解析配置文件前后定义好空模板,由子类去实现相关逻辑,运用了设计模式中的模板模式
一级代码:
protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//提取对应的beanName
/**
* 要什么需要这一步,因为传入的参数name可能是别名也可能是FactoryBean,需要分情况做如下处理
* 1.如果是FactoryBean,则去除FactoryBean的修饰符,也就是如果name="&aa",那么会首先去除&而使用name="aa"
* 2.取指定alias所表示的最终的beanName,例如别名A指向名称为B的bean则返回B,若别名A指向别名B,别名B又指向别名
* 为C的bean,则最终返回C名称
*/
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
/**
* 检查缓存中或者实例工厂中是否有对应的实例
* 为什么首先会使用这段代码呢,因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候
* 为了避免循环依赖,Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光
* 也就是将ObjectFactory加入到缓存中,一旦下个bean创建时候需要依赖上个bean则直接使用beanFactory
*/
//直接尝试从缓存获取或者singletonFactories中的ObjectFactory中获取
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {//从缓存或者ObjectFactory中获取到了实例
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 + "'");
}
}
//返回对应的实例,有时候存在诸如BeanFactory的情况并不是直接返回实例本身而是返回指定方法返回的实例
//bean的实例化
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {////从缓存或者ObjectFactory中没有获取到了实例
// Fail if we're already creating this bean instance:
//如果我们已经创建了这个Bea实例则会失败:
// We're assumably within a circular reference.
/**
* 只有在单例情况才会尝试解决循环依赖,原型模式情况下如果存在A中有B的属性,B中有A的属性,那么当依赖注入
* 的时候,就会产生当A还未创建完的时候因为对应B的创建再次返回创建A,造成循环依赖,就是下面的情况
*/
//原型模式的依赖检查
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
//检查该bean定义是否存在ParentBeanFactory中
BeanFactory parentBeanFactory = getParentBeanFactory();
//如果当前加载的XML配置文件中不包含beanName所对应的配置,就只能到parentBeanFactory去尝试
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
//如果不是类型检查则是创建bean,这里要记录
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition,如果指定BeanName
//是子Bean的话同时会合并父类的相关属性
/**
* 因为从XML配置文件中读取到的Bean信息是存储在GernericBeanDefinition中的,但是所有Bean后续处理
* 都是针对于RootBeanDefinition的,所以这里转换一下
*/
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
//保证当前bean依赖的bean的初始化
/**
* bean的初始化过程中有可能用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖于其他的bean,那么
* 这个时候就有必要加载依赖的bean,所以,在spring的加载顺序中,在初始化某一个Bean的时候首先会初始化这个bean
* 所对应的依赖
*/
String[] dependsOn = mbd.getDependsOn();
//如果存在依赖则需要递归实例化依赖的Bean
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进行不同的初始化策略,对bean进行创建
*/
// 单例模式创建Bean实例.
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);
}
//原型模式创建Bean
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 {//指定Scope实例化Bean
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;
}
}
// Check if required type matches the type of the actual bean instance.
//检查所需类型是否与实际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实例继续跟踪底层源码:
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;
// 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,根据设置的class属性或者根据className来解析Class
Class> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 验证及准备覆盖的方法
/**
* 其实是处理lookup-method和replace-method的。
* 在Spring配置中存在lookup-method和replace-method两个配置功能,而这两个配置的加载其实就是将配置
* 统一存放在BeanDefinition中的methodOverrides属性里,这两个功能实现原理其实是在bean实例化的时候
* 如果检测到存在methodOverrides属性,会动态地为当前bean生成代理并使用对应的拦截器为bean做增强处理
*/
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.
//创建实例前做了一些处理
//应用初始化前的后处理,解析指定bean是否存在初始化前的短路操作
/**
* 实例化bean之前就为bean初始化定义一些后处理事项,有两个方法:
* postProcessBeforInitializationBean:初始化之前被回调
* postProcessAfterInitialization:Bean初始化之后被回调
*/
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的操作
//常规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);
}
}
这里重点提下:Spring提供了一中叫做BeanFactoryPostProcessor的容器扩展机制。该机制允许我们在容器s实例化相应对象之前,对注册在容器中的BeanDefinition所保存的信息做相应的修改,让我们对最终的BeanDefinition做一些额外的操作,比如修改其中Bean定义的某些属性,为bean定义增加其他信息等。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);就是实现了这个扩展机制。
该方法的代码是:
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//实例化前的后处理器应用
/**
* bean的实例化前调用,也就是将AbstarctBeanDefinition转换为BeanWapper前的处理
* 给子类一个修改BeanDefinition的机会,也就是说当程序经过这个方法后,bean可能已经不是我们
* 认为的bean,而是或许成为了一个经过处理的代理bean,可能是通过cglib生成的,也可能是通过
* 其他技术生成的
*/
//在目标Bean初始化之前被回调。
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//实例化后的后处理器应用
//在目标Bean初始化之后被回调。
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
通过Object beanInstance = doCreateBean(beanName, mbdToUse, args)对常规Bean进行创建。
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) {
//根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//org.springframework.beans.factory.support.LookupMethodTests$AbstractBean$$EnhancerBySpringCGLIB$$9976ee6a@2bb3058
final Object bean = instanceWrapper.getWrappedInstance();
//class org.springframework.beans.factory.support.LookupMethodTests$AbstractBean$$EnhancerBySpringCGLIB$$9976ee6a
Class> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
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.
//即使由BeanFactoryAware等生命周期接口触发
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");
}
//为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
//对bean再一次依赖引用,主要应用SmrtInstantitationAware BeanPostProcessor,其中
//我们熟知的AOP就是在这里将advice动态织入bean中,若没有则直接返回bean,不做任何处理
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
//初始化bean实例
Object exposedObject = bean;
try {
//对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始依赖bean
//填充bean
populateBean(beanName, mbd, instanceWrapper);
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 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.");
}
}
}
}
// 将bean注册为一次性(用完就销毁)
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
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;
}
}
// 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.
//给InstantiationAwareBeanPostProcessors最后一次机会在属性设置前来改变bean
//如:可以用来支持属性注入的类型
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//返回值为是否继续填充bean
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
//如果后处理器发出停止填充命名则终止后续的执行
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
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) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
//根据类型自动注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//后处理器已经初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
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);
}
//依赖检查,对应depend-on属性,3.0已经弃用此属性
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
//将属性应用到bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
该方法主要做的事情有:
1.根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
2.装配Bean依赖(对Bean进行相关属性填充)
3.Bean初始化前定义一些后处理事项,有初始化前回调方法,初始化后回调方法
4.Bean初始化
5.对象其他处理
6.注册回调接口(如:销毁Bean)