开发者

Spring中Bean注入源码示例解析

开发者 https://www.devze.com 2023-01-16 10:37 出处:网络 作者: 陈汤姆
目录BeanDefinition和BeanBeanDefinition的注入BeanDefinitionRegistry接口BeanDefinitionRegistry的实现类SimpleBeanDefinitionRegistryDefaultListableBeanFactoryBean的注入SingletonBeanRegistry接口SingletonBe
目录
  • BeanDefinition和Bean
  • BeanDefinition的注入
    • BeanDefinitionRegistry接口
    • BeanDefinitionRegistry的实现类
    • SimpleBeanDefinitionRegistry
    • DefaultListableBeanFactory
  • Bean的注入
    • SingletonBeanRegistry接口
    • SingletonBeanRegistry的实现类
    • AbstractBeanFactory
    • DefaultSingletonBeanRegistry
  • 总结

    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的实现类

    Spring中Bean注入源码示例解析

    找到操作BeanDefinition的接口就可以通过接口查看接口的实现类,进而找到BeanDefinition的应用。

    BeanDefinition常见的几个实现类有:

    • DefaultListableBeanFactory
    • SimpleBeanDefinitionRegistry

    SimpleBeanDefinitionRegistry

    public class Simplewww.devze.comBeanDefinitionRegistry 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: replaciVfOiCwng [" + 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.isandroidPrototype()) {//原型模式下的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, () -> {
    			android				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, singletoVfOiCwnObject);
    		}
    	}
    	/**
    	* 将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注入的资料请关注我们其它相关文章!

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号