文章目录
前言
ignoreDependencyInterface方法是笔者在阅读Spring源码过程中遇到的,刚看到时还不明白其真正含义,导致笔者对此方法有所误解,冥思苦想许久,依然想不明白,决定做一下实验,做完实验后,恍然大悟!!!
ignoreDependencyInterface方法有什么用?
其作用就是在Spring自动装配Bean的时候忽略掉接口实现类或普通类中的set注入,这么说可能有点抽象,我们来看下面的案例
案例
说明
例如,A接口中有一个B实现类,我不希望它能够使用set进行注入Cat对象,而是使用别的注入方式,那么我们就可以使用到ConfigurableListableBeanFactory接口的ignoreDependencyInterface方法,来看下示例吧
Cat类
package com.spring.demo.test;
public class Cat {
}
接口
package com.spring.demo.test;
public interface A {
void setCat(Cat cat);
}
实现类
package com.spring.demo.test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Resource;
public class B implements A {
private Cat cat;
@Override
public void setCat(Cat cat) {
this.cat = cat;
}
public Cat getCat() {
return cat;
}
}
BeanFactoryPostProcessor实现类
怎么拿到ConfigurableListableBeanFactory接口?我们通过实现BeanFactoryPostProcessor接口可以拿到ConfigurableListableBeanFactory接口并配置自动装配时忽略该接口实现类的set注入
//BeanFactoryPostProcessorImpl.java
package com.spring.demo.test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
public class BeanFactoryPostProcessorImpl implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
//这里有个注意的点,就是参数传“接口.class or 类.class”都会生效,对于接口实现类和普通类都会生效,因为它在检查的时候只会看当前类或实现的接口里有没有定义set方法(即set注入)
beanFactory.ignoreDependencyInterface(A.class);
}
}
spring-context.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="cat" class="com.spring.demo.test.Cat" ></bean>
<bean id="b" class="com.spring.demo.test.B" autowire="byType"/> //一定要开启自动装配,byType或byName
<bean class="com.spring.demo.test.BeanFactoryPostProcessorImpl"/>
</beans>
测试
Main.java
package com.spring.demo;
import com.spring.demo.test.A;
import com.spring.demo.test.B;
import com.spring.demo.test.Cat;
import com.spring.demo.test.Dog;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionReader;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
System.out.println(bean);
}
}
两种情况
-
不调用ignoreDependencyInterface方法
通过debug可以发现,cat对象是成功被注入了的,接下来我们再看看调用ignoreDependencyInterface方法会是什么结果 -
调用ignoreDependencyInterface方法
调用ignoreDependencyInterface方法后set注入失败,值为null
以上是针对接口实现类的,那我们还有一种情况,直接忽略普通类可不可以呢?
首先,把B类实现的A接口去掉,然后再把beanFactory.ignoreDependencyInterface(A.class);改成beanFactory.ignoreDependencyInterface(B.class);,我们直接忽略普通类看看能不能注入成功
可以看到结果是注入失败的
总结
做完实验后,我们得出以下总结:
- ignoreDependencyInterface方法是用来忽略接口实现类和普通类set注入的
- 不论是接口实现类还是普通类,都能进行配置忽略set注入(可以通过其他注入方式进行依赖注入)