1、依赖注入在何时发生?
①第一次调用getBean() IOC容器触发依赖注入
②容器解析注册Bean定义时预实例化触发依赖注入
2、依赖注入实现过程:
入口getBean()
/*****实现类:AbstractBeanFactory # getBean()
* 1,如果是单例模式:则首先从缓存中查找; 定义为原型则创建一个新的实例对象;
* 2,创建实例对象:委派给 AbstractAutowireCapableBeanFactory # createBean() 实现;
****/
//获取IOC 容器中指定名称的Bean
@Override
public Object getBean(String name) throws BeansException {
//doGetBean 才是真正向IOC 容器获取被管理Bean 的过程
return doGetBean(name, null, null, false);
}
@SuppressWarnings("unchecked")
//真正实现向IOC 容器获取Bean 的功能,也是触发依赖注入功能的地方
protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//根据指定的名称获取被管理Bean 的名称,剥离指定名称中对容器的相关依赖
//如果指定的是别名,将别名转换为规范的Bean 名称
final String beanName = transformedBeanName(name);
Object bean;
//先从缓存中取是否已经有被创建过的单态类型的Bean
//对于单例模式的Bean 整个IOC 容器中只创建一次,不需要重复创建
Object sharedInstance = getSingleton(beanName);
//IOC 容器创建单例模式Bean 实例对象
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
//如果指定名称的Bean 在容器中已有单例模式的Bean 被创建
//直接返回已经创建的Bean
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 + "'");
}
}
//获取给定Bean 的实例对象,主要是完成FactoryBean 的相关处理
//注意:BeanFactory 是管理容器中Bean 的工厂,而FactoryBean 是
//创建创建对象的工厂Bean,两者之间有区别
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}else {
//缓存没有正在创建的单例模式Bean
//缓存中已经有已经创建的原型模式Bean
//但是由于循环引用的问题导致实例化对象失败
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//对IOC 容器中是否存在指定名称的BeanDefinition 进行检查,首先检查是否
//能在当前的BeanFactory 中获取的所需要的Bean,如果不能则委托当前容器
//的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找
BeanFactory parentBeanFactory = getParentBeanFactory();
//当前容器的父级容器存在,且当前容器中不存在指定名称的Bean
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//解析指定Bean 名称的原始名称
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}else if (args != null) {
//委派父级容器根据指定名称和显式的参数查找
return (T) parentBeanFactory.getBean(nameToLookup, args);
}else {
//委派父级容器根据指定名称和类型查找
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//创建的Bean 是否需要进行类型验证,一般不需要
if (!typeCheckOnly) {
//向容器标记指定的Bean 已经被创建
markBeanAsCreated(beanName);
}
try {
//根据指定Bean 名称获取其父级的Bean 定义
//主要解决Bean 继承时子类合并父类公共属性问题
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//获取当前Bean 所有依赖Bean 的名称
String[] dependsOn = mbd.getDependsOn();
//如果当前Bean 有依赖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 + "'");
}
//递归调用getBean 方法,获取当前Bean 的依赖Bean
registerDependentBean(dep, beanName);
//把被依赖Bean 注册给当前依赖的Bean
getBean(dep);
}
}
//创建单例模式Bean 的实例对象
if (mbd.isSingleton()) {
//这里使用了一个匿名内部类,创建Bean 实例对象,并且注册给所依赖的对象
sharedInstance = getSingleton(beanName, () -> {
try {
//调用1:创建一个指定Bean 实例对象,如果有父级继承,则合并子类和父类的定义
return createBean(beanName, mbd, args);
}catch (BeansException ex) {
//显式地从容器单例模式Bean 缓存中清除实例对象
destroySingleton(beanName);
throw ex;
}
});
//获取给定Bean 的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//IOC 容器创建原型模式Bean 实例对象
else if (mbd.isPrototype()) {
//原型模式(Prototype)是每次都会创建一个新的对象
Object prototypeInstance = null;
try {
//回调beforePrototypeCreation 方法,默认的功能是注册当前创建的原型对象
beforePrototypeCreation(beanName);
//创建指定Bean 对象实例
prototypeInstance = createBean(beanName, mbd, args);
}finally {
//回调afterPrototypeCreation 方法,默认的功能告诉IOC 容器指定Bean 的原型对象不再创建
afterPrototypeCreation(beanName);
}
//获取给定Bean 的实例对象
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//要创建的Bean 既不是单例模式,也不是原型模式,则根据Bean 定义资源中
//配置的生命周期范围,选择实例化Bean 的合适方法,这种在Web 应用程序中
//比较常用,如:request、session、application 等生命周期
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
//Bean 定义资源中没有配置生命周期范围,则Bean 定义不合法
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 的实例对象
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 实例对象进行类型检查
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
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;
}
调用1:创建Bean实例化对象
/**
*创建Bean 实例对象,其实现方法为
* createBeanInstance() :生成Bean 所包含的java 对象实例。
* populateBean() :对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;
//判断需要创建的Bean 是否可以实例化,即是否可以通过当前的类加载器加载
Class> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
//校验和准备Bean 中的方法覆盖
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);
}
try {
//创建Bean 的入口
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (BeanCreationException ex) {
throw ex;
} catch (ImplicitlyAppearedSingletonException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
//真正创建Bean 的方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
//调用1-1、封装被创建的Bean 对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
//获取实例化对象的类型
Class> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
//调用PostProcessor 后置处理器
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, () -> getEarlyBeanReference(beanName, mbd, bean));
}
//Bean 对象的初始化,依赖注入在此触发
//这个exposedObject 在初始化完成之后返回作为依赖注入完成后的Bean
Object exposedObject = bean;
try {
//调用1-2、将Bean 实例对象封装,并且Bean 定义中配置的属性值赋值给实例对象
populateBean(beanName, mbd, instanceWrapper);
//初始化Bean 对象
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);
}
}
if (earlySingletonExposure) {
//获取指定名称的已注册的单例模式Bean 对象
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
//根据名称获取的已注册的Bean 和正在实例化的Bean 是同一个
if (exposedObject == bean) {
//当前实例化的Bean 初始化完成
exposedObject = earlySingletonReference;
}
//当前Bean 依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
//获取当前Bean 所依赖的其他Bean
for (String dependentBean : dependentBeans) {
//对依赖Bean 进行类型检查
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;
}
//调用1-1、封装被创建的Bean 对象, 根据指定初始化策略;静态工厂、工厂方法容器自动装配生成java实例对象 BeanWrapper ---> 包装器模式:做功能增强;
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//检查确认Bean 是可实例化的
Class> beanClass = resolveBeanClass(mbd, beanName);
//使用工厂方法对Bean 进行实例化
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());
}
Supplier> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
if (mbd.getFactoryMethodName() != null) {
//① 调用工厂方法实例化(beanName, RootBeanDefinition, 参数)
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
//② 使用容器的自动装配方法进行实例化
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) {
//配置了自动装配属性,使用容器的自动装配实例化
//容器的自动装配是根据参数类型匹配Bean 的构造方法
return autowireConstructor(beanName, mbd, null, null);
} else {
//使用默认的无参构造方法实例化
return instantiateBean(beanName, mbd);
}
}
//③ 使用Bean 的构造方法进行实例化
Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//使用容器的自动装配特性,调用匹配的构造方法实例化
return autowireConstructor(beanName, mbd, ctors, args);
}
//使用默认的无参构造方法实例化
return instantiateBean(beanName, mbd);
}
//【重点】使用默认的无参构造方法实例化Bean 对象
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
//获取系统的安全管理接口,JDK 标准的安全管理API
if (System.getSecurityManager() != null) {
//这里是一个匿名内置类,根据实例化策略创建实例对象
beanInstance = AccessController.doPrivileged((PrivilegedAction
其他依赖注入方式:基于注解的依赖注入:AnnotationConfigApplicationContext ;
Spring IOC 容器对于类级别的注解和类内部的注解分以下两种处理策略:
1、类级别的注解: 如@Component、@Repository、@Controller 、@Service 以及JavaEE6 的
@ManagedBean 和@Named 注解,都是添加在类上面的类级别注解,Spring 容器根据注解的过滤规则扫
描读取注解Bean 定义类,并将其注册到Spring IOC 容器中。
2、类内部的注解:如@Autowire、@Value、@Resource 以及EJB 和WebService 相关的注解等,都
是添加在类内部的字段或者方法上的类内部注解,SpringIOC 容器通过Bean 后置注解处理器解析Bean
内部的注解。
到这里就完整的分析了IOC容器依赖注入的过程,走到这里似乎还有什么不清楚,不明白的东西? 我们的IOC容器在完成了注册的BeanDefinition,而BeanDefinition是对xml配置文件的解析,那我们依赖注入的时候又是以什么在承载数据的携带以及赋值责任呢?源码分析中的内省机制是什么呢?
首先简单介绍一下内省机制?
内省(Introspector)是Java语言对Bean类属性、事件的一种缺省处理方法。 例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新的值。 通过getName/setName来访问name属性,这就是默认的规则。 Java中提供了一套API用来访问某个属性的getter/setter方法,通过这些API可以使你不需要了解这个规则, 这些API存放于包java.beans中。
一般的做法是通过类Introspector来获取某个对象的BeanInfo信息,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反射机制来调用这些方法。
详细操作及原理解析请参考以下博文:
https://blog.csdn.net/jiangyu1013/article/details/75280962
然后,介绍一下依赖注入的核心接口BeanWapper
BeanWrapper接口,是spring内部的一个核心接口,它是bean的包裹类,在内部中即会保存该bean的实例,提供其它一些扩展功能。同时,BeanWrapper接口还继承了PropertyAccessor, propertyEditorRegistry, TypeConverter、ConfigurablePropertyAccessor接口,提供了访问bean的属性值、属性编辑器注册、类型转换等功能。
同时BeanWrapper采用了包装器模式,方便无侵入的扩展,扩展之后依然保持OOP关系,对象被改变之后可以还原;
1,Bean实例化过程与BeanWapper
(1)ResourceLoader加载配置信息
(2)BeanDefinitionReader读取并解析标签,并将标签的属性转换为BeanDefinition对
应的属性,并注册到BeanDefinitionRegistry注册表中。
(3)容器扫描BeanDefinitionRegistry注册表,通过反射机制获取BeanFactoryPostProcessor类型的
工厂后处理器,并用这个工厂后处理器对BeanDefinition进行加工。
(4)根据处理过的BeanDefinition,使用InstantiationStrategy实例化bean。
(5)然后BeanWrapper结合BeanDefinitionRegistry和PropertyEditorRegistry对Bean的属性赋值。
2、类关系图与设置包装Bean属性的序列值
进一步分析:
1,数据结构:BeanWapperImpl持有 CacheIntrespectionResults {
List
beanInfoFactories; ConcurrentMap
, CachedIntrospectionResults> strongClassCache;
} 结合内省机制,我们知道这一定是保存内省机制的信息,实现对Bean属性的获取和设值 ;TypeConverterDelegate:属性编辑器的委托者,可自定义实现;
PropertyTokenHolder:保存Bean要注入的属性名
2、核心关键方法:
Object getPropertyValue(String propertyName) throws BeansException;
void setPropertyValue(String propertyName, Object value) throws BeansException;
【关键点】:方法中的 propertyName 支持表达式例如: name 与 getName ,setName对应;
account.name 对应 getAccount.getName 和 getAccount.setName 及数组, Map形式
nestedBw.setPropertyValue(tokens, pv) 为注入值设置属性;
nestedBw为嵌套属性的BeanWapper;
分析完了IOC容器的依赖注入,后续将对IOC的高级特性进行分析,内容包括如下:
1、懒加载特性实现、
2、FactoryBean实现类源码分析与策略解析 Proxy,RMI,JNDI 的getObject实现策略、
3、BeanPostProcessor后置处理器实现 、
4、AdvisorAdapterRegistrationManager 注册通知适配器、
5、自动注入实现原理