Spring IOC(三)依赖注入
本系列目录:
目录
1.AbstractBeanFactory设计类图
2.模拟容器获取Bean,源码剖析
3.总结
=====正文分割线=============
前面一章讲解的高级容器ApplicationContext的接口设计和ClassPathXmlApplicationContext实现类从xml文件中载入bean的过程,其它实现类大同小异。
光生成Bean还不够,还得在需要使用的地方获取到才能使用,即依赖注入。主要涉及源码AbstractBeanFactory。本章先分析AbstractBeanFactory类的类图,再结合例子看源码如何获取bean.
一、核心类图
如上图,核心类AbstractBeanFactory,相关接口描述:
AliasRegistry接口:别名注册接口。声明了别名的注册、移除、判断是否别名、获取接口。
SimpleAliasRegistry类:简单别名注册器,实现了AliasRegistry接口。维护了一个ConcurrentHashMap,key是别名,value是bean name。
SingletonBeanRegistry接口:单例bean注册接口。声明了对单例bean的对象获取、名称获取、注册、判断包含、计数。获取单例互斥量对象。
DefaultSingletonBeanRegistry类:默认单例Bean注册器,继承自SimpleAliasRegistry。同时实现了SingletonBeanRegistry接口。即同时具有别名注册+单例bean注册的功能。并且拓展了对单例的一系列操作。拓展维护了11个集合用以存储各种业务数据。(例如缓存了单例对象、单例工厂、注册过的单例、正在创建中的单例)
FactoryBeanRegistrySupport类:工厂bean注册支持类,继承自DefaultSingletonBeanRegistry。拓展维护一个ConcurrentHashMap<String, Object>,key是工厂bean名称,value是bean对象,作为工厂bean创建的bean对象缓存使用。
ConfigurableBeanFactory接口:可配置bean工厂接口。继承自HierarchicalBeanFactory、SingletonBeanRegistry接口。拓展维护了父类工厂、工厂的类加载器、值解析器、类型转换器、bean后处理器、注册scope、bean表达式解析器等等。
AbstractBeanFactory类:继承自FactoryBeanRegistrySupport,实现了ConfigurableBeanFactory接口。拓展了containsBeanDefinition、getBeanDefinition、createBean3个抽象方法,供子类实现。
AutowireCapableBeanFactory接口:自动装备bean工厂接口。声明了bean的创建、自动装配、配置、初始化bean、初始化前后bean处理器、销毁bean。
AbstractAutowireCapableBeanFactory类:继承自AbstractBeanFactory,实现了AutowireCapableBeanFactory接口。即支持了bean生命周期的各种细粒度的实现。
二、模拟容器获取Bean,源码剖析
1 public static void main(String[] args) {
2 //源码入口,从类路径下读取xml
3 ApplicationContext ac1 = new ClassPathXmlApplicationContext("aop.xml");
4 Dao dao = (Dao)ac1.getBean("daoImpl",Dao.class);//根据名称和class获取Bean
5 dao.select();//执行Bean实例方法
}
debug运行,F6单步跳过,F5进入方法,发现最终执行的AbstractBeanFactory的doGetBean方法,源码如下:
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
//获取规范的bean name
final String beanName = transformedBeanName(name);
Object bean; // 1.从缓存中获取bean实例
Object sharedInstance = getSingleton(beanName);
//能获取到
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {//debug循环引用
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 + "'");
}
}
//bean实例--》bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
} //2.从父容器中直接获取bean.
BeanFactory parentBeanFactory = getParentBeanFactory();
//当前容器的父容器存在,且当前容器中不存在指名的Bean
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 解析Bean的原始名.
String nameToLookup = originalBeanName(name);
if (args != null) {
//委派给父类容器查找,根据指定的名称和显示参数.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// 委派给父类容器查找,根据指定的名称和类型.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//创建的Bean是否需要进行验证,一般不需要
if (!typeCheckOnly) {
//添加进已创建set
markBeanAsCreated(beanName);
} try {
//根据Bean的名字获取BeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args); // 初始化依赖bean
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);
getBean(dep);//递归
}
} // 3.单例模式获取bean
if (mbd.isSingleton()) {
// 使用一个内部匿名类,创建Bean实例对象,并且注册对所依赖的对象
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
// 创建一个指定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实例对象FactoryBean-》bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//4.原型模式获取bean
else if (mbd.isPrototype()) {
// 每次创建新对象实例
Object prototypeInstance = null;
try {
// 回调方法,注册原型对象
beforePrototypeCreation(beanName);
// 创建指定Bean对象实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 回调方法,Bean无法再次创建
afterPrototypeCreation(beanName);
}
// 获取给定Bean实例对象FactoryBean-》bean
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//5.从scope中获取bean
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 {
// 从scope中获取bean
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
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;
}
} // 对创建的Bean进行类型检查,如果没有问题,就返回这个新建的Bean,这个Bean已经包含了依赖关系.
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
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;
}
AbstractBeanFactory的doGetBean方法获取bean有5种方法如下:
- 从缓存中获取bean
- 从父容器中直接获取bean
- 单例模式获取bean
- 原型模式获取bean
- 从scope中获取bean
其中,除了从父容器中直接获取bean外,其它4种方法都包含2个步骤:createBean即bean实例的创建和初始化、getObjectForBeanInstance即从bean实例中获取bean对象。下面详细追一下源码。
1.bean实例的创建和初始化
createBean(beanName, mbd, args),这就是核心方法了。AbstractBeanFactory的createBean只是一个声明,在子类AbstractAutowireCapableBeanFactory中覆盖实现,源码如下:
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd; // 确保bean的类解析完毕,如果是动态解析类型,不会存储合并到bean定义中。克隆一份bean定义。
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
} // Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
} try {
// 如果Bean配置了实例化前处理器,则返回一个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);
}
// 核心方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
进入doCreateBean:
/**
* Actually create the specified bean. Pre-creation processing has already happened
* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
* <p>Differentiates between default bean instantiation, use of a
* factory method, and autowiring a constructor.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
*/
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException { // Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {// 单例模式,清除缓存bean
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType; // 允许处理器修改合并bean定义
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
} // 如果是单例模式,且允许循环引用,且当前单列正在创建中,则返回之前的bean引用
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
} // 初始化(依赖注入)
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);// 数据填充进实例
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
// 早期已注册的单例bean生成方案,有依赖的注入依赖,无依赖的直接返回引用
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
} // 注册完成依赖注入的Bean.(如果有销毁方法添加销毁方法等待回调)
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
} return exposedObject;
}
如上图,doCreateBean方法是中重要的方法:
1)createBeanInstance 创建bean实例对象instanceWrapper
2)populateBean bean定义中配置的属性注入实例对象instanceWrapper
3)initializeBean 初始化bean
1.createBeanInstance有三种实例化方法:
1.工厂方法
2.容器自动装配
3.使用构造函数实例化。
源码如下:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// 1.这里使用工厂方法对Bean进行实例化
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
} // 2.使用容器自动装配方法进行实例化
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
} // 3.使用构造函数进行实例化
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
} // No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
上面的源码中instantiateBean:最终调用SimpleInstantiationStrategy.instantiate方法来生成Bean对象实例,它提供了两种方式
1.BeanUtils,是jvm的反射机制
2.cglib。这里就是典型的策略模式。
instantiate源码如下:
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (bd.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 1.通过BeanUtils进行实例化,利用反射机制获取:java.lang.reflect.Constructor
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 2.使用CGLIB来实例化对象
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
2.populateBean:属性依赖注入方法
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues(); if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
} // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
} if (!continueWithPropertyPopulation) {
return;
}
// 开始进行依赖注入过程,先处理autowire的注入:名字+类型注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // 根据Bean的名字自动装配注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
} // 根据Bean的类型自动装配注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
} pvs = newPvs;
} boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
// 有实例化bean处理器/需要依赖检查
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {// 实例化bean处理器
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);
}
}
// 对属性进行依赖注入
applyPropertyValues(beanName, mbd, bw, pvs);
}
最终追踪到applyPropertyValues方法,源码如下:
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs == null || pvs.isEmpty()) {
return;
} MutablePropertyValues mpvs = null;
List<PropertyValue> original; if (System.getSecurityManager() != null) {
if (bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());// 设置安全上下文,JDK安全机制
}
} if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);// 为实例化对象设置属性值
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
} TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); // Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
} // 依赖注入属性值
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
setPropertyValues该方法:AbstractPropertyAccessor实现类注入依赖的属性。
3.初始化initializeBean
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);// Aware接口 设置bean name、factory、classloader } Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);// bea后处理器-初始化之前
} try {
invokeInitMethods(beanName, wrappedBean, mbd);// 执行初始化方法(InitializingBean)
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
} if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//bea后处理器-初始化之后
}
return wrappedBean;
} private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);//设置bean 名称
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());//设置bean类加载器
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);//设置bean 工厂
}
}
}
invokeInitMethods初始化方法如下:
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {//有安全策略
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
((InitializingBean) bean).afterPropertiesSet();//回调属性设置完后方法
return null;
}
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {// 无安全策略,直接执行
((InitializingBean) bean).afterPropertiesSet();//回调属性设置完后方法 }
} if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
2.从bean实例中获取bean对象
AbstractBeanFactory.getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd),源码如下:
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
} // 这个bean实例可能是一个普通bean或者是一个工厂Bean.
// 如果bean实例不是工厂bean且这个name也不是工厂解引用(工厂本身,name以"&"开头),即已经是一个普通bean实例了直接返回即可
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
} Object object = null;
if (mbd == null) {// bean定义为空,从缓存中获取bean
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {// 缓存中没有bean实例
// 强转成工厂bean
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// 获取bean,单例的就缓存进concurrenthashmap
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);// 核心方法入口
}
return object;
}
getObjectFromFactoryBean:根据"工厂bean"、name、"是否有后置处理器"3个参数获取bean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
}
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
}
return (object != NULL_OBJECT ? object : null);
}
}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
1.doGetObjectFromFactoryBean核心方法:根据工厂bean和名称获取bean
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException { Object object;
try {// 配置了安全管理器
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
return factory.getObject();
}
}, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {// 未配置安全管理器,直接获取对象
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
} // Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
return object;
}
2.postProcessObjectFromFactoryBean:执行“初始化之后的后处理器“”
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);//这里是接口AutowireCapableBeanFactory定义的方法
} public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException { Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
可以看到最后调用了BeanPostProcessor接口来处理。这里不再拓展,将来会开一篇专门讲解BeanPostProcessor接口的各种实现。
三、总结
通过分析跟踪IOC容器依赖注入这一部分,发现主要与AbstractBeanFactory、AutowireCapableBeanFactory这两个类相关。实现了5种获取bean的方案。
- 从缓存中获取bean
- 从父容器中直接获取bean
- 单例模式获取bean
- 原型模式获取bean
- 从scope中获取bean
除了从父容器中直接获取bean外,其它4种方法都包含2个步骤:bean实例的创建和初始化、从bean实例中获取bean对象。
Spring IOC(三)依赖注入的更多相关文章
- spring ioc三种注入方式
spring ioc三种注入方式 IOC ,全称 (Inverse Of Control) ,中文意思为:控制反转 什么是控制反转? 控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术. 由容 ...
- 【Spring IoC】依赖注入DI(四)
平常的Java开发中,程序员在某个类中需要依赖其它类的方法.通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理. Spring提出了依赖注入的思想,即依赖类不由程 ...
- Spring IOC 三种注入方式
1. 接口注入 2. setter注入 3. 构造器注入 对象与对象之间的关系可以简单的理解为对象之间的依赖关系:A类需要B类的一个实例来进行某些操作,比如在A类的方法中需要调用B类 ...
- Spring IOC三种注入方式(接口注入、setter注入、构造器注入)(摘抄)
IOC ,全称 (Inverse Of Control) ,中文意思为:控制反转, Spring 框架的核心基于控制反转原理. 什么是控制反转?控制反转是一种将组件依赖关系的创建和管理置于程序外部的技 ...
- Spring IOC 三种注入方式(构造器,setter,接口)
Spring的依赖注入有三种方式: 1,构造器注入 2,setter注入 3,接口注入 下面我给大家介绍一下这三种注入 1.构造器注入 构造器注入主要是依赖于构造方法去实现,构造方法可以是有参也可以是 ...
- TinyFrame续篇:整合Spring IOC实现依赖注入
上一篇主要讲解了如何搭建基于CodeFirst的ORM,并且在章节末我们获取了上下文对象的实例:BookContext.这节主要承接上一篇,来讲解如何整合Spring IOC容器实现控制反转,依赖注入 ...
- Spring Ioc和依赖注入
总结一下近来几天的学习,做个笔记 以下是Spring IoC相关内容: IoC(Inversion of Control):控制反转: 其主要功能可简单概述为:将 用 new 去创建实例对象,转换为让 ...
- Spring学习-理解IOC和依赖注入
最近刚买了一本介绍ssm框架的书,里面主要对Mybatis.spring.springmvc和redis做了很多的讲解,个人觉得虽然有的内容我看不懂,但是整体上还是不错的.最近正在学习中,一边学习一边 ...
- SSM框架之Spring(3)IOC及依赖注入(基于注解的实现)
Spring(3)IOC及依赖注入(基于注解的实现) 学习基于注解的 IoC 配置,大家脑海里首先得有一个认知,即注解配置和 xml 配置要实现的功能都是一样 的,都是要降低程序间的耦合.只是配置的形 ...
- SSM框架之Spring(2)IOC及依赖注入
Spring(2)IOC及依赖注入 基于xml配置文件的实现 1.IOC (控制反转-Inversion Of Control) 控制反转(Inversion of Control,缩写为IoC),是 ...
随机推荐
- Future与Promise
https://code.csdn.NET/DOC_Scala/chinese_scala_offical_document/file/Futures-and-Promises-cn.md#ancho ...
- SEO优化-robots.txt解读
一.什么是robots.txt robots.txt 文件由一条或多条规则组成.每条规则可禁止(或允许)特定抓取工具抓取相应网站中的指定文件路径. 通俗一点的说法就是:告诉爬虫,我这个网站,你哪些能看 ...
- Spring Cloud Config - RSA简介以及使用RSA加密配置文件
简介 RSA非对称加密有着非常强大的安全性,HTTPS的SSL加密就是使用这种方法进行HTTPS请求加密传输的.因为RSA算法会涉及Private Key和Public Key分别用来加密和解密,所以 ...
- JavaScript中对数组和数组API的认识
JavaScript中对数组和数组API的认识 一.数组概念: 数组是JavaScript中的一类特殊的对象,用一对中括号“[]”表示,用来在单个的变量中存储多个值.在数组中,每个值都有一个对应的不重 ...
- css多类选择器
<!DOCTYPE html> <html lang="zh-CN"> <head> <style type="text/css ...
- 团队项目第二阶段个人进展——Day5
一.昨天工作总结 冲刺第五天,找到了一个专门的提供后端数据服务的网站:leancloud,并学习了相关操作 二.遇到的问题 对leancloud的数据如何请求和响应不懂 三.今日工作规划 深入学习le ...
- github routine
1. 从官方库fork 自己的分支库后,git clone到local. 2. local的remotes/origin默认是自己的分支库.可以添加remotes/upstream指向官方库. 3. ...
- 读《图解HTTP》有感-(确认访问用户身份的认证)
写在前面 认证机制能够保证特定的资源给特定的(经过认证的)用户访问.从而保证了资源的机密性. 正文 1.为什么要认证?认证的媒介是什么? 认证的目的在于确认访问者的身份,保证资源的私有性(只有经过特定 ...
- Spring Boot实战笔记(二)-- Spring常用配置(Scope、Spring EL和资源调用)
一.Bean的Scope Scope描述的是Spring容器如何新建Bean实例的.Spring的Scope有以下几种,通过@Scope注解来实现. (1)Singleton:一个Spring容器中只 ...
- PAT1090:Highest Price in Supply Chain
1090. Highest Price in Supply Chain (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 C ...