1.声明
当前内容主要用于本人复习Spring5的@Autowired、@Bean和@Qualifier等注解,以及其中的区别
Spring5.1.5版本
本内容采用注解配置和组件扫描方式
本次使用的pom.xml依旧相同
<context:annotation-config />
<context:component-scan base-package=“com.hy.java.spring.annotation.qualifier” />
2.测试
自动注入bean
MovieFinder.java
public class MovieFinder {
public int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void find() {
System.out.println("current movie finder find a moviee ....");
}
}
QualifierAnnotationConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QualifierAnnotationConfig {
@Bean
public MovieFinder getMainMovieFinder() {
MovieFinder mainMovieFinder = new MovieFinder();
mainMovieFinder.setId(11111);
return mainMovieFinder;
}
}
SimpleMovieLister .java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component("simpleMovieLister")
public class SimpleMovieLister {
@Autowired
private MovieFinder mainMovieFinder;
public MovieFinder getMainMovieFinder() {
return mainMovieFinder;
}
public void setMainMovieFinder(MovieFinder mainMovieFinder) {
this.mainMovieFinder = mainMovieFinder;
}
}
QualifierAnnotationTest .java
/**
* @description
* @author admin
*
*/
public class QualifierAnnotationTest {
public static void main(String[] args) {
String xml = "/com/hy/java/spring/annotation/qualifier/applicationContext.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(xml);
SimpleMovieLister simpleMovieLister = context.getBean("simpleMovieLister", SimpleMovieLister.class);
System.out.println(simpleMovieLister);
System.out.println("mainMovieFinder id==>"+simpleMovieLister.getMainMovieFinder().getId());
}
}
1.当只有@Autowired且IOC容器中只有一个对应类型的bean时,那么注入成功!
com.hy.java.spring.annotation.qualifier.SimpleMovieLister@6156496
mainMovieFinder id==>11111
2.当只有@Autowired且IOC容器中有两个或两个以上对应类型的bean时,那么注入失败!(抛出异常)
此时修改当前的QualifierAnnotationConfig.java中的代码:
@Bean
public MovieFinder getMainMovieFinder() {
MovieFinder mainMovieFinder = new MovieFinder();
mainMovieFinder.setId(11111);
return mainMovieFinder;
}
// 这是添加的@Bean
@Bean
public MovieFinder getMovieFinder() {
MovieFinder mainMovieFinder = new MovieFinder();
mainMovieFinder.setId(22222);
return mainMovieFinder;
}
再次测试的结果为:报错
No qualifying bean of type ‘com.hy.java.spring.annotation.qualifier.MovieFinder’ available: expected single matching bean but found 2: getMainMovieFinder,getMovieFinder
解决本问题有:1.通过设置@Bean(“beanName”),且beanName对应SimpleMovieLister.java中的属性名称完全一致可以注入成功!
3.当只有@Autowired且IOC容器中有两个或两个以上对应类型的bean时,如果配置了@Bean(“beanName”),默认可以通过beanName的方式注入(自动查找setBeanName方法),如果有那么成功,否则报错
此时修改2中的文件QualifierAnnotationConfig.java中的内容的@Bean为其添加自定义名称,修改为
@Bean(name = "mainMovieFinder")
public MovieFinder getMainMovieFinder() {
MovieFinder mainMovieFinder = new MovieFinder();
mainMovieFinder.setId(11111);
return mainMovieFinder;
}
@Bean(name = "movieFinder")
public MovieFinder getMovieFinder() {
MovieFinder mainMovieFinder = new MovieFinder();
mainMovieFinder.setId(22222);
return mainMovieFinder;
}
再次启动发现成功!
com.hy.java.spring.annotation.qualifier.SimpleMovieLister@37e547da
mainMovieFinder id==>11111
通过@Bean中的beanName方式自动注入,再次修改2中的文件SimpleMovieLister.java中的内容
@Autowired
private MovieFinder mainMovieFinder;
public MovieFinder getMainMovieFinder() {
return mainMovieFinder;
}
public void setMainMovieFinder(MovieFinder mainMovieFinder) {
this.mainMovieFinder = mainMovieFinder;
}
// 这是新添加的注入属性
@Autowired
private MovieFinder movieFinder;
public MovieFinder getMovieFinder() {
return movieFinder;
}
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
在测试中添加:System.out.println(“movieFinder id==>”+simpleMovieLister.getMovieFinder().getId());
测试结果:成功!(此时的@Bean的beanName和注入的属性名称完全一致)
com.hy.java.spring.annotation.qualifier.SimpleMovieLister@6107227e
mainMovieFinder id==>11111
movieFinder id==>22222
如果@Bean中的beanName和注入的属性不一致那么报错:修改上面的文件SimpleMovieLister.java中的属性movieFinder为movieFinder2
测试结果:报错!
Error creating bean with name ‘simpleMovieLister’: Unsatisfied dependency expressed through field ‘movieFinder2’;
4.当只有@Autowired且IOC容器中有两个或两个以上对应类型的bean时,如果配置有@Qualifier(“beanName”),那么默认就是按照beanName找,如果没有则报错(一般和@Bean的名称一致)
此时只要添加@Qualifier(“beanName”)方式就可以解决3中的问题,修改SimpleMovieLister.java中的内容
@Autowired
private MovieFinder mainMovieFinder;
public MovieFinder getMainMovieFinder() {
return mainMovieFinder;
}
public void setMainMovieFinder(MovieFinder mainMovieFinder) {
this.mainMovieFinder = mainMovieFinder;
}
@Autowired
@Qualifier("movieFinder") // 新添加的注解
private MovieFinder movieFinder2;
public MovieFinder getMovieFinder2() {
return movieFinder2;
}
public void setMovieFinder2(MovieFinder movieFinder2) {
this.movieFinder2 = movieFinder2;
}
3.总结
- @Autowired一般是先按照类型注解
- 如果类型不存在则报错,然后如果只有一个类型则注入
- 如果存在两个以上的类型,可以按照
@Bean的beanName和需要注入的属性名称一致的方式注入 - 如果存在两个以上的类型,且
@Bean的beanName和需要注入的属性名称不一致,那么报错
- @Bean一般用在方法上面,默认返回一个对象并注入到IOC容器中,可以设置beanName
- @Qualifier一般和@Autowired一起连用,
采用@Bean的beanName注入,如果找不到则报错