文档章节

spring application 之 BeanFactory

my_juke
 my_juke
发布于 05/19 18:14
字数 2296
阅读 7
收藏 0

org.springframework.core.AliasRegistry

给Bean取别名,可以用多个名称对应同一个Bean
默认实现:org.springframework.core.SimpleAliasRegistry
这个有个小技巧:
	/** Map from alias to canonical name */
	private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);
我们知道一个Bean的名称可以有多个别名,这里把key当作别名,value当作bean的名称

org.springframework.beans.factory.support.BeanDefinitionRegistry

继承自:AliasRegistry
获取BeanDefinition,注册BeanDefinition
默认实现:org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry
里面就一个Map:private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(64);

org.springframework.beans.factory.config.SingletonBeanRegistry

老接口:注册单例Bean的
默认实现:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
管理单例Bean的依赖,创建,销毁

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

//直接注册单例
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException;

//创建完毕后,缓存到Map
protected void addSingleton(String beanName, Object singletonObject);

//解决单例循环依赖的问题,创建过程中会将还未完全初始化的Bean放入ObjectFactory中
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory);

//获取单例Bean,解决循环依赖
protected Object getSingleton(String beanName, boolean allowEarlyReference);

//创建单例Bean时,会将Bean包装成ObjectFactory,调用该类进行获取
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory);

org.springframework.beans.factory.support.FactoryBeanRegistrySupport

解决FatoryBean的问题

org.springframework.beans.factory.BeanFactory

获取Bean

org.springframework.beans.factory.HierarchicalBeanFactory

父BeanFactory

org.springframework.beans.factory.config.ConfigurableBeanFactory

对BeanFactory进行配置
默认支持两种作用域:单例,原型 
void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);
设置EL表达式,解析属性值  #{....}
void setConversionService(@Nullable ConversionService conversionService);
转换器
void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
属性解析器
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
自定义属性解析,与上面的属性解析器是同一个东西

void setTypeConverter(TypeConverter typeConverter);
与ConversionService同一个东西

void addEmbeddedValueResolver(StringValueResolver valueResolver);
字符属性处理器,对字符进行加工

void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
Bean的后置处理器,在创建实例后

org.springframework.beans.factory.support.AbstractBeanFactory

主要是对ConfigurableBeanFactory的实现


protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
		//转换beanName去掉前面的&,并且解决Bean的别名问题
		final String beanName = transformedBeanName(name);
		Object bean;

		// 是否单例模式
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			//是获取FacotryBean,还是获取FacotryBean中的Bean
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// 原型模式,不允许循环依赖,原因是没有缓该Bean
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// 从父BeanFactory中获取
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}
			//是否只进行类型检查,而不获取实例
			if (!typeCheckOnly) {
				//标记已被创建
				markBeanAsCreated(beanName);
			}

			try {
				//检查是否抽像Bean
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				//获取该Bean所依赖的beanName,先初始化依赖Bean
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						//通过DependOn设置的依赖,不允许循环依赖
						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);
						}
					}
				}

				// Create bean instance.
				 if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							//调用AbstractAutowireCapableBeanFactory类创建Bean
							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()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						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;
			}
		}

		//类型不匹配,进行转换
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
			//先获取自定义的TypeConverter,没有就获取系统默认的
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
				if (logger.isDebugEnabled()) {
					logger.debug("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}


org.springframework.beans.factory.config.AutowireCapableBeanFactory

固名思义:装配可用的Bean 包含创建,前置处理,后置处理,依赖Bean的解决

AbstractAutowireCapableBeanFactory.AbstractAutowireCapableBeanFactory

创建Bean的实现类

	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// 是否需要lookup replacMethod
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// 是否可以通过后置处理器直接创建Bean
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
			//创建
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isDebugEnabled()) {
				logger.debug("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

创建过程如下:不贴代码了

1 能否通过后置处理器创建Bean,执行InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation方法,如果可以创建,执行后置初始化方法BeanPostProcessor.postProcessAfterInitialization
2 第一步如果返回不为空的Bean,结束创建过程。否则进入流程3。
3 BeanDefinition中是否有instanceSupplier,如果有通过该函数创建Bean。并返回Bean的包装类BeanWrapper,进入流程8。否则进入流程4。
4 BeanDifinition中是否含有facotryMethod。如果有,通过工厂方法创建,该方法支持参数,instantiateUsingFactoryMethod(beanName, mbd, args),进入流程8。如果无,进入流程5。
5 获取Bean的构造器,通过SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors,这里没有也关系,有的话就用这些指定的构造器。如果构造器不为空,或者BeanDifinition需要通过构造器注入,或者创建Bean传递的参数不空,则进入流程6,有参创建实例,否则进行流程7,无参创建实例。
6 配置合适的构造器与参数,如果含有MethodOverride(LookupOverrideMethodInterceptor,ReplaceOverrideMethodInterceptor)。则采用cglib创建实例,因为需要代理,否则直接创建对象。
7 如果含有MethodOverride(LookupOverrideMethodInterceptor,ReplaceOverrideMethodInterceptor)。则采用cglib创建实例,因为需要代理,否则直接创建对象。
8 合并BeanDinition,如果需要。MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition。进入流程9。
9 set注入,循环依赖解决。暴露一个已经创建好的对象,未设置属性与执行初始化。这里如果有SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference(exposedObject, beanName);可以进一步加工。进入流程10。
10 执行后置处理器:InstantiationAwareBeanPostProcessor..postProcessAfterInstantiation(bw.getWrappedInstance(), beanName),进入流程11。
11 如果是byName或byType的注入方式。通过PropertyDescripter获取Bean,将这些属性设置到BeanDifintion的PropertyValues中。进入流程12。
12 执行后置处理器,InstantiationAwareBeanPostProcessor.postProcessPropertyValues。该处理器主要解决属性注入的问题。
13 设置属性,进入流程14。
14 注入BeanNameAware,BeanClassLoaderAware,BeanFactoryAware。进入流程15。
15 执行后置处理器,BeanPostProcessor.postProcessBeforeInitialization(result, beanName);postDestruct()就是在这里处理的。进入流程16。
16 执行初始化方法。如果有实现InitializingBean接口,就执行afterPropertiesSet()方法。进入流程17。
17 执行后置处理器,BeanPostProcessor.postProcessAfterInitialization。进入流程18
18 注册销毁Bean的方法,包括destroy,close,shutdown方法,只会注册一个,优先级依次降低。只有单例模式会注册,其它需要从scope中注册。结束流程。

org.springframework.beans.factory.ListableBeanFactory

BeanFactory的补充接口,都是一些获取Bean的扩展方法。

org.springframework.beans.factory.config.ConfigurableListableBeanFactory

辅助接口

org.springframework.beans.factory.support.DefaultListableBeanFactory

BeanFactory的最终实现类,核心方法 resolveDependency,Bean里面的属性注入,就是靠该方法来生成具体的Bean的。

public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

		descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
		//支持jdk8 Optional
		if (Optional.class == descriptor.getDependencyType()) {
			return createOptionalDependency(descriptor, requestingBeanName);
		}
		//支持ObjectFactory,ObjectProvider
		else if (ObjectFactory.class == descriptor.getDependencyType() ||
				ObjectProvider.class == descriptor.getDependencyType()) {
			return new DependencyObjectProvider(descriptor, requestingBeanName);
		}
		else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
			return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
		}
		else {
		//支持懒加载
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);
			//获取具体的Bean的实现方法
			if (result == null) {
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}


@Nullable
	public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

		InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
		try {
			Object shortcut = descriptor.resolveShortcut(this);
			if (shortcut != null) {
				return shortcut;
			}

			Class<?> type = descriptor.getDependencyType();
			//搞定@Value 注解
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
			if (value != null) {
				if (value instanceof String) {
					String strVal = resolveEmbeddedValue((String) value);
					BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
					value = evaluateBeanDefinitionString(strVal, bd);
				}
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				return (descriptor.getField() != null ?
						converter.convertIfNecessary(value, type, descriptor.getField()) :
						converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
			}
			//搞定属性是数组,Map,List等类型的注入
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}
			//存在多个符合要求的类型的解决
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (matchingBeans.isEmpty()) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}

			String autowiredBeanName;
			Object instanceCandidate;

			if (matchingBeans.size() > 1) {
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
				if (autowiredBeanName == null) {
					if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
						return descriptor.resolveNotUnique(type, matchingBeans);
					}
					else {
						// In case of an optional Collection/Map, silently ignore a non-unique case:
						// possibly it was meant to be an empty collection of multiple regular beans
						// (before 4.3 in particular when we didn't even look for collection beans).
						return null;
					}
				}
				instanceCandidate = matchingBeans.get(autowiredBeanName);
			}
			else {
				// We have exactly one match.
				Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
				autowiredBeanName = entry.getKey();
				instanceCandidate = entry.getValue();
			}

			if (autowiredBeanNames != null) {
				autowiredBeanNames.add(autowiredBeanName);
			}
			if (instanceCandidate instanceof Class) {
				instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
			}
			Object result = instanceCandidate;
			if (result instanceof NullBean) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				result = null;
			}
			if (!ClassUtils.isAssignableValue(type, result)) {
				throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
			}
			return result;
		}
		finally {
			ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
		}
	}

© 著作权归作者所有

my_juke
粉丝 4
博文 34
码字总数 22261
作品 0
深圳
私信 提问
Spring代码分析一:加载与初始化

一般的Web项目都会在web.xml中加入Spring监听器,内容如下: <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-p......

卡布不卡
2013/07/24
2.5K
1
BeanFactory和ApplicationContext的区别

Spring Bean 先从SpringBean说起,Spring Beans是被Spring容器管理的Java对象,比如: 我们一般通过Application.xml配置Spring Bean元数据。 Spring Bean被Spring容器管理之后,可以在程序中...

春哥大魔王的博客
07/02
37
0
Spring动态的注入Bean对象的实现方式,

Many guys maybe encountered this situation in actually working.he want to gain the spring bean object through the dynamic injection. such as there are two datasources one is nor......

保罗的寓言
2011/06/03
4K
0
Spring源码学习(一) IOC容器

Spring 提供的最基本的Ioc容器接口是BeanFactory, 通过BeanFactory可以获取bean对象的实例, 但BeanFactory 是怎么从配置文件里读取的bean对象的信息呢? 下面的代码是BeanFactory去获取sprin...

younchen
2014/07/09
280
0
Spring核心源码:ApplicationContext

废话 spring版本:4.0.6 随便做了这么多年的spring,但是源码就只阅读过 shiro的。一直想去读一下spring,mybatis,netty,这些结构优美的开源框架的源码。 核心包: spring-context:spring的上...

GITTODO
2018/04/25
75
0

没有更多内容

加载失败,请刷新页面

加载更多

Redis集群搭建

服务器资源 ip 账号 配置 操作系统 xxx.70 root/xxx 磁盘50G(/)+150G(/home)、内存16G、CPU 16core CentOS Linux release 7.2.1511 (Core) xxx.74 root/xxx 磁盘50G(/)+150G(/home)、......

jxlgzwh
20分钟前
2
0
avro

一、 ```我们已经接触过很多序列化框架(或者集成系统),比如protobuf、hessian、thrift等,它们各有优缺点以及各自的实用场景,Avro也是一个序列化框架,它的设计思想、编程模式都和thi...

hexiaoming123
22分钟前
4
0
QML TextInput的字体超出控件范围

本文链接:https://blog.csdn.net/chyuanrufeng/article/details/54691998 问题描述 :QML TextInput输入内容超过TextInput的大小 当输入过多的字符串时,会出现内容超过TextInput的大小,字...

shzwork
23分钟前
2
0
《Java 8 in Action》Chapter 10:用Optional取代null

1965年,英国一位名为Tony Hoare的计算机科学家在设计ALGOL W语言时提出了null引用的想法。ALGOL W是第一批在堆上分配记录的类型语言之一。Hoare选择null引用这种方式,“只是因为这种方法实...

HelloDeveloper
24分钟前
2
0
进击的 Java ,云原生时代的蜕变

作者| 易立 阿里云资深技术专家<br /> <br />导读:云原生时代的来临,与Java 开发者到底有什么联系?有人说,云原生压根不是为了 Java 存在的。然而,本文的作者却认为云原生时代,Java 依然...

阿里巴巴云原生
26分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部