在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");
}
}
}
}
}