相信很多人在看Spring源码的时候的会看到这个方法,但是不知道这个方法是干嘛的,但是从方法名中我们能够大概知道其功能。
先看下Spring源码中这个接口的注释。
大概的翻译前面两句话
忽略给定的依赖接口进行自动装配。
通常由应用程序上下文用来注册以其他方式解析的依赖项,
例如通过BeanFactoryAware的BeanFactory或通过ApplicationContextAware的ApplicationContext。
一般官方的解释都比较抽象难理解。想要理解这个方法的作用我们得先了解一下Spring中的一个功能。也是让新手容易混淆的一个功能。
因为很多人看到 自动绑定或者Autowiring就以为是 @Autowired
明确这个事实以后我们得介绍一下这个自动绑定的功能有什么作用?
开启自动绑定之后会将我们放入到IOC中的对象自动执行其setter方法,在javaBean中一个属性对应着一个setter和一个getter方法
根据约定setXxx其Xxx把首字母改为小写之后就是这个对象中有的属性名。在开启Spring的自动装配之后,一个放入到IOC中的对象中有setTestBean()方法,如果此时自动绑定的规则是 byName 那么Spring会去IOC中寻找testBean这个对象,如果有的会就会执行该setter方法,如果是byType的方式,就是会寻找当前setter方法里对应的参数类型的bean。如果找到多个同样也是抛出异常。
我们从使用Xml的方式到使用@Bean的方式逐一讲解。
如上图所示,我们在使用XML文件方式的时候涉及到了三个类和一个xml文件 AutowiringTest类中只有一个autowiring方法作为我们测试程序的入口。
在XML文件中我们定义了两个Bean标签,将User和Person放入到了IOC中
Person类关联了User并有setUser(User)方法
XML文件源码
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
default-autowire="byType">
<bean id="user" class="com.itzijin.dependency.autowiring.domain.User"/>
<bean id="person" class="com.itzijin.dependency.autowiring.domain.Person"/>
beans>
Person类和User类
public class Person {
private User user;
public void setUser(User user) {
this.user = user;
}
}
public class User {
}
AutowiringTest 类
@ContextConfiguration("classpath:/META-INF/autowiring-demo.xml")
@RunWith(SpringRunner.class)
public class AutowiringTest {
@Autowired
private User user;
@Autowired
private Person person;
@Test
public void autowiring(){
}
}
此时会自动执行该setter方法。并且我们在setUser中对user属性进行了赋值
上面是基于byType的方式,当然也可以修改成byName的方式。按照我之前说的byName和byType的区别可自行进行验证。
@Bean中有autowire属性。该属性在Spring5.1的时候已经被标记为过时了
当前程序的类图变成了这样。其中User和Person仍然没有任何变化,但是却新增了一个AutowiredConfiguration类,该类作为配置类,并且XML文件中也发生了变化,Person这个类不在通过XML文件的方式放入到IOC中而是通过配置类的@Bean来放入到IOC中
AutowiringConfiguration类
public class AutowiringConfiguration {
// 指定autowiring的模式为byType
@Bean(autowire = Autowire.BY_TYPE)
public Person person() {
return new Person();
}
}
我们可以看到,仍然可以进行自定绑定,不然不得不提的是通过@Bean的方式,只对当前类进行自动绑定,在我们上述例子中。我们Person类放入IOC中的时候@Bean上指定了Autowiring模式。那么就只有Person类有Autowiring的能力,如果想要其他类也有则其他类的@Bean上也要为其指定Autowiring模式
我们了解完Autowiring之后该我们的 beanFactory.ignoreDependencyInterface(Class> ifc) 方法上场了。
Spring在org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory方法中有使用到
我第一次看源码看到这个方法的时候我以为该方法是你在@Autowired的时候不给你进行注入,然而经过我的多方面测试,通过@Autowired仍然能够注入进来,这让我百思不得其解,在网上找了大量资料之后才明白其方法的作用。
这个方法与我们上面讲的Autowiring模式息息相关。
此时我们的类图变成了这样。其中AutowiringConfiguration新增了一个方法,这个方法将BeanFactoryPostProcessorImpl放入到IOC中
AutowiringConfiguration 类
public class AutowiringConfiguration {
@Bean(autowire = Autowire.BY_TYPE)
public Person person() {
return new Person();
}
@Bean
public BeanFactoryPostProcessor beanFactoryPostProcessor() {
return new BeanFactoryPostProcessorImpl();
}
}
BeanFactoryPostProcessorImpl类
public class BeanFactoryPostProcessorImpl implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 我们的 beanFactory.ignoreDependencyInterface()方法善良登场了
beanFactory.ignoreDependencyInterface(Person.class);
}
}
我们可以看到在 BeanFactoryPostProcessorImpl中我们的 beanFactory.ignoreDependencyInterface()方法善良登场了。
继续运行程序看看有什么不同
我们发现Person类的setUser(User)方法竟然不执行了?也就是Autowiring模式失效了。
beanFactory.ignoreDependencyInterface() 方法的确是忽略给定接口的自动装配。但是这个自动装配不是 @Autowired