spring中按照Bean的scop可以被定义为两种模式:prototype(多例)和singleton(单例),按照Bean的实例化方式可以被定义为预加载和懒加载(@Lazy)。
prototype(多例)和懒加载(@Lazy)的Bean被延迟到使用时才进行实例化,而非延迟加载的单例Bean则在容器刷新(refresh)时通过finishBeanFactoryInitialization方法进行实例化,只是实例化的时机和处理循环依赖的方式不同,这里只分析非延迟单例Bean的实例化过程。
Bean实例化的方法是在AbstractApplicationContext类中通过doGetBean方法进行的:
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
// 提取对应的beanName,如果是工厂Bean则加前缀&
final String beanName = transformedBeanName(name);
Object bean;
// 尝试从缓存或者singletonFactories中的ObjectFactory中获取
Object sharedInstance = getSingleton(beanName);// step 1
if (sharedInstance != null && args == null) {
// 返回对应的实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);//step 2
}else {
// 只有在单例的情况才会尝试解决循环依赖
if (isPrototypeCurrentlyInCreation(beanName)) { // step 3
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
// 如果beanDefinitionMap中,也就是所有已加载的类中不包含beanName则尝试从parentBeanFactory中检查
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// 递归查找
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
// 不仅仅是做类型检查,而是创建BEAN则记录
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {// 将各种类型的BeanDefinition转换成RootBeanDefinition
// 如果指定的BEAN为子BEAN的话,则合并父BEAN的属性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
// 如果存在强制依赖,则递归实例化依赖的bean
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);
// 实例化依赖的Bean
getBean(dep);
}
}
// 实例化依赖的bean后则进行实例化
// 单例模式创建
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
// bean实例化核心方法 step 5
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 省略非单例 实例创建代码 ... .... ....
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
return (T) bean;
}
step1、尝试从缓存或者singletonFactories中的ObjectFactory工厂中获取,在创建单例bean的时候会存在依赖注入的情况,spring创建bean的原则是不等bean创建完成 就会将创建bean的ObjectFactory提早曝光,也就是将ObjectFactory加入缓存中,一旦下一个bean依赖上个bean则直接使用ObjectFactory。
step 2 获取对应的实例
存在BeanFactory的情况并不是直接返回对象本身而是返回工厂方法返回的实例
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
// 如果BeanName为&前缀,但却不是FactoryBean的实例,抛出异常
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// 如果是一般的BEAN,或者是工厂bean,但是name的前缀为&
// 直接返回该实例
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
// 加载FactoryBean
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// 已经明确了beanInstance为FactoryBean,可以强制转换
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
step3 非单例Bean循环依赖检查
如果是Prototype类型的Bean,两次进入创建则抛出异常,如Bean A中有Bean B的引用,Bean B中有Bean A的引用,注入时候就会产生当A还未创建完成的时候对应B的创建需要再次返回创建A,从而第二次进入同一个Bean的getBean方法,一定会在此抛出异常,不能完成注入,也就是说prototype类型的Bean不能实现循环依赖,只有在单例的Bean才会尝试解决循环依赖。
step4 单例Bean实例创建
实际调用的方法在AbstractAutowireCapableBeanFactory类中,这里还不是真正的创建实例,可以看出是创建前的准备工作,比如类的解析、BeanPostProcessors处理器的调用等,需要注意的是这里还有一个AOP的切入点。
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 锁定并解析class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
// 验证并准备覆盖的方法
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 调用Bean的前置处理器:BeanPostProcessors
// step 4.1
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 如果前置处理返回了Bean,Bean不为空就直接返回
if (bean != null) {
System.out.println(beanName+":");
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
// step 4.2
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
step 4.1 调用InstantiationAwareBeanPostProcessors
InstantiationAwareBeanPostProcessor是BeanPostProcessor的子接口,在实例化Bean之前调用postProcessBeforeInstantiation方法,实例化Bean之后调用applyBeanPostProcessorsAfterInitialization方法。调用过程:
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// 尚未被解析
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 前置处理调用
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 后置处理调用
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
先调用前置方法,如果返回的不为空则调用后置方法,注意,此时Bean还没有进如真正的doCreate方法,如果此时返回了一个Bean,那肯定是一个代理,所有此处可以作为AOP的切入点,有机会返回代理对象。
step 4.2 doCreateBean
方法在AbstractAutowireCapableBeanFactory类中实现,这里才是真正创建Bean实例、进行各种属性和依赖注入的地方。
有四个主要的步骤:
1、调用createBeanInstance()方法创建Bean实例,使用构造方法和工厂方法来实例化,首先要根据参数来锁定具体的构造方法或工厂方法,然后处理参数的引入,最后实例化。
2、应用MergedBeanDefinitionPostProcessors,MergedBeanDefinitionPostProcessor也是BeanPostProcessor的子接口,扩展了postProcessMergedBeanDefinition方法,这个方法是用来处理合并Bean定义的。
3、解决单例的循环依赖,根据”正在创建的Bean池“singletonsCurrentlyInCreation中是否包含当前的Bean,如果包含则认为存在循环依赖,为了避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory放入工厂,因为此时Bean的属性尚未填充所以可以理解为未初始化完成。这个步骤可以理解为”提前曝光单例Bean“。
4、对Bean的各种依赖和属性进行填充,比如@Autowired、@Resource、@Value注解的属性都在此进行赋值。
属性的方法是populateBean在AbstractAutowireCapableBeanFactory类中实现:
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
// 省略部分代码 ... ...
// BeanPostProcessor理器已经初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 对所有需要依赖检查的属性进行处理
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
// 依赖检查
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//将属性应用到BEAN中
applyPropertyValues(beanName, mbd, bw, pvs);
}
代码中又一次对BeanPostProcessor进行了遍历执行,在容器构造分析中提到了在初始化容器的时候会向容器注入一些BeanPostProcessor的实现:
AutowiredAnnotationBeanPostProcessor
RequiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
其中AutowiredAnnotationBeanPostProcessor就是用来处理@Autowired、@Value注解的属性。
RequiredAnnotationBeanPostProcessor是用来处理@Required注解的属性。
CommonAnnotationBeanPostProcessor是用来处理@Resource注解的属性,@Resource注解来自JAVAEE5规范,这个规范中还有两个常用的注解@PostConstruct和@PreDestroy。
我们来看AutowiredAnnotationBeanPostProcessor是怎么进行属性填充的。
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
// 查找@Autowired和@Value注入的元数据缓存中有直接返回,没有则创建 step 4.2.1
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 注入step 4.2.2
metadata.inject(bean, beanName, pvs);
}
// 省略部分 代码 ... ...
return pvs;
}
step 4.2.1 查找自动注入元数据
使用ReflectionUtils反射工具从类中获取有@Autowired或@Value注解的字段封装成AutowiredFieldElement对象返回。
使用ReflectionUtils反射工具从类中获取有@Autowired或@Value注解的犯法封装成AutowiredMethodElement对象返回。
这两类都是InjectionMetadata.InjectedElement的子类。
step 4.2.2 注入
AutowiredFieldElement字段属性的自动注入:
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;// 属性字段
Object value;
if (this.cached) {// 如果有缓存直接从缓存中拿出
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
// 封装依赖描述类
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);
// 类型转换器具
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 调用DefaultListableBeanFactory中的resolveDependency step 4.2.3
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
// 省略 引用快照缓存的代码 ... ....
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);// 使字段可访问
field.set(bean, value);// 设置字段的值
}
}
}
属性的依赖值是从DefaultListableBeanFactory类中解析出来的:
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 省略部分代码... ...
// 依赖的属性类型
Class<?> type = descriptor.getDependencyType();
// 获取@Value的建议值,类似:"${jsets.jdbc.dialect}"
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);
// 这里使用beanExpressionResolver进行表达式解析
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()));
}
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 查找自动注入的候选Beans
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
// 如果 匹配的beans为空,且@Autowired的required为true ,抛出异常
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 {
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {// 单个候选这
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
return (instanceCandidate instanceof Class ?
descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
针对@Value注解的属性从AutowireCandidateResolver中获取建议的值,如"${jsets.jdbc.dialect}",然后使用beanExpressionResolver进行表达式解析器进行解析。
@Autowired注解的属性使用BeanFactoryUtils根据属性的类型从BeanFactory中获取对应的Bean实例,如果对应类型的Bean只有一个就直接返回这个Bean实例,如果有多个候选的Bean实例,使用有@Primary注解的哪个实例,如果没有@Primary注解则根据属性的名称进行匹配,匹配不到则抛出异常。
AutowiredMethodElement的注入逻辑于此类似,不做分析。
@Resource的处理逻辑和@Autowired 处理逻辑类似,只是@Resource依BeanName进行注入。
码字不易,转载请保留原文连接https://www.jianshu.com/p/ad4a5d35481b
网友评论