spring_core(1)EnvironmentBuildAndExecuteProcessParse
我们要创建一个spring的工程,然后注册一个bean到容器当中。
环境搭建
工程创建
创建工程spring-kernel-lecture,地址: https://github.com/1156721874/spring-kernel-lecture,引入依赖如下:
1 | dependencies { |
新建一个bean class
1 | package com.tdl.spring; |
在applicationContext.xml当中配置bean
1 | <?xml version="1.0" encoding="UTF-8"?> |
创建资源的抽象:
在spring当中,类路径下的类和文件,文件系统当中的文件,网络上获取的信息等都被抽象为了资源,都是Resource的实现,这次我们要加载的资源是applicationContext.xml当中的bean,因此是从class path下的资源加载,使用ClassPathResource。
1 | Resource resource = new ClassPathResource("applicationContext.xml"); |
spring当中的所有bean都会委托bean的工厂来管理,即,ioc.
IOC: [Inverse of control]控制反转
DI: [Dependency Injection] 依赖注入
对象的创建无需用户去创建,而是交给工厂来接手。
工厂的创建
1 | DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory(); |
工厂创建完毕之后,我们要使用读取器读取资源,然后把资源放到工厂里边。
bean的读取器
1 | BeanDefinitionReader beanDefinitionReader = |
XmlBeanDefinitionReader是xml文件读取器,它将要从applicationContext.xml读取资源,然后放到defaultListableBeanFactory
里边。
从工厂获取bean
1 | Student student = defaultListableBeanFactory.getBean("student", Student.class); |
小结
以上步骤汇总 就是一个spring的标准的过程。
1 | import com.tdl.spring.bean.Student; |
关于spring容器管理bean以及加载模式:
- 需要将bean的定义信息声明在bean的配置文件当中。
- 需要通过spring抽象出的各种Resource来指定对应的配置文件。
- 需要显式声明一个spring工厂,该工厂用来掌控我们在配置文件中所声明的各种bean以及bean之间的依赖关系与注入关系。
- 需要定义一个配置信息读取器,该读取器用来读取之前所定义的bean配置文件信息。
- 读取器的作用是读取我们所声明的配置文件信息,并且将读取后的信息装配到之前所声明的工厂当中。
- 需要将读取器与工厂以及资源对象进行相应的关联处理。
- 工厂所管理的全部对象装配完毕,可以供客户端直接调用,获取客户端想要使用的各种bean对象。
spring 对于bean管理的核心组件:
- 资源抽象
- 工厂
- 配置信息读取器
BeanFactory:
BeanFactory是spring bean工厂最顶层的抽象
The root interface for accessing a Spring bean container. This is the basic client view of a bean container; further interfaces such as ListableBeanFactory and org.springframework.beans.factory.config.ConfigurableBeanFactory are available for specific purposes.
spring bean容器最根的访问接入接口,是客户端展现的基础bean容器,更进一步像ListableBeanFactory、ListableBeanFactory都是对特定目的使用的实现。
1 | org.springframework.beans.factory.BeanFactory |
实现类: DefaultListableBeanFactory
Resource:
Interface for a resource descriptor that abstracts from the actual type of underlying resource, such as a file or class path resource.
对实际资源的一个抽象描述,比如文件 、class path下的资源。
ClassPathResource
首先看一下ClassPathResource的构造器:
1 | public ClassPathResource(String path) { |
DefaultListableBeanFactory
构造器:
1 | public DefaultListableBeanFactory() { |
DefaultListableBeanFactory的父接口AbstractAutowireCapableBeanFactory
1 | /** |
public AbstractBeanFactory() {
}
1 |
|
public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
super(registry);
}
1 | XmlBeanDefinitionReader继承了AbstractBeanDefinitionReader: |
protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
Assert.notNull(registry, “BeanDefinitionRegistry must not be null”);
this.registry = registry;
// Determine ResourceLoader to use.
//判断defaultListableBeanFactory是否实现了ResourceLoader,如果实现了ResourceLoader,赋值给resourceLoader
/ResourceLoader: Strategy interface for loading resources (e.. class path or file system resources)
// ResourceLoader是用来加载文件,classpath下的文件的策略接口
if (this.registry instanceof ResourceLoader) {
this.resourceLoader = (ResourceLoader) this.registry;
}
else {
//否则,创建一个PathMatchingResourcePatternResolver(内部封装了类加载器的逻辑,即ClassUtils.getDefaultClassLoader())
this.resourceLoader = new PathMatchingResourcePatternResolver();
}
// Inherit Environment if possible
//defaultListableBeanFactory实现了EnvironmentCapable,直接得到环境对象
if (this.registry instanceof EnvironmentCapable) {
this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
}
else {
//否则直接new 一个StandardEnvironment
this.environment = new StandardEnvironment();
}
}
1 |
|
public interface Environment extends PropertyResolver {
org.springframework.core.env.Environment#getActiveProfiles
org.springframework.core.env.Environment#getDefaultProfiles
org.springframework.core.env.Environment#acceptsProfiles(java.lang.String…)
org.springframework.core.env.Environment#acceptsProfiles(org.springframework.core.env.Profiles)
}
1 | Environment继承了PropertyResolver,得到了处理属性(properties)相关的功能。 |
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);
}
//resourcesCurrentlyBeingLoaded是一个ThreadLocal
Set
if (currentResources == null) {
currentResources = new HashSet<>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
// 循环导入,即存在一个资源被导入2次,一般出现在嵌套循环依赖里边。
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
“Detected cyclic loading of “ + encodedResource + “ - check your import definitions!”);
}
//InputStream是Closeable的,不需要手动关闭流
try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
//InputSource是对xml解析sax方式的封装,InputSource是通过流的方式进行解析的
InputSource inputSource = new InputSource(inputStream);
//编码设置
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
catch (IOException ex) {
//解析xml文档异常
throw new BeanDefinitionStoreException(
“IOException parsing XML document from “ + encodedResource.getResource(), ex);
}
finally {
//防止内存泄露
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
1 | EncodedResource的底层构造器,将参数Resource赋值给resource,encoding和encoding是编码方式, |
private EncodedResource(Resource resource, @Nullable String encoding, @Nullable Charset charset) {
super();
Assert.notNull(resource, “Resource must not be null”);
this.resource = resource;
this.encoding = encoding;
this.encoding = charset;
}
1 |
|
private DocumentLoader documentLoader = new DefaultDocumentLoader();
private Class<? extends BeanDefinitionDocumentReader> documentReaderClass =
DefaultBeanDefinitionDocumentReader.class;
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
//读取并解析,Document代表整个xml文档
Document doc = doLoadDocument(inputSource, resource);
//注册bean的定义
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug(“Loaded “ + count + “ bean definitions from “ + resource);
}
return count;
}
……
}
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//创建一个读取xml文档BeanDefinition的读取器
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
//解析之前的bean的个数,
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
//解析之后bean的个数减去解析之前的bean的个数,这种出现不一致的情况往往是由于xml里边有import的情况导致的。
return getRegistry().getBeanDefinitionCount() - countBefore;
}
protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
return BeanUtils.instantiateClass(this.documentReaderClass);
}
……
1 |
|
public static
Assert.notNull(clazz, “Class must not be null”);
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, “Specified class is an interface”);
}
try {
return instantiateClass(clazz.getDeclaredConstructor());
}
catch (NoSuchMethodException ex) {
//找不到方法通过另外一种方式进行,findPrimaryConstructor使用的是kotlin的方式
Constructor
if (ctor != null) {
//反射进行实例化
return instantiateClass(ctor);
}
throw new BeanInstantiationException(clazz, “No default constructor found”, ex);
}
catch (LinkageError err) {
throw new BeanInstantiationException(clazz, “Unresolvable class definition”, err);
}
}
public static
Assert.notNull(ctor, “Constructor must not be null”);
try {
//突破访问修饰符的限制
ReflectionUtils.makeAccessible(ctor);
//对kotlin的支持
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
return KotlinDelegate.instantiateClass(ctor, args);
}
else {
//得到构造器的参数
Class>[] parameterTypes = ctor.getParameterTypes();
Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
Object[] argsWithDefaultValues = new Object[args.length];
for (int i = 0 ; i < args.length; i++) {
if (args[i] == null) {
Class> parameterType = parameterTypes[i];
argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
}
else {
argsWithDefaultValues[i] = args[i];
}
}
//反射得到实例
return ctor.newInstance(argsWithDefaultValues);
}
}
……
}
1 | BeanDefinitionDocumentReader构建完毕之后,接下来就是文档的解析和bean的注册。 |
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
doRegisterBeanDefinitions(doc.getDocumentElement());
}
//在给定的root元素下,注册每个bean的定义
protected void doRegisterBeanDefinitions(Element root) {
// Any nested
// order to propagate and preserve
// 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.
// 任何嵌套的元素都可能导致递归。
//this.delegate是一种委托,这里使用了委托的设计模式
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);
//从root开始解析【模板方法模式】
parseBeanDefinitions(root, this.delegate);
//默认空实现,留给用户的扩展【模板方法模式】
postProcessXml(root);
this.delegate = parent;
}
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);
//xml当中的注释()也会被加载,但是不是Element对象
if (node instanceof Element) {
Element ele = (Element) node;
//默认命名空间
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
//默认命名空间之外的元素
delegate.parseCustomElement(root);
}
}
//某个元素的解析都是由委托对象完成的
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
//impot是顶级元素
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
//读取另外一个xml文件进行加载
importBeanDefinitionResource(ele);
}
//alias是顶级元素
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
//bean是顶级元素
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
//嵌套的情况
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
//递归调用
doRegisterBeanDefinitions(ele);
}
}
//bean元素的解析和注册
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//解析bean的定义,构造成BeanDefinitionHolder,是bean的完整的定义
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
//对bean的定义进行最终修饰
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
//bdHolder是解析出来的bean的定义信息,getReaderContext().getRegistry()是工厂,即
//将bean注册到工厂里边
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));
}
}
1 | delegate.parseBeanDefinitionElement(ele)完成对Element的解析: |
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
//bean的id
String id = ele.getAttribute(ID_ATTRIBUTE);
//bean的name
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
List
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.isTraceEnabled()) {
logger.trace(“No XML ‘id’ specified - using ‘“ + beanName +
“‘ as bean name and “ + aliases + “ as aliases”);
}
}
if (containingBean == null) {
//bean名称唯一性检查
checkNameUniqueness(beanName, aliases, ele);
}
//parseBeanDefinitionElement里边会解析xml得到bean的class的名字
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
//definition.getParentName() + “$child” + “#1” or
//definition.getFactoryBeanName() + “$created” + “#1”
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.
//获取到bean的类的名字,类的全限定名
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);
//BeanDefinitionHolder持有beanDefinition、bean的名字,bean的别名数组
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
public static final String CLASS_ATTRIBUTE = “class”;
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
//bean的类型解析
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
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
//bean的属性的解析
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
//描述相关信息设置
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
//元数据信息配置
parseMetaElements(ele, bd);
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
//构造方法的参数的解析(bean的注入方式一种是set的方式注入(属性注入),一种是构造器的注入)
parseConstructorArgElements(ele, bd);
//属性解析(属性注入),包括ref属性,value属性等
parsePropertyElements(ele, bd);
//qualifier解析
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;
}
protected AbstractBeanDefinition createBeanDefinition(@Nullable String className, @Nullable String parentName)
throws ClassNotFoundException {
return BeanDefinitionReaderUtils.createBeanDefinition(
parentName, className, this.readerContext.getBeanClassLoader());
}
1 | BeanDefinitionReaderUtils根据类名和bean的父级名称封装为AbstractBeanDefinition. |
public static AbstractBeanDefinition createBeanDefinition(
@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setParentName(parentName);
if (className != null) {
if (classLoader != null) {
//设置bean的class对象
bd.setBeanClass(ClassUtils.forName(className, classLoader));
}
else {
//classloader是空的情况,直接返回类对象的名字
bd.setBeanClassName(className);
}
}
return bd;
}
1 | GenericBeanDefinition是AbstractBeanDefinition的子类。 |
private volatile Object beanClass;
public void setBeanClass(@Nullable Class<?> beanClass) {
this.beanClass = beanClass;
}
public void setBeanClassName(@Nullable String beanClassName) {
this.beanClass = beanClassName;
}
public String getBeanClassName() {
Object beanClassObject = this.beanClass;
if (beanClassObject instanceof Class) {
return ((Class<?>) beanClassObject).getName();
}
else {
return (String) beanClassObject;
}
}
1 |
|
public static Class<?> forName(String name, @Nullable ClassLoader classLoader)
throws ClassNotFoundException, LinkageError {
Assert.notNull(name, “Name must not be null”);
//原生类型的解析
Class> clazz = resolvePrimitiveClassName(name);
if (clazz == null) {
clazz = commonClassCache.get(name);
}
if (clazz != null) {
return clazz;
}
//数组类型的解析
// "java.lang.String[]" style arrays
if (name.endsWith(ARRAY_SUFFIX)) {
String elementClassName = name.substring(0, name.length() - ARRAY_SUFFIX.length());
Class> elementClass = forName(elementClassName, classLoader);
return Array.newInstance(elementClass, 0).getClass();
}
// “[Ljava.lang.String;” style arrays
if (name.startsWith(NON_PRIMITIVE_ARRAY_PREFIX) && name.endsWith(“;”)) {
String elementName = name.substring(NON_PRIMITIVE_ARRAY_PREFIX.length(), name.length() - 1);
Class<?> elementClass = forName(elementName, classLoader);
return Array.newInstance(elementClass, 0).getClass();
}
// “[[I” or “[[Ljava.lang.String;” style arrays
if (name.startsWith(INTERNAL_ARRAY_PREFIX)) {
String elementName = name.substring(INTERNAL_ARRAY_PREFIX.length());
Class<?> elementClass = forName(elementName, classLoader);
return Array.newInstance(elementClass, 0).getClass();
}
ClassLoader clToUse = classLoader;
if (clToUse == null) {
clToUse = getDefaultClassLoader();
}
try {
//调用jdk的Class.forName返回class的对象
return Class.forName(name, false, clToUse);
}
catch (ClassNotFoundException ex) {
int lastDotIndex = name.lastIndexOf(PACKAGE_SEPARATOR);
if (lastDotIndex != -1) {
String innerClassName =
name.substring(0, lastDotIndex) + INNER_CLASS_SEPARATOR + name.substring(lastDotIndex + 1);
try {
return Class.forName(innerClassName, false, clToUse);
}
catch (ClassNotFoundException ex2) {
// Swallow - let original exception get through
}
}
throw ex;
}
}
1 | 回到BeanDefinitionParserDelegate的parseBeanDefinitionElement方法,【AbstractBeanDefinition bd = createBeanDefinition(className, parent);】创建完毕之后,接下里是parseBeanDefinitionAttributes(),完成bean的属性的解析: |
private static final String SINGLETON_ATTRIBUTE = “singleton”;
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
@Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {
//bean的作用域范围是singleton的时候不支持,报告错误【历史遗留问题】
if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
error(“Old 1.x ‘singleton’ attribute in use - upgrade to ‘scope’ declaration”, ele);
}
else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
//将scope的值取出来,然后设置到AbstractBeanDefinition里边,默认是singleton。
bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
}
}
1 | parseBeanDefinitionAttributes方法会对很对属性进行解析和配置: |
//bean元素的解析和注册
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//解析bean的定义,构造成BeanDefinitionHolder,是bean的完整的定义
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
//对bean的定义进行最终修饰
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
//bdHolder是解析出来的bean的定义信息,getReaderContext().getRegistry()是工厂,即
//将bean注册到工厂里边
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));
}
}
1 | 经过对bean的解析,我们得到了bean的定义BeanDefinitionHolder。 |
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
//获取bean的名字
String beanName = definitionHolder.getBeanName();
//将bean的名字和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 | 工厂的注册方法registerBeanDefinition: |
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
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 {
//对bean进行验证
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
“Validation of bean definition failed”, ex);
}
}
//根据bean的名字得到bean的定义对象,spring工厂最核心的容器就是一个ConcurrentHashMap
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
//当前容器存在这个bean
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 + “]”);
}
}
//当前bean和既有的bean不相同,打印日志
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 + “]”);
}
}
//往集合里边塞入当前bean的定义
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
//工厂中不存在当前参数的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);
}
}
1 | 此时工厂的ConcurrentHashMap里边就会存在bean的定义的key-value对。 |
//Send registration event.
//观察者模式,bean的注册的时候会触发一些事件,通知观察者
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
1 | 回到org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseDefaultElement方法, |
protected void doRegisterBeanDefinitions(Element root) {
……
preProcessXml(root);
//bean的解析和注册
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);
……
}
1 |
|
Resource resource = new ClassPathResource(“applicationContext.xml”);
DefaultListableBeanFactory defaultListableBeanFactory
= new DefaultListableBeanFactory();
BeanDefinitionReader beanDefinitionReader =
new XmlBeanDefinitionReader(defaultListableBeanFactory);
beanDefinitionReader.loadBeanDefinitions(resource);
关于spring bean实例的注册流程
1. 定义好spring的配置文件
2. 通过Resource对象将spring配置文件进行抽象,抽象成一个具体的Resource对象(如ClassPathResource)
3. 定义好将要使用的bean工厂(各种BeanFactory)
4. 定义好XmlBeanDefinationReader对象,并将工厂对象作为参数传递进去,从而构建好二者之间的关联关系
5. 通过XmlBeanDefinationReader对象读取之前所抽取出的Rresource对象
6. 流程开始尽心解析
7. 针对XML文件进行各种元素属性的解析,这里面,真正的解析是通过BeanDefinationParserDelegate对象来完成的(委托模式)
8. 通过BeanDefinationParserDelegate对象在解析XML文件时,又使用了模板方法设计模式(pre,process,post)
9. 当所有的bean元素标签元素都解析完毕后,开始定义一个BeanDefination对象,该对象是一个非常重要的对象,里面容纳了一个bean相关的所有属性。
10. BeanDefination对象创建完毕后,Spring又会创建一个BeanDefinationHolder对象来持有这个BeanDefination对象。
11. BeanDefinationHolder对象主要包含两部分内容:beanName和BeanDefination。
12. 工厂将会解析出来的Bean信息存放到内部的一个ConcurrentHashMap中,该Map的键是beanName(唯一),值是beanDefination对象。
13. 调用bean解析完毕的触发动作,从而触发相应的监听器的方法的执行(使用到了观察者模式)