public static void main(String[] args) {
XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("spring.xml"));
}
配置文件封装
new ClassPathResource("spring.xml")
Spring对于不同来源的资源文件都有响应的Resource实现
XmlBeanFactory构造
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
- super方法
/**
* Create a new AbstractAutowireCapableBeanFactory.
*/
public AbstractAutowireCapableBeanFactory() {
super();
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
if (NativeDetector.inNativeImage()) {
this.instantiationStrategy = new SimpleInstantiationStrategy();
}
else {
this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();
}
}
- ignoreDependencyInterface(接口.clsss):会忽略指定接口的类型的依赖项
- reader.loadBeanDefinitions(resource)
重点内容,reader的实现类就是XmlBeanFactoryReader
loadBeanDefinitions(resource)
处理流程
- 将
Resource
封装成EncodedResource
- 从
Resource
获取InputSource
最后将
Resource
和InputSource
共同传入doLoadBeanDefinitions
方法中doLoadBeanDefinitions
这段代码里异常处理很多,不看异常处理,重要的代码是2句
加载xml文件为Document
根据Document注册Bean信息
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
int count = registerBeanDefinitions(doc, resource);
return count;
}
catch ....
}
获取Document流程
获取Document流程交给了
DocumentLoader
的唯一一个实现类DefaultDocumentLoader
来处理,
具体的处理逻辑也是通过Java提供的SAX对XML进行解析解析及注册BeanDefinitions
流程描述
获取一个
BeanDefinitionDocumentRader
类,这里的具体实现类是DefaultBeanDefinitionDocumentReader
- 调用
DefaultBeanDefinitionDocumentReader
解析前,封装XmlReaderContext
- 调用
DefaultBeanDefinitionDocumentReader
的registerBeanDefinitions
执行注册 -
doRegisterBeanDefinitions
DefaultBeanDefinitionDocumentReader
的registerBeanDefinitions
最终会进入,这个doRegisterBeanDefinitions
方法。@SuppressWarnings("deprecation") // for Environment.acceptsProfiles(String...)
protected void doRegisterBeanDefinitions(Element root) {
BeanDefinitionParserDelegate parent = this.delegate;
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);
// 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;
}
}
}
preProcessXml(root);
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);
this.delegate = parent;
}
创建委托对象
- 解析profile
- preProcessXml:未实现的方法
- 执行解析
- postProcessXml:未实现的方法
parseBeanDefinitions(root, this.delegate);
解析”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、import、alias等,走parseDefaultElement(ele, delegate);
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
//import标签
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
//alias标签
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
//bean标签
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
若是自定义标签:走delegate.parseCustomElement(ele);
Bean标签的解析
方法:DefaultBeanDefinitionDocumentReader#processBeanDefinition
- 委托
BeanDefinitionDelegate
类的parseBeanDefinitionElement
方法进行元素解析,返回BeanDefinitionHodler
- 若默认标签的子标签下有自定义标签,会执行
BeanDefinitionParserDelegate#decorateBeanDefinitionIfRequired()
方法 - 将
BeanDefinition
注册,通过BeanDefinitionReaderUtils
-
步骤1解析为BeanDefinitionHodler
判断beanName和name属性
- 生成
GenericBeanDefinition
- 若无beanName,自动生成
@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
//提取 id 和 name属性
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
//所有的name属性通过分词作为别名
List<String> aliases = new ArrayList<>();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
//若未指定id则使用 name的 第一个元素作为 beanName
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");
}
}
//检查所有的别名和beanName的唯一性
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
//将元素解析未 BeanDefiniton
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;
}
根据指定字符串中任一字符串分词的工具类 String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
生成GenericBeanDefinition
- 解析
中的calss和parent - 生生成BeanDefinition
- 解析
的各种属性 - 解析子元素meta
- 解析子元素lookup-method
- 解析子元素replaced-method
- 解析子元素constructor-arg
- 解析子元素property
解析子元素qualifier
@Nullable
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 {
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
//解析 parent scope/lazy-init等属性
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
//
parseMetaElements(ele, bd);
//解析lookup
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;
}
AbstractBeanDefinition
```java
/**
- Constant for the default scope name: {@code “”}, equivalent to singleton
status unless overridden from a parent bean definition (if applicable). */ public static final String SCOPE_DEFAULT = “”;
/**
- s自动装配模式
- Constant that indicates no external autowiring at all.
@see #setAutowireMode */ public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
/**
- Constant that indicates autowiring bean properties by name.
@see #setAutowireMode */ public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
/**
- Constant that indicates autowiring bean properties by type.
@see #setAutowireMode */ public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
/**
- Constant that indicates autowiring a constructor.
@see #setAutowireMode */ public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
/**
- Constant that indicates determining an appropriate autowire strategy
- through introspection of the bean class.
- @see #setAutowireMode
- @deprecated as of Spring 3.0: If you are using mixed autowiring strategies,
use annotation-based autowiring for clearer demarcation of autowiring needs. */ @Deprecated public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
/**
- Constant that indicates no dependency check at all.
@see #setDependencyCheck */ public static final int DEPENDENCY_CHECK_NONE = 0;
/**
- Constant that indicates dependency checking for object references.
@see #setDependencyCheck */ public static final int DEPENDENCY_CHECK_OBJECTS = 1;
/**
- Constant that indicates dependency checking for “simple” properties.
- @see #setDependencyCheck
@see org.springframework.beans.BeanUtils#isSimpleProperty */ public static final int DEPENDENCY_CHECK_SIMPLE = 2;
/**
- Constant that indicates dependency checking for all properties
- (object references as well as “simple” properties).
@see #setDependencyCheck */ public static final int DEPENDENCY_CHECK_ALL = 3;
/**
- Constant that indicates the container should attempt to infer the
- {@link #setDestroyMethodName destroy method name} for a bean as opposed to
- explicit specification of a method name. The value {@value} is specifically
- designed to include characters otherwise illegal in a method name, ensuring
- no possibility of collisions with legitimately named methods having the same
- name.
Currently, the method names detected during destroy method inference
are “close” and “shutdown”, if present on the specific bean class. */ public static final String INFER_METHOD = “(inferred)”;
// beanClass @Nullable private volatile Object beanClass; //作用域 @Nullable private String scope = SCOPE_DEFAULT;
private boolean abstractFlag = false;
//懒加载 @Nullable private Boolean lazyInit; //自动装配方式 private int autowireMode = AUTOWIRE_NO;
private int dependencyCheck = DEPENDENCY_CHECK_NONE; //dependon @Nullable private String[] dependsOn; //装配候选人 private boolean autowireCandidate = true; // 是否主要 private boolean primary = false; // private final Map
qualifiers = new LinkedHashMap<>(); @Nullable private Supplier<?> instanceSupplier;
private boolean nonPublicAccessAllowed = true;
private boolean lenientConstructorResolution = true;
@Nullable private String factoryBeanName;
@Nullable private String factoryMethodName;
@Nullable private ConstructorArgumentValues constructorArgumentValues;
@Nullable private MutablePropertyValues propertyValues;
private MethodOverrides methodOverrides = new MethodOverrides();
@Nullable private String initMethodName;
@Nullable private String destroyMethodName;
private boolean enforceInitMethod = true;
private boolean enforceDestroyMethod = true;
private boolean synthetic = false;
private int role = BeanDefinition.ROLE_APPLICATION;
@Nullable private String description;
@Nullable private Resource resource;
<a name="PMzub"></a>
## 步骤2解析自定义标签
过
<a name="WL1Fm"></a>
## 步骤3注册成为BeanDefinition
通过`BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder,getReaderContext().getRegistry())`进行注册
```java
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any. beanName的别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
注册beanName->BeanDefinition
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
//校验
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
//若存在,需要判断是否允许覆盖
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
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 + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
//r若已经又Bean创建了
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
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);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
else if (isConfigurationFrozen()) {
clearByTypeCache();
}
}
注册alia->beanName
@Override
public void registerAlias(String name, String alias) {
Assert.hasText(name, "'name' must not be empty");
Assert.hasText(alias, "'alias' must not be empty");
synchronized (this.aliasMap) {
if (alias.equals(name)) {
this.aliasMap.remove(alias);
if (logger.isDebugEnabled()) {
logger.debug("Alias definition '" + alias + "' ignored since it points to same name");
}
}
else {
String registeredName = this.aliasMap.get(alias);
if (registeredName != null) {
if (registeredName.equals(name)) {
// An existing alias - no need to re-register
return;
}
if (!allowAliasOverriding()) {
throw new IllegalStateException("Cannot define alias '" + alias + "' for name '" +
name + "': It is already registered for name '" + registeredName + "'.");
}
if (logger.isDebugEnabled()) {
logger.debug("Overriding alias '" + alias + "' definition for registered name '" +
registeredName + "' with new target name '" + name + "'");
}
}
checkForAliasCircle(name, alias);
this.aliasMap.put(alias, name);
if (logger.isTraceEnabled()) {
logger.trace("Alias definition '" + alias + "' registered for name '" + name + "'");
}
}
}
}
会检查循环的问题 A->B->A
步骤4通知注册完成
过