小编给大家分享一下Spring IoC容器中依赖注入原理的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
我们提供的服务有:成都网站设计、网站制作、外贸营销网站建设、微信公众号开发、网站优化、网站认证、宁远ssl等。为近千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的宁远网站制作公司
具体如下:
IoC容器初始化的过程,主要完成的工作是在IoC容器中建立 BeanDefinition 数据映射,并没有看到IoC容器对Bean依赖关系进行注入,
假设当前IoC容器已经载入用户定义的Bean信息,依赖注入主要发生在两个阶段
正常情况下,由用户第一次向IoC容器索要Bean时触发
但我们可以在 BeanDefinition 信息中通过控制 lazy-init 属性来让容器完成对Bean的预实例化,即在初始化的过程中就完成某些Bean的依赖注入的过程
1.getBean触发的依赖注入
在基本的IoC容器接口 BeanFactory 中,有一个 getBean 的接口定义,这个接口的实现就是触发依赖注入发生的地方.为了进一步了解这个依赖注入的过程,我们从 DefaultListableBeanFactory 的基类 AbstractBeanFactory 入手去看看getBean的实现
// 这里是对 BeanFactory 接口的实现,比如getBean接口方法
//这些getBean接口方法最终是通过调用doGetBean来实现的
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
@Override
public T getBean(String name, Class 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 getBean(String name, Class requiredType, Object... args) throws BeansException {
return doGetBean(name, requiredType, args, false);
}
//这里是实际取得Bean的地方,也就是触发依赖注入发生的地方
@SuppressWarnings("unchecked")
protected T doGetBean(
final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
//急切地检查单例人士缓存手动注册的单例
//先从缓存中取得Bean,处理那些已经被创建过的单例Bean,这种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 + "'");
}
}
//这里的getObjectForBeanInstance完成的是FactoryBean的相关处理,以取得FactoryBean的相关处理,以取得FactoryBean的生产结果,BeanFactory和FactoryBean的区别已在前面讲过,这个过程在后面还会详细地分析
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);
}
// // 检查IoC容器中的BeanDefinition是否存在,若在当前工厂不存在则去顺着双亲BeanFactory链一直向上找
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
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的名字取得BeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
//递归获得当前Bean依赖的所有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);
}
}
//通过调用createBean方法创建Singleton bean实例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory