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;
    }
}

配置资源文件:



    
    
        
    

 测试获取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。它没有实现。交给子类去实现。大家可以看看三者之间的继承关系,如下图所示:

Spring IOC之ignoredDependencyInterface_第1张图片

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

/**
	 * Ignore the given dependency interface for autowiring.
	 * 

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. *

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> ignoredDependencyInterfaces = new HashSet>();

这货其实是个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就要忽略这个依赖注入放入接口。

你可能感兴趣的:(spring)