这里我们首先来讲抽象 bean如何解析及实现属性的继承的
先上示例。
Car.java
@Data public class Car { private String brand; private int maxSpeed; private String color; }
spring27_abstract_bean.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--所以声明为 abstract = "true" 表示这个<bean> 不实例化为一个对应的 bean , 在代码清单中,如果用户没有指定 abstract="true ", Spring ioc 容器将实例化一个名为 abstractCar 的 bean --> <bean id="abstract" class="com.spring_1_100.test_21_30.test27_abstract_bean.Car" p:maxSpeed="300" abstract="true"></bean> <bean id="abstractCar" class="com.spring_1_100.test_21_30.test27_abstract_bean.Car" p:brand="红旗 CA72" abstract="true" parent="abstract"></bean> <bean id="car4" p:color="黑色" parent="abstractCar"></bean> </beans>
Test27.java
public class Test27 { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring_1_100/config_21_30/spring27_abstract_bean.xml"); Car car =(Car) ac.getBean("car4"); System.out.println(JSON.toJSONString(car)); } }
结果输出
首先我们来看 bean 的解析。
parent:标签解析
public static AbstractBeanDefinition createBeanDefinition( String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException { GenericBeanDefinition bd = new GenericBeanDefinition(); // parentName 可能为空 bd.setParentName(parentName); if (className != null) { if (classLoader != null) { // 如果classLoader不为空。则使用传入的classLoader同一虚拟机 // 记录className bd.setBeanClass(ClassUtils.forName(className, classLoader)); } else { bd.setBeanClassName(className); } } return bd; }
abstract的解析:
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, BeanDefinition containingBean, AbstractBeanDefinition bd) { // 解析scope 属性 if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele); } else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) { bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE)); } else if (containingBean != null) { // Take default from containing bean in case of an inner bean definition. // 在嵌入beanDefinition的情况下且没有单独指定scope的属性则使用父类默认的 bd.setScope(containingBean.getScope()); } //解析abstract属性 if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) { bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE))); } // 解析lazy-init属性 String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE); if (DEFAULT_VALUE.equals(lazyInit)) { lazyInit = this.defaults.getLazyInit(); } //若没有设置或者设置其他的字符会被设置为false bd.setLazyInit(TRUE_VALUE.equals(lazyInit)); //解析autowire属性 String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE); bd.setAutowireMode(getAutowireMode(autowire)); // 解析dependency-check属性 String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE); bd.setDependencyCheck(getDependencyCheck(dependencyCheck)); //解析depends-on属性 if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) { String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE); bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS)); } //解析autowire-candidate属性 String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE); if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(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属性 if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) { bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE))); } //解析init-method属性 if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) { String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE); if (!"".equals(initMethodName)) { bd.setInitMethodName(initMethodName); } } else { if (this.defaults.getInitMethod() != null) { bd.setInitMethodName(this.defaults.getInitMethod()); bd.setEnforceInitMethod(false); } } //解析destroy-method属性 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属性 if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) { bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE)); } // 解析factory-bean属性 if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) { bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE)); } return bd; }
而对于普通的属性 p:color 的解析将在SimplePropertyNamespaceHandler中进行解析
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) { if (node instanceof Attr) { Attr attr = (Attr) node; String propertyName = parserContext.getDelegate().getLocalName(attr); String propertyValue = attr.getValue(); MutablePropertyValues pvs = definition.getBeanDefinition().getPropertyValues(); if (pvs.contains(propertyName)) { parserContext.getReaderContext().error("Property '" + propertyName + "' is already defined using " + "both and inline syntax. Only one approach may be used per property.", attr); } if (propertyName.endsWith(REF_SUFFIX)) { propertyName = propertyName.substring(0, propertyName.length() - REF_SUFFIX.length()); pvs.add(Conventions.attributeNameToPropertyName(propertyName), new RuntimeBeanReference(propertyValue)); } else { pvs.add(Conventions.attributeNameToPropertyName(propertyName), propertyValue); } } return definition; }
最终保存到BeanDefinition 的MutablePropertyValues中。
Bean 的初始化和依赖注入,这样当应用程序第一次向容器索取所需要的Bean时,容器不再需要对Bean进行初始化的依赖注入可直接从已经完成的实例化和依赖注入的Bean中取一个现在的Bean ,提高第一次获取Bean的性能
DefaultListableBeanFactory.java
@Override public void preInstantiateSingletons() throws BeansException { if (this.logger.isDebugEnabled()) { this.logger.debug("Pre-instantiating singletons in " + this); } List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { // 获取指定名称的Bean 定义 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // Bean 不是抽象的,是单例模式的,且lazy-init属性配置为false if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // 如果指定的名称的Bean是创建容器的Bean if (isFactoryBean(beanName)) { // FACTORY_BEAN_PREFIX="&",当Bean 名称前面加了&符号时,获取的是容器对象本身,而不是容器产生的Bean // 调用getBean 方法,触发Bean实例化,和依赖注入 final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); // 标识是否需要预实例化 boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { // 一个匿名的内部类 isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { @Override public Boolean run() { return ((SmartFactoryBean<?>) factory).isEagerInit(); } }, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { // 调用getBean()方法,触发Bean实例化和依赖注入 getBean(beanName); } } else { getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { smartSingleton.afterSingletonsInstantiated(); return null; } }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
因此,在创建过程中,对于抽象类,不会被创建,而对于普通的类,如果填充了 parent 属性,则会从父类中继承 BeanDefinition 中的属性。
AbstractBeanFactory.java
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null) { return mbd; } return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); }
AbstractBeanFactory.java
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd) throws BeanDefinitionStoreException { return getMergedBeanDefinition(beanName, bd, null); }
AbstractBeanFactory.java
protected RootBeanDefinition getMergedBeanDefinition( String beanName, BeanDefinition bd, BeanDefinition containingBd) throws BeanDefinitionStoreException { synchronized (this.mergedBeanDefinitions) { RootBeanDefinition mbd = null; // Check with full lock now in order to enforce the same merged instance. if (containingBd == null) { mbd = this.mergedBeanDefinitions.get(beanName); } if (mbd == null) { if (bd.getParentName() == null) { // Use copy of given root bean definition. if (bd instanceof RootBeanDefinition) { mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); } else { mbd = new RootBeanDefinition(bd); } } else { // Child bean definition: needs to be merged with parent. BeanDefinition pbd; try { String parentBeanName = transformedBeanName(bd.getParentName()); if (!beanName.equals(parentBeanName)) { //如果配置了 parent ,则反复的调用 BeanDefinition的合并方法 pbd = getMergedBeanDefinition(parentBeanName); } else { if (getParentBeanFactory() instanceof ConfigurableBeanFactory) { pbd = ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(parentBeanName); } else { throw new NoSuchBeanDefinitionException(bd.getParentName(), "Parent name '" + bd.getParentName() + "' is equal to bean name '" + beanName + "': cannot be resolved without an AbstractBeanFactory parent"); } } } catch (NoSuchBeanDefinitionException ex) { throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex); } // Deep copy with overridden values. mbd = new RootBeanDefinition(pbd); //mbd父亲的BeanDefinition, bd子的 beanDefinition mbd.overrideFrom(bd); } // Set default singleton scope, if not configured before. 其他的属性是子 BeanDefinition 覆盖父 BeanDefinition,而只有 Scope属性,被父亲保留 if (!StringUtils.hasLength(mbd.getScope())) { mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON); } // A bean contained in a non-singleton bean cannot be a singleton itself. // Let's correct this on the fly here, since this might be the result of // parent-child merging for the outer bean, in which case the original inner bean // definition will not have inherited the merged outer bean's singleton status. if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) { mbd.setScope(containingBd.getScope()); } // Only cache the merged bean definition if we're already about to create an // instance of the bean, or at least have already created an instance before. if (containingBd == null && isCacheBeanMetadata()) { this.mergedBeanDefinitions.put(beanName, mbd); } } return mbd; } }
AbstractBeanDefinition.java
public void overrideFrom(BeanDefinition other) { //复制子类的 beanClassName if (StringUtils.hasLength(other.getBeanClassName())) { setBeanClassName(other.getBeanClassName()); } //复制子类FactoryBeanName if (StringUtils.hasLength(other.getFactoryBeanName())) { setFactoryBeanName(other.getFactoryBeanName()); } //复制子类FactoryMethodName if (StringUtils.hasLength(other.getFactoryMethodName())) { setFactoryMethodName(other.getFactoryMethodName()); } //复制子类Scope 属性 if (StringUtils.hasLength(other.getScope())) { setScope(other.getScope()); } //复制子类Abstract 属性 setAbstract(other.isAbstract()); //复制子类lazyInit setLazyInit(other.isLazyInit()); setRole(other.getRole()); //复制子类构造函数参数getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues()); //复制子类属性参数 getPropertyValues().addPropertyValues(other.getPropertyValues()); setSource(other.getSource()); copyAttributesFrom(other); if (other instanceof AbstractBeanDefinition) { AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other; if (otherAbd.hasBeanClass()) { setBeanClass(otherAbd.getBeanClass()); } setAutowireCandidate(otherAbd.isAutowireCandidate()); setAutowireMode(otherAbd.getAutowireMode()); copyQualifiersFrom(otherAbd); setPrimary(otherAbd.isPrimary()); setDependencyCheck(otherAbd.getDependencyCheck()); setDependsOn(otherAbd.getDependsOn()); setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed()); setLenientConstructorResolution(otherAbd.isLenientConstructorResolution()); if (StringUtils.hasLength(otherAbd.getInitMethodName())) { setInitMethodName(otherAbd.getInitMethodName()); setEnforceInitMethod(otherAbd.isEnforceInitMethod()); } if (otherAbd.getDestroyMethodName() != null) { setDestroyMethodName(otherAbd.getDestroyMethodName()); setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod()); } getMethodOverrides().addOverrides(otherAbd.getMethodOverrides()); setSynthetic(otherAbd.isSynthetic()); setResource(otherAbd.getResource()); } else { setResourceDescription(other.getResourceDescription()); } }
这个方法主要是将子BeanDefinition 覆盖父的 BeanDefinition,重而得到全新的 BeanDefinition定义。并且递归调用。在本例中,先用 car4的 BeanDefinition 覆盖掉 abstractCar 的 BeanDefinition,再用新的 beanDefinition 覆盖掉 abstract 的 BeanDefinition,最终得到合并的 beanDefinition 作为 car4 的 BeanDefinition,因此,car4 有了 abstractCar 配置的 brand 属性,有 abstract 配置的 maxSpeed 属性、
而 abstract 类在 Spring 中是不会被实例化的,因此,在配置的 bean 中,只有 car4最终被实例化,并且有从父类继承而来的属性 brand 和 maxSpeed 属性。
总结 :
在本例中,其实不是非常的复杂,在理解 beanDefinition 的合并是,需要注意一下,子类继承父类,其实就是子类的属性覆盖掉父类的属性,而得到的一个超级类。不过还是那句话,学习源码,一定要自己调试。
本文的 github地址是https://github.com/quyixiao/spring_tiny/tree/master/src/main/java/com/spring_1_100/test_21_30/test27_abstract_bean