Spring中Bean注入源码示例解析
作者:陈汤姆
BeanDefinition和Bean
在Spring中Bean的注入涉及两部分:
- BeanDefinition
- Bean
两个对象存在先后顺序,先注入BeanDefinition之后才执行Bean对象的注入。
那么两者有什么关联呢?
BeanDefinition和Bean的关系:可以理解为BeanDefinition是Bean的包装类,类似Java中类和属性的关系。
BeanDefinition是对Bean对象的包装,BeanDefinition中封装了Bean相关的描述,比如bean对象,bean的单例还是原型、bean的父级、懒加载方式等等。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { void setScope(@Nullable String scope); @Nullable String getScope(); void setLazyInit(boolean lazyInit); boolean isLazyInit(); } //bean的原数据 public interface BeanMetadataElement { @Nullable Object getSource(); }
在BeanDefinition中继承了BeanMetadataElement,该类是Bean的原数据,该类中实例化了Bean对象为Object。因此在BeanDefinition中调用getSource就可以获取到Bean对象。
分清楚BeanDefinition和Bean之后再看BeanDefinition的注入,因为只有注入了BeanDefinition才会注入后续的Bean。
BeanDefinition的注入
BeanDefinitionRegistry接口
BeanDefinitin的注入通过接口BeanDefinitionRegistry抽象了各种对BeanDefinition的操作,例如
- BeanDefinitionRegistry#registerBeanDefinition(注入到beanDefinition中)
- BeanDefinitionRegistry#removeBeanDefinition(从beanDefinition容器中移除)
- BeanDefinitionRegistry#getBeanDefinition(获取BeanDefinition)
public interface BeanDefinitionRegistry extends AliasRegistry { void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException; void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; boolean containsBeanDefinition(String beanName); String[] getBeanDefinitionNames(); int getBeanDefinitionCount(); boolean isBeanNameInUse(String beanName); }
该接口是操作BeanDefinition的基础接口,该类是一个接口类型并不是一个抽象类,因此该接口中不会定义任何BeanDefinition的容器,BeanDefinition的容器只在各实现类中定义并使用。任何需要操作BeanDefinition的实现都需要实现该接口。
BeanDefinitionRegistry的实现类
找到操作BeanDefinition的接口就可以通过接口查看接口的实现类,进而找到BeanDefinition的应用。
BeanDefinition常见的几个实现类有:
- DefaultListableBeanFactory
- SimpleBeanDefinitionRegistry
SimpleBeanDefinitionRegistry
public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements BeanDefinitionRegistry { /**beanDefinition的容器,通过ConcurrentHashMap实现. */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(64); //该类的实现方法只是实现了最简单的beanDefinition的注入,在Java开发环境中并不会使用该实现类 @Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "'beanName' must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); this.beanDefinitionMap.put(beanName, beanDefinition); } }
该实现类中只做了最简单的注入功能,没有任何的逻辑处理,因此在实际开发过程中Spring并不会使用该类。
DefaultListableBeanFactory
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { //beanDefinition的容器 private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256); //向BeanFactory中注入BeanDefinition 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) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); //判断beanDefinition容器中是否已存在该beanDefinition 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 + "]"); } } //覆盖beanDefinition this.beanDefinitionMap.put(beanName, beanDefinition); } else { //容器中不存在该beanDefinition的处理 if (hasBeanCreationStarted()) { synchronized (this.beanDefinitionMap) { //对beanDefinition加锁 //注入该beanDefinition this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } } }
DefaultListableBeanFactory是默认使用的注入BeanDefinition的实现类,可以看到该实现类中对注入BeanDefinition做了很多的逻辑判断,日常开发启动容器过程中都会使用该实现类注入BeanDefinition进行后续的Bean注入。
Bean的注入
BeanDefinition注入后后续执行Bean的注入,bean注入的方式也是将bean注入到bean的容器中,因此在Spring中BeanDefinition和Bean都是通过容器化的方式操作的,那么在Bean的注入中也通过对应的接口定义对Bean的操作,该接口就是SingletonBeanRegistry。
SingletonBeanRegistry接口
该接口实现了对Bean的操作:
- SingletonBeanRegistry#registerSingleton(将bean注入到容器中)
- SingletonBeanRegistry#getSingleton(从容器中获取bean)
public interface SingletonBeanRegistry { //注入bean void registerSingleton(String beanName, Object singletonObject); //获取bean @Nullable Object getSingleton(String beanName); //是否存在bean boolean containsSingleton(String beanName); String[] getSingletonNames(); int getSingletonCount(); Object getSingletonMutex(); }
SingletonBeanRegistry的实现类
SingletonBeanRegistry的实现类有多个,分别为:
- AbstractBeanFactory
- DefaultListableBeanFactory
- DefaultSingletonBeanRegistry
- FactoryBeanRegistrySupport
- AbstractAutowireCapableBeanFactory
下面说两个有代表性的:AbstractBeanFactory和DefaultSingletonBeanRegistry
AbstractBeanFactory
该实现类是一个抽象类,即该类是bean的工厂类,其中主要实现的是可以复用的具体逻辑,该抽象类中包含获取bean、beanPostProcessor、初始化bean、销毁bean等对bean的操作抽象类。
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { //获取bean的方式平时使用ApplicationContext就是最终调用该方法 public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); } @Override public Object getBean(String name, Object... args) throws BeansException { return doGetBean(name, null, args, false); } public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args) throws BeansException { return doGetBean(name, requiredType, args, false); } /** * 从容器中获取bean的主要逻辑 */ protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { //省略部分代码 try { //先获取beanDefinition final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // 单例模式下获取bean的方式 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) {//原型模式下的bean的获取 // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); //原型模式每次都需要创建bean prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } //省略部分代码 return (T) bean; } //将实现beanPostProcessor的实现类加入到链表中用于对bean的前置或者后置处理 @Override public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) { Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null"); // Remove from old position, if any this.beanPostProcessors.remove(beanPostProcessor); // Track whether it is instantiation/destruction aware if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { this.hasInstantiationAwareBeanPostProcessors = true; } if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) { this.hasDestructionAwareBeanPostProcessors = true; } // Add to end of list this.beanPostProcessors.add(beanPostProcessor); } //销毁bean的方法 @Override public void destroyBean(String beanName, Object beanInstance) { destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName)); } protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) { new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy(); } }
DefaultSingletonBeanRegistry
该实现类通过名字也可以推断出该实现类是对单例bean的注入,该类中实现了bean的所有容器,平时开发过程中Spring容器启动就是使用了该实现类中的容器,该实现类是对bean最终注入的实现,涉及的四个容器主要有:
- singletonObjects
- singletonFactories
- earlySingletonObjects
- registeredSingletons
四个容器其中三个的核心作用是解决循环依赖,这里不展开说。
找一条主线梳理下Bean注入的过程,当BeanDefinition注入成功后,后续执行bean的注入,以AbstractAutowireCapableBeanFactory的实现为例,该实现类中会对bean的注入,整个注入的链路如下:
- 获取资源数据:CommonAnnotationBeanPostProcessor#autowireResource
- 通过beanName解析bean:AbstractAutowireCapableBeanFactory#resolveBeanByName
- 调用抽象类中获取bean:AbstractBeanFactory#getBean
- 执行抽象类中获取bean的核心逻辑:AbstractBeanFactory#doGetBean
- bean不存在时创建bean:AbstractAutowireCapableBeanFactory#createBean
- 获取单例bean:efaultSingletonBeanRegistry#getSingleton
- 单例bean不存在将类注入到容器中:DefaultSingletonBeanRegistry#addSingleton
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { //单例bean的容器,开发过程中获取的bean都是从该容器中获取的:即所谓的一级缓存 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); //单例bean的beanFactory的容器:即所谓的三级缓存 private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); //提前初始化的bean的容器,该容器的bean并没有任何属性值只是提前将bean注入到该容器中用于后续的判断 //即所谓的二级缓存 private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); //已注册的单例bean的beanName列表 private final Set<String> registeredSingletons = new LinkedHashSet<>(256); //注入bean的方法 public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { Assert.notNull(beanName, "Bean name must not be null"); Assert.notNull(singletonObject, "Singleton object must not be null"); synchronized (this.singletonObjects) { Object oldObject = this.singletonObjects.get(beanName); if (oldObject != null) { throw new IllegalStateException("Could not register object [" + singletonObject + "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound"); } addSingleton(beanName, singletonObject); } } /** * 将bean注入容器中,操作四个容器主要用于bean的循环依赖问题 */ protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } }
总结
以上就是对bean注入从源码的梳理,该梳理主要从bean注入前的准备(beanDefinition的注入)和bean注入的实现来完成,从整个梳理中学到最多的主要有两点:
- 抽象的思想:在BeanDefinition的实现和Bean的实现逻辑中,都完成高度抽象并且遵循单一原则和高度抽象,代码的可扩展性和复用性很高,我们作为开发者也可以通过Spring暴露的各种Registry接口实现对Bean的操作。
- 容器化思想:从BeanDefinition和Bean的注入来看,整个的实现思路都是基于容器化思想来实现的,将开发中需要关心的对象都实例化到容器中,开发者在使用时只要从容器中获取即可,并且获取bean的方式也很灵活,开发者在使用和扩展性上更便利。
对于源码的学习自己理解来说并不是背其中的代码,而是学习大佬实现代码的思想,为什么可以抽象出扩展性这么高的代码,并且从源头梳理下来都能很轻松的按照主线一步一步梳理到目的地,这也是每个开发者需要学习的地方,提高自己代码的可读性和可扩展性,能够掌握面向对象的核心:封装、继承、多态。
以上就是Spring中Bean注入源码示例解析的详细内容,更多关于Spring Bean注入的资料请关注脚本之家其它相关文章!