Spring源码解读5——IoC容器的高级特性

本文详细解析了Spring框架中的BeanFactory与FactoryBean的区别及其工作原理,同时深入探讨了Spring IoC容器如何通过autowiring实现依赖注入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Spring中,有两个很容易混淆的类:BeanFactory和FactoryBean。

BeanFactory:Bean工厂,是一个工厂(Factory),我们Spring IoC容器的最顶层接口就是这个BeanFactory,它的作用是管理Bean,即实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

FactoryBean:工厂Bean,是一个Bean,作用是产生其他bean实例。通常情况下,这种bean没有什么特别的要求,仅需要提供一个工厂方法,该方法用来返回其他bean实例。通常情况下,bean无须自己实现工厂模式,Spring容器担任工厂角色;但少数情况下,容器中的bean本身就是工厂,其作用是产生其它bean实例。

public abstract class AbstractBeanFactory{

        public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

	protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly){
                //根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖 
		final String beanName = transformedBeanName(name);
		Object bean;
                //先从缓存中取是否已经有被创建过的单态类型的Bean
                Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			......
                        //如果指定名称的Bean在容器中已有单态模式的Bean被创建,直接返回 
                        //获取给定Bean的实例对象,主要是完成FactoryBean的相关处理  
                        //注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是  
                        //创建创建对象的工厂Bean,两者之间有区别  
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		else {//缓存没有正在创建的单态模式Bean  
                        ......
                        //根据指定Bean名称获取其父级的Bean定义,主要解决Bean继承时子类合并父类公共属性问题

                        //获取factory中注册过的BeanDefinition
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                        //创建单态模式Bean的实例对象
			if (mbd.isSingleton()) {
                                //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
				sharedInstance = getSingleton(beanName, new ObjectFactory() {
					public Object getObject() throws BeansException {
						try {
							return createBean(beanName, mbd, args);
						}
					}
				});
                                //获取给定Bean的实例对象
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                        }
                        else if (mbd.isPrototype()) {
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);

                                        //说明createBean返回的bean是一个FactoryBean,而不是一个直接的bean实例
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					afterPrototypeCreation(beanName);
				}
				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}
		}


	protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd){

              ... ...

              //为何可以这样强转?
              FactoryBean factory = (FactoryBean)beanInstance;
              Object object = null;
	      object = getObjectFromFactoryBean(factory, beanName, !synthetic);
              return object;
        }
}
public abstract class FactoryBeanRegistrySupport{

	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, shouldPostProcess);
					this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
				}
				return (object != NULL_OBJECT ? object : null);
			}
		}
		else {
			return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
		}
	}
	private Object doGetObjectFromFactoryBean(
			final FactoryBean factory, final String beanName, final boolean shouldPostProcess)
			throws BeanCreationException {

		Object object;
		try {
			if (System.getSecurityManager() != null) {
				AccessControlContext acc = getAccessControlContext();
				try {
					object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						public Object run() throws Exception {

                                                             //调用Bean工厂的getObject方法生产指定Bean的实例对象。就类似于一个静态工

厂 
								return factory.getObject();
							}
						}, acc);
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
				object = factory.getObject();
			}
		}
}

FactoryBean的实现类有非常多,比如:Proxy、RMI、JNDI、ServletContextFactoryBean等等,FactoryBean接口为Spring容器提供了一个很好的封装机制,具体的getObject有不同的实现类根据不同的实现策略来具体提供。(就如同一个静态工厂)

=======================================================================
Spring IoC容器autowiring实现原理。
除了在Bean定义文件中直接指定字符串值,使用<ref>直接指定参考至其他的Bean,或是使用<bean>标签并指定"class"属性来指定依赖对象之外,spring也支持隐式的自动绑定,您可以透过类型(byType)或名称(byName)将某个Bean实例绑定至其他Bean对应的属性,比如

<bean id="helloBean" class="....." autowire="byType">
...
</bean>

class A
{
 private B b;
 void setB(B b){this.b=b;
 }
}
class B
{....
}
非自动:
<bean name="a" class="A">
  <property name="b"><ref bean="b"></property>
</bean>
<bean name="b" class="B"/>
如果按名字自动:
<bean name="a" class="A"/>
<bean name="b" class="B"/>

public abstract class AbstractAutowireCapableBeanFactory{

	protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {
		PropertyValues pvs = mbd.getPropertyValues();
                //对依赖注入处理,首先处理autowiring自动装配的依赖注入
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			//根据Bean名称进行autowiring自动装配处理
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			//根据Bean类型进行autowiring自动装配处理
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}

	protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
                //获取bean里的property属性
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
                        //如果Spring IoC容器中包含指定名称的Bean
			if (containsBean(propertyName)) {
                                //调用getBean方法向IoC容器索取指定名称的Bean实例,迭代触发属性的初始化和依赖注入
				Object bean = getBean(propertyName);
                                //为指定名称的属性赋予属性值
				pvs.add(propertyName, bean);
				registerDependentBean(propertyName, beanName);
				if (logger.isDebugEnabled()) {
					logger.debug("Added autowiring by name from bean name '" + beanName +
							"' via property '" + propertyName + "' to bean named '" + propertyName + 

"'");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
							"' by name: no matching bean found");
				}
			}
		}
	}
}

 

转载于:https://my.oschina.net/u/2286010/blog/707224

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值