概述
https://blog.csdn.net/gosaint/article/details/85010300
在阅读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就要忽略这个依赖注入放入接口。
最后
以上就是壮观蚂蚁为你收集整理的Spring IOC之ignoredDependencyInterface的全部内容,希望文章能够帮你解决Spring IOC之ignoredDependencyInterface所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复