spring xml 解析bean配置文件为beanDefinition过程
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
@Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {
// https://blog.csdn.net/ZixiangLi/article/details/87937819
// singleton 已经不使用了,后面都修改为scope配置了
if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
}
// bean 作用范围 singleton,prototype request session
else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
}
// 如果都找不到,则使用bean的scope
else if (containingBean != null) {
// Take default from containing bean in case of an inner bean definition.
bd.setScope(containingBean.getScope());
}
// 设置bean 是否为抽象类,默认是false 如果设置为true 则不能初始化
if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
}
// 解析 lazy-init 属性,设置bean是否懒加载,如果设置为true,在应用第一次使用到该bean时才加载
// "非单例" 的不受这个限制,在初始化容器时都不会加载
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
if (isDefaultValue(lazyInit)) {
lazyInit = this.defaults.getLazyInit();
}
bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
// 解析 autowire
// 存在5个值
// byName:通过属性名称来自动装配,及A类中的B对象名称为beanService,那么将根据id="beanService"来装配,A 类必须提供setBeanService方法
// byType:根据属性来找到和配置文件中配置的class类型一致的bean来自动装配,如果找到多个类型一致的bean则抛出异常,如果一个都没找到,则不执行装配,也不抛出异常
// no 不执行 自动装配,只能用<ref标签进行装配;
// constructor: 根据构造器中参数类型自动装配,如果找到了多个类型一致的bean则抛出异常,如果找不到这抛出异常
// autodetect: 从spring4开始该值被抛弃,通过bean类的反省机制,决定使用constructor还是byType
String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
bd.setAutowireMode(getAutowireMode(autowire));
// 解析 depends-on 他的作用是一个bean实例化的构成需要依赖另一个bean的初始化,即当前bean初始化之前,依赖的bean要完成初始化,多个依赖bean之间使用 , 分割
if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
}
// 解析 autowire-candidate 默认为true ,如果设置为false,则当前bean不能作为其他bean自动装配的候选者。
String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
if (isDefaultValue(autowireCandidate)) {
String candidatePattern = this.defaults.getAutowireCandidates();
if (candidatePattern != null) {
String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
}
}
else {
bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
}
// 解析 primary 默认为false 当设置为true 时,如果 容器中出现多个与该bean相同类型的其他bean时,
// 使用Autowired 装配这个类型bean时,优先使用当前bean:https://blog.csdn.net/qq_36951116/article/details/79130591
if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
}
// 解析 init-method 他的作用是在创建一个bean之后调用该方法,初始化方法必须是一个无参方法
if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
bd.setInitMethodName(initMethodName);
}
else if (this.defaults.getInitMethod() != null) {
bd.setInitMethodName(this.defaults.getInitMethod());
bd.setEnforceInitMethod(false);
}
// 解析 destroy-method 它的作用是在销毁bean之前可以执行指定的方法,
// 这个bean必须满足scope=singleton 并且destroy方法不能超过一个,并且参数类型只能为boolean
if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
bd.setDestroyMethodName(destroyMethodName);
}
else if (this.defaults.getDestroyMethod() != null) {
bd.setDestroyMethodName(this.defaults.getDestroyMethod());
bd.setEnforceDestroyMethod(false);
}
// 解析 factory-method 指定创建bean的工厂方法
if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
}
// 解析 factory-bean 指定创建bean的工厂对象 class 属性将失效
if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
}
return bd;
}
Go deeper!