涉及IOC容器的相关设计,bean是在IOC容器中实现的。
IOC 容器是Spring的基本组件,IoC 容器(又名DI 容器)是Spring 实现自动依赖注入的组件, Spring通过IOC 容器管理对象的创建及其生命周期,并向类注入依赖项。 IoC 容器可以创建指定类的对象,并在运行时通过构造函数、属性或方法注入所有依赖对象,并在适当的时候销毁它。实际就是Map结构。key存bean名称或ID,value存bean对应的定义成的beanDefiniton
一般IOC容器需要具备一下功能:
主要分为两个容器系列:
一个是实现BeanFactory接口的简单容器系列,实现了容器的基本功能;
另一个是ApplicationContext应用上下文,是更高级的容器,在简单容器的基础上增加了许多特性。
BeanDefinition继承体系
以下通过对BeanDefinition源码进行调试,先编写测试类
package com.yhw.controller;
import com.yhw.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("classpath:spring-config.xml");
User user = (User) app.getBean("user");
user.hello();
System.out.println(user.getTeacher().getName());
}
}
1.1 基于配置文件的BeanDefinitoin加载流程
ClassPathXmlApplicationContext
AbstractApplicationContext中的核心方法refresh
doLoadBeanDefinition
流的处理,解析成DOC文档
registerBeanDefinitions(返回解析配置文件的个数)
//处理doc文档
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
// doc解析器
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
// 已经解析的BeanDefinition数量,配置文件有多个,循环一个个解析
int countBefore = getRegistry().getBeanDefinitionCount();
// 解析doc
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
// 返回本次解析配置文件个数
return getRegistry().getBeanDefinitionCount() - countBefore;
}
DefaultBeanDefinitionDocumentReader.registerBeanDefinition()
@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
// 获取doc结点,入参evaluate(doc.getDocumentElement())
doRegisterBeanDefinitions(doc.getDocumentElement());
}
DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions()
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.
// beans内部定义bean,如果没定义某些信息,直接调用外部的beans
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
// 获取profile,spring中配置的激活环境,这里判断是否需要加载这个节点
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
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());
}
// 环境没激活,直接返回,代表一个xml文件解析的结束
return;
}
}
}
// 模板方法 需要一些细节处理
preProcessXml(root);
// 解析bean标签
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);
this.delegate = parent;
}
DefaultBeanDefinitionDocumentReader.parseBeanDefinitions()
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;
// 如果是默认标签,走默认标签解析方法(parseDefaultElement)
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
//否则,走parseCustomElement解析方法,也就是子标签的解析
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
对子标签的解析
// 子标签的解析
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
// import标签解析
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
// alias标签解析
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)) {
// recurse
// 解析外层bean一样的流程
doRegisterBeanDefinitions(ele);
}
}
解析ele节点(非默认节点),默认节点一般包括bean、alias等
包装方法parseBeanDefinitonElement()
拿到bean的id或者name值,配置别名
判断beanname是否存在,并开始创建BeanDefinition
// 检测beanname是否已存在,内部用set存储beanname(id),避免重复
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
// 创建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.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;
DefaultListableBeanFactory.registerBeanDefinition(BeanDefiniton的注册)
// 根据beanname获取BeanDefinition
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
// 已存在BeanDefinition对象,
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
// 判断是否可覆盖
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
// BeanDefinition注册,实际将BeanDefinition存入beanDefinitionMap
this.beanDefinitionMap.put(beanName, beanDefinition);
判断是否有bean初始化
// 判断是否有其他bean开始初始化
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;
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
// 注册beanDefinition 也就是保存在map中
// 至此BeanDefinition注册成功,后面都是循环注册所有xml文件中定义的bean(beans标签的解析由外到内)
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
有别名的话绑定别名
// 创建BeanDefinition
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
// 拿到bean的名字
String beanName = definitionHolder.getBeanName();
// bean的注册
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);
}
}
}
执行结束
1.2 基于配置类的BeanDefinition加载流程
测试Demo
配置类的解析同样用到refresh,最后BeanDefinition都会在refresh方法中加载到工厂中
BeanDefinition的注册
// 注册BeanDefinition
private void doRegisterBean(Class beanClass, @Nullable String name,
@Nullable Class extends Annotation>[] qualifiers, @Nullable Supplier supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//直接搞了一个beanDefinition
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
// 判断是不是需要跳过,配置类是否有Condition注解,满足指定条件,则会加载对应的实例或类,写在类或方法上,例如获取window或者Linux类型
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
// 解析abd的scope类型
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
// 设置作用域,默认单例
abd.setScope(scopeMetadata.getScopeName());
// bean的名字
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 解析bean的一些注解值
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
//qualifiers注解处理 我们这里为null 在注入其他bean的时候分析
if (qualifiers != null) {
for (Class extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
// bean的个性化处理 前提时bean实现了beanDefinitionCustomizer接口
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
// 包装
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 注册BeanDefinition,就是将其放入map中,并将别名与bean的名字绑定
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
配置类与配置文件加载的区别:
在refreshBeanFactory中,设置id后直接返回beanfactory,
而xml版,在这里解析xml文件,注册beandefinition等信息
BeanDefinition的加载流程
BeanDefinition 的扫描注册过程分了三个阶段:
BeanDefinition 的扫描
即从 class 类定义中扫描出 BeanDefinition
BeanDefinition 基本属性的填充
基本属性包括:@Lazy、@Primary、@DependsOn、@Role、@Description 等。
BeanDefinition 的注册
BeanDefinition 最终会注册到 BeanDefinitionRegistry 中
所以,BeanDefinition 的注册主要是将 bean 的定义从 class 类定义中扫描出来,并注册到 BeanDefinitionRegistry 中