Spring IOC之ignoredDependencyInterface

        在阅读Spring源码的时候,我曾经遇到了一个方法ignoredDependencyInterface();当时很是困惑,在查阅大量的资料的时候才初步的理解到了这个方法的作用。这篇文章是迈向Spring IOC源码的初步。可能在文章中存在个人的偏见或者主观臆测,希望大家不要留面子,直接指证,我们一起进步吧。好了,我们开始吧!

        在这里我使用的源码是Spring4.3.16的源码包。

        先创建一个Bean吧。

public class SpringBeanExplor {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }
}

配置资源文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <import resource="classpath:spring/spring-dao.xml"/>
    <bean id="springBeanExplor" class="com.gosaint.domain.SpringBeanExplor">
        <property name="name" value="caozg"/>
    </bean>
</beans>

 测试获取Bean

public class BeanTest {

    @Test
    public void testBeanLife() throws Exception{
        Resource resource=new ClassPathResource("applicationContext.xml");
        BeanFactory beanFactory=new DefaultListableBeanFactory();
        BeanDefinitionReader bdr=new XmlBeanDefinitionReader((BeanDefinitionRegistry) beanFactory);
        bdr.loadBeanDefinitions(resource);
        SpringBeanExplor bean = beanFactory.getBean(SpringBeanExplor.class);
        System.out.println(bean.getName());
    }
}

 1 读取资源文件,返回Resource的过程这里我暂且不再赘述。

        2 上述创建BeanFactory对象的时候,我没有使用XmlBeanFactory实现,因为这是一个过时的实现。我使用DefaulteListableBeanFacory作为实现。在new的时候开始创建对象,我们可以观察这个过程中都干了些什么。

public DefaultListableBeanFactory() {
		super();
}

在DefaultListableBeanFactory的构造器中调用了父类的构造器。DefaultListableBeanFactory继承了AbstractAutowireCapableBeanFactory。这是一个抽象的自动注入的一个Bean容器。当然是从字面理解。我们再来看看它的构造器的实现:

public AbstractAutowireCapableBeanFactory() {
		super();
		ignoreDependencyInterface(BeanNameAware.class);
		ignoreDependencyInterface(BeanFactoryAware.class);
		ignoreDependencyInterface(BeanClassLoaderAware.class);
}

  AbstractAutowireCapableBeanFactory的父类是AbstractBeanFactory。它没有实现。交给子类去实现。大家可以看看三者之间的继承关系,如下图所示:

再看上述的方法:ignoreDependencyInterface(Class class);这个方法都干了写什么。

/**
	 * Ignore the given dependency interface for autowiring.
	 * <p>This will typically be used by application contexts to register
	 * dependencies that are resolved in other ways, like BeanFactory through
	 * BeanFactoryAware or ApplicationContext through ApplicationContextAware.
	 * <p>By default, only the BeanFactoryAware interface is ignored.
	 * For further types to ignore, invoke this method for each type.
	 * @see org.springframework.beans.factory.BeanFactoryAware
	 * @see org.springframework.context.ApplicationContextAware
	 */
      //上述注释的翻译:忽略给定依赖接口的自动装配,这通常被应用程序上下文用于注册。
      //依赖关系是通过其他方式解决的,比如BeanFactory BeanFactoryAware或ApplicationContext通过ApplicationContextAware
      //默认情况下,只有BeanFactoryAware接口被忽略。若要忽略其他类型,请为每种类型调用此方法。 
	public void ignoreDependencyInterface(Class<?> ifc) {
		this.ignoredDependencyInterfaces.add(ifc);
	}

        简单的说:由于我要创建一个BeanFactory。但是这个过程中我的Bean可能会依赖一些接口,如:BeanNameAware等。这些接口在创建Bean的过程中不会去实例化,而是自动忽略掉这些依赖。为什么要忽略这些依赖呢?

private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<Class<?>>();

这货其实是个Set集合。目前我们存在两个问题没有搞清楚

        1 为什么在实现某些接口的时候依赖的接口要自动忽略注入?

        2 如何实现忽略注入的?(待续)

关于第一个问题:对于Spring自动创建Bean,但是Bean是无状态的,也就是说Bean不知道Spring容器BeanFactory的任何信心,包括Bean自己的名称name,Spring这样做的目的是为了Spring容器和Bean的解耦,带来的问题就是Bean的无状态。那么Bean要想定制化的做一些操作,就必然要获取BeanFactory中的信息,在Spring Bean的生命周期中我们都知道实现一些列接口去观察Bean创建过程中的一些信息。这里的BeanNameAware、BeanfactoryAware、BeanClassLoaderAware这些接口就是获取Bean的名称、BeanFactory的信息以及类加载器的信息的。因此这里牵扯到Spring创建bean的方式,正常实例化的bean和对定制化的bean要有所区分,因此Spring正常实例化的Bean就要忽略这个依赖注入放入接口。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值