spring IOC 之篇三:默认标签的解析
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 doRegisterBeanDefinitions(ele); } }
这里主要分新bean标签的处理,其他都类似
/** * Process the given bean element, parsing the bean definition * and registering it with the registry. */ protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { // 首先委托 BeanDefinitionParserDelegate 类的parseBeanDefinitionElement方法进行元素的解析,返回实例BeanDefinitionHolder 对象,经过这个方法后,bdHolder实例已经包含我们配置的配置文件中的各种属性了,列如:class,id,alias之类的属性了。 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { // 当返回的BeanDefinitionHolder对象实例 bdHolder不为空的情况下若存在默认标签的字节点下再有自定义属性,还需要再次对自定义属性进行解析。 bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // Register the final decorated instance. //解析完成后,需要对解析后的bdHolder进行注册,同样,注册操作委托给了BeanDefinitionReaderUtils的registerBeanDefinition方法。 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } // Send registration event. //最后发出响应事件,通知相关的监听器,这个bean已经加载完成了。 getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
继续深入分析 BeanDefinitionParserDelegate 类的parseBeanDefinitionElement方法:
/** * Parses the supplied {@code <bean>} element. May return {@code null} * if there were errors during parse. Errors are reported to the * {@link org.springframework.beans.factory.parsing.ProblemReporter}. */ public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) { // 解析id属性 String id = ele.getAttribute(ID_ATTRIBUTE); // 解析name属性 String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); // 分隔name属性 List<String> aliases = new ArrayList<String>(); 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.isDebugEnabled()) { logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); } } if (containingBean == null) { checkNameUniqueness(beanName, aliases, ele); } // 进一步解析bean的其他属性 并封装到对象 GenericBeanDefinition对象中 AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); if (beanDefinition != null) { if (!StringUtils.hasText(beanName)) { try { if (containingBean != null) { // 如果不存在 beanName,则使用Spring提供的命名规则默认生成beanName beanName = BeanDefinitionReaderUtils.generateBeanName( beanDefinition, this.readerContext.getRegistry(), true); } else { // 如果有则获取beanName 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.isDebugEnabled()) { logger.debug("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 实例中去
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); } return null; }
接下来进一步分析对其他bean标签的解析方法:
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
/** * Parse the bean definition itself, without regard to name or aliases. May return * {@code null} if problems occurred during the parsing of the bean definition. */ public AbstractBeanDefinition parseBeanDefinitionElement( Element ele, String beanName, BeanDefinition containingBean) { this.parseState.push(new BeanEntry(beanName)); String className = null; // 解析class属性 if (ele.hasAttribute(CLASS_ATTRIBUTE)) { className = ele.getAttribute(CLASS_ATTRIBUTE).trim(); } try { String parent = null; // 解析parent属性 if (ele.hasAttribute(PARENT_ATTRIBUTE)) { parent = ele.getAttribute(PARENT_ATTRIBUTE); } // 创建用于承载bean各种标签的 GenericBeanDefinition对象 AbstractBeanDefinition bd = createBeanDefinition(className, parent); // 硬编码解析bean的属性 例如:singleton、destroy-method等 parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); // 提取 desciption bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT)); // 解析元数据 parseMetaElements(ele, bd); // 解析lookup-method属性 parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); // 解析repalce-method属性 parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); // 解析构造函数参数 parseConstructorArgElements(ele, bd); // 解析property字元素 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; }
进一步分析创建属性承载的BeanDefinition对象
BeanDefinition是一个接口,spring中三种实现形式:RootBeanDefinition、ChildBeanDefinition和GenericBeanDefinition。三种实现类均继承了AbstractBeanDefinition,其中BeanDefinition是<bean>标签在容器内部的表现形式,BeanDefinition和<bean>的属性是一一对应的。Spring通过BeanDefinition将配置文件中的信息装换为内部的表现形式,并将这些BeanDefinition注册到BeanDefinitionRegistry中。
至此 已经完成XML文档像GenericBeandefinition的全部装换。GenericBeandefinition只是子类实现,大部分属性封装在AbstractBeandefinition对象中,我们继续分析AbstractBeandefinition的给中属性:
@SuppressWarnings("serial") public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable { /** * 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 = ""; /** * Constant that indicates no 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. * <p>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)"; private volatile Object beanClass; // bean的作用范围,对应bean的属性 scope private String scope = SCOPE_DEFAULT; // 是否抽象标识,默认false,对应bean的属性 abstract private boolean abstractFlag = false; // 是否延迟加载,对应bean的属性 lazy-init private boolean lazyInit = false; // 是否自动注入模式,对应bean的属性autowire private int autowireMode = AUTOWIRE_NO; // 依赖检查,spring3以后弃用这个属性 private int dependencyCheck = DEPENDENCY_CHECK_NONE; // 用来表示一个bean的实例化,依赖另一个bean实例化,对应bean的属性depend-on private String[] dependsOn; // autowire-candidate属性设置为false,这样容器在查找自动装配对象的时候,将不会考虑该bean,即不会考虑该bean作为其他bean的自动装配候选者 private boolean autowireCandidate = true; // 当自动装配出现多个bean,如果primary为true,则改bean作为首席候选者 private boolean primary = false; // 用于记录 Qualifier 对应子元素 qualifier private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<String, AutowireCandidateQualifier>(0); private boolean nonPublicAccessAllowed = true; private boolean lenientConstructorResolution = true; //记录构造函数注入属性,对应属性值 constructor-arg private ConstructorArgumentValues ArgumentValues; // 普通属性集合 private MutablePropertyValues propertyValues; // 记录 lookup-method和replace-method属性值 private MethodOverrides methodOverrides = new MethodOverrides(); private String factoryBeanName; private String factoryMethodName; // 初始化方法 对应属性 init-method private String initMethodName; // 销毁方法 对应属性 destroy-method private String destroyMethodName; // 是否执行 init-method 程序设置 private boolean enforceInitMethod = true; // 是否执行 destroy-method 程序设置 private boolean enforceDestroyMethod = true; // 使用用户自定义而不是应用程序本身定义的,创建AOP时候为true private boolean synthetic = false; private int role = BeanDefinition.ROLE_APPLICATION; private String description; // 这个bean定义的资源 private Resource resource;
解析完成以后,会将所有的xml属性值封装至对象 GenericBeanDefinition中,然后会进行注册。
针对以下代码进行分析:
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())
// 解析完以后,BeanDefinition对象就注册到了BeanDefinitionRegisty集合中去了。将beanName作为Key,BeanDefinition作为value。
/** * Register the given bean definition with the given bean factory. * @param definitionHolder the bean definition including name and aliases * @param registry the bean factory to register with * @throws BeanDefinitionStoreException if registration failed */ public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // Register bean definition under primary name. // 使用beanName作为唯一注册标识 String beanName = definitionHolder.getBeanName(); registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); // Register aliases for bean name, if any. // 注册所有的bean的别名 String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String alias : aliases) { registry.registerAlias(beanName, alias); } } }
继续深入解析:
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
@Override 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 { // 注册前的最后一次校验,这里主要校验AbstractBeandefinition 中的methodOverrides 属性,校验methodOverrides是否与工厂方法共存,或者对应的方法根本不存在 ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition oldBeanDefinition; oldBeanDefinition = this.beanDefinitionMap.get(beanName); if (oldBeanDefinition != null) { // 对于已经注册过的bean,如果不允许覆盖,则直接抛出异常 if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound."); } else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (this.logger.isWarnEnabled()) { this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(oldBeanDefinition)) { if (this.logger.isInfoEnabled()) { this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else { if (this.logger.isDebugEnabled()) { this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) //因为 beanDefinitionMap 是全局变量,这里会存在并发的情况 synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { // Still in startup registration phase // 注册beanDefinition this.beanDefinitionMap.put(beanName, beanDefinition); // 记录所有的beanNames this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } if (oldBeanDefinition != null || containsSingleton(beanName)) { // 重置beanName所有的对应的缓存 resetBeanDefinition(beanName); } }
注册完成,通知所有的监听事件:
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
这里是spring留给子类进行扩展的。