今天在项目中使用线程池执行任务时,发现配置的线程池参数怎么都没有生效(固定了线程池的线程数为1,但实际执行任务时却有10多个线程在跑),一番排查过后发现原来是我配置的线程池名称跟Spring容器中已存在的线程池重名了,通过Async注解进行注入时,spring默认选了原先容器中存在的线程池,所以没有生效。于是联想到Autowired注解好像也会出现类似的注入问题,所以写下这篇文章记录一下。
@Autowired
spring的注解,默认是按照Type进行自动装配,当且仅有一个匹配的Bean时,才能正常注入。如果一个接口被多个实现类实现,或者Spring容器中存在两个相同类型的Bean、使用Autowired注入该属性会报BeanCreationException
@Qualifier
spring的注解,按name注入,一般当出现两个及以上bean时,不知道要注入哪个,作为@Autowired()的修饰用
@Resource
@Resource(J2EE注解),默认按name注入,可以通过name和type属性进行选择性注入。默认按照注入类名的小写作为name去注入Bean,如果发现并没有这个名字的实例,然后会根据类型自动匹配
来看例子
Controller
/**
* @author JayChan
* @Description
* @create 2023-01-17 09:10
*/
@RestController
public class TestAutowireController {
@Autowired
private TestUser testUser;
@Autowired
private IUserService userService;
@RequestMapping("/bean")
public String bean() {
return testUser.getUsername();
}
@RequestMapping("/service")
public String service() {
return userService.getUser().getUsername();
}
}
BeanFactory
/**
* @author JayChan
* @Description bean的方式注入两个相同的bean
* @create 2023-01-17 09:07
*/
@Component
public class BeanFactory {
@Bean("userA")
public TestUser get(){
TestUser testUser = new TestUser();
testUser.setUsername("userA");
testUser.setId(1L);
return testUser;
}
@Bean("userB")
public TestUser get2(){
TestUser testUser = new TestUser();
testUser.setUsername("userB");
testUser.setId(1L);
return testUser;
}
}
IUserService
public interface IUserService {
public TestUser getUser();
}
两个实现类
@Service
public class UserServiceImpl implements IUserService{
@Override
public TestUser getUser() {
TestUser testUser = new TestUser();
testUser.setUsername("i come from UserServiceImpl");
return testUser;
}
}
@Service
public class UserServiceImpl2 implements IUserService{
@Override
public TestUser getUser() {
TestUser testUser = new TestUser();
testUser.setUsername("i come from UserServiceImpl2");
return testUser;
}
}
iDea的提示非常智能,在编译前就已经帮检测出注入的bean对象可能有多个实例,不能自动装配
![](https://img-blog.csdnimg.cn/img_convert/db66cdce9a4a6f1ac58be3425ab6fd97.png)
这时候就可以通过@Qualifier注解来指定注入某个名称的Bean
![](https://img-blog.csdnimg.cn/img_convert/6044aac070992bf0fe0c863c5162322c.png)
或者直接使用@Resource
![](https://img-blog.csdnimg.cn/img_convert/9840e80e7de279a63cde74bc7ecb3ba6.png)