在学习spring源码时,遇到了ignoreDependencyInterface
方法,但是讲课老师,只是简单的讲了一下它的作用是:实现了这些接口的实现类,不能通过这些接口类型来自动注入。
实在是好奇,它是不是真的能忽略依赖注入,于是测试了一番。
定义一个要忽略的接口:
setter方法的入参就是要忽略的依赖,为啥要用setter方法呢,
看AutowireUtils类的isSetterDefinedInInterface方法。里面有约定用setter方法
public interface IgnoreInterface {
void setList(List<String> list);
void setStudent(Student student);
}
实现类:
public class IgnoreInterfaceImpl implements IgnoreInterface {
private List<String> list;
private Student student;
private Set<String> set;
@Override
public void setList(List<String> list) {this.list = list;}
@Override
public void setStudent(Student student) { this.student=student; }
public void setSet(Set<String> set) {this.set = set;}
@Override
public String toString() {
return "IgnoreInterfaceImpl{" +
"list=" + list +
", student=" + student +
", set=" + set +
'}';
}
}
public class IgnoreInterfaceImpl2 implements IgnoreInterface {
private List<String> list;
private Student student;
private Set<String> set;
@Override
public void setList(List<String> list) {this.list = list;}
@Override
public void setStudent(Student student) { this.student=student; }
public void setSet(Set<String> set) {this.set = set;}
@Override
public String toString() {
return "IgnoreInterfaceImpl2{" +
"list=" + list +
", student=" + student +
", set=" + set +
'}';
}
}
配置类:
这里必须说明,不能使用@Autowire
来注入Student
和List<String>
,不然的话忽略不起作用,使用@Bean(autowire =Autowire.BY_TYPE)
这种方式
@Configuration
@ComponentScan("com.example.threaddemo.threaddemo.kz")
public class ExtConfig {
@Bean(autowire=Autowire.BY_TYPE)
public IgnoreInterfaceImpl ignoreInterface( ){
IgnoreInterfaceImpl ignoreInterface=new IgnoreInterfaceImpl();
Set<String> strings=new HashSet<>();
strings.add("hah");
ignoreInterface.setSet(strings);
return ignoreInterface;
}
@Bean(autowire =Autowire.BY_TYPE)
public IgnoreInterfaceImpl2 ignoreInterfaceImpl2(){
IgnoreInterfaceImpl2 ignoreInterfaceImpl2=new IgnoreInterfaceImpl2();
Set<String> strings=new HashSet<>();
strings.add("xixi");
ignoreInterfaceImpl2.setSet(strings);
return ignoreInterfaceImpl2;
}
@Bean
public List<String> list(){
List<String> list=new ArrayList<>();
list.add("lzh");
return list;
}
@Bean
public Student student(){
Student student=new Student();
student.setName("aa");
return student;
}
}
定义一个BeanFactoryPostProcessor:
@Component
public class IgnoreAutowiringProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
//1.如果指定的是接口并且接口里有setter方法,那么该接口的所有实现类中和接口setter方法入参相同的依赖,都会被忽略
//2.如果指定的是实现类,那么只会忽略当前实现类中和接口setter方法入参相同的依赖
//beanFactory.ignoreDependencyInterface(IgnoreInterface.class);
//所有bean的List属性都忽略,不给注入
//beanFactory.ignoreDependencyType(List.class);
}
}
测试:
@Test
public void test(){
AnnotationConfigApplicationContext applicationContext=
new AnnotationConfigApplicationContext(ExtConfig.class);
IgnoreInterfaceImpl bean = applicationContext.getBean(IgnoreInterfaceImpl.class);
System.out.println("IgnoreInterfaceImpl:"+bean);
IgnoreInterfaceImpl2 bean2 = applicationContext.getBean(IgnoreInterfaceImpl2.class);
System.out.println("IgnoreInterfaceImpl2:"+bean2);
applicationContext.close();
}
1.先什么都不忽略,直接运行,可以看到都是有结果的
IgnoreInterfaceImpl:IgnoreInterfaceImpl{list=[lzh], student=Student(name=aa), set=[hah]}
IgnoreInterfaceImpl2:IgnoreInterfaceImpl2{list=[lzh], student=Student(name=aa), set=[xixi]}
2.我想忽略所有bean
的List
属性都给忽略,不给注入
打开注释 //beanFactory.ignoreDependencyType(List.class);
,运行,可以看到所有的bean的list属性都没被注入
IgnoreInterfaceImpl:IgnoreInterfaceImpl{list=null, student=Student(name=aa), set=[hah]}
IgnoreInterfaceImpl2:IgnoreInterfaceImpl2{list=null, student=Student(name=aa), set=[xixi]}
3.我想忽略IgnoreInterface
接口下的所有实现类的List<String>
和Student
属性,都不给注入
打开注释//beanFactory.ignoreDependencyInterface(IgnoreInterface.class);
同时注释beanFactory.ignoreDependencyType(List.class);
IgnoreInterfaceImpl:IgnoreInterfaceImpl{list=null, student=null, set=[hah]}
IgnoreInterfaceImpl2:IgnoreInterfaceImpl2{list=null, student=null, set=[xixi]}
可以看到IgnoreInterface
接口下的所有实现类的list
,student
都没被注入
4.我只想忽略指定类里的List<String>
和Student
属性,不给注入
打开注释//beanFactory.ignoreDependencyInterface(IgnoreInterface.class);
同时注释beanFactory.ignoreDependencyType(List.class);
并把IgnoreInterface
改成IgnoreInterfaceImpl
IgnoreInterfaceImpl:IgnoreInterfaceImpl{list=null, student=null, set=[hah]}
IgnoreInterfaceImpl2:IgnoreInterfaceImpl2{list=[lzh], student=Student(name=aa), set=[xixi]}
只有IgnoreInterfaceImpl
的list
,student
没有被注入
总结:
ignoreDependencyType
可以在所有的bean中忽略指定的依赖。
ignoreDependencyInterface
可以忽略指定接口或类中的指定的依赖