@Autowired @Resource @Qualifier的区别
@Autowired
- 注释进行自动注入是,Spring容器中匹配的候选Bean数量必须只有一个,当找不到一个匹配的Bean时候,Spring容器抛出BeanCreationException一次,并且指出至少拥有一个匹配的Bean,Autowired默认按照byType进行注入,如果发现找到多个bean,则又按照byname进行查询,如果还是多个则抛出异常。
@Autowired
private UserNameServiceImpl userNameService;
//UserNameServiceImpl是一个接口
- spring先找类型是UsernameServiceImpl的bean
- 如果存在并且唯一则正常得到bean类
- 不唯一,则会再查找到的结果集中寻找name为userNameService的bean,因为bean的name有唯一性,这样应该可以定位到满足的唯一bean
- @Autowired手动按照byName方式注入,使用@Qualifier标签
@Autowired
@Qualifier("userNameService")
@Qualifier("userNameService")
- Spring运行我们通过该注解指定bean的名称,通过这个注解的方式我们可以解决多数据源的问题,如下:
@Value("${mongodb.address.uri}")private String mongAddressUri;@Value("${mongodb.moment.uri}")private String mongoMomentUri;@Value("${mongodb.address.database}")private String mongAddressDB;@Value("${mongodb.moment.database}")private String mongMomentDB;@Bean@Qualifier("addressTemplate")public MongoTemplate addressTemplate(){MongoClient client = new MongoClient(new MongoClientURI(mongAddressUri));MongoDbFactory factory = new SimpleMongoDbFactory(client, mongAddressDB);return new MongoTemplate(factory);}@Bean@Primary@Qualifier("momentTemplate")public MongoTemplate momentTemplate(){MongoClient client = new MongoClient(new MongoClientURI(mongoMomentUri));MongoDbFactory factory = new SimpleMongoDbFactory(client, mongMomentDB);return new MongoTemplate(factory);}
- 如上所示,我们定义了两个mongoTemplate类型的bean,但是通过@Qualifier注解指定了bean的名称,然后通过@Primary注解的作用在使用方不指定beanname的情况下默认加载的bean,使用方法如下
@Autowired
@Qualifier("addressTemplate")
private MongoTemplate mongoAddressTemplate;@Autowired
@Qualifier("momentTemplate")
private MongoTemplate momentTemplate; //或者如下方式@Autowired
private MongoTemplate momentTemplate; //此处不指定beanname,默认使用momentTemplate
- Spring不但支持自己定义的@Autowired注解,还支持几个有JSR-250规范定义的注解,他分别是@Resource,@PostConstruct以及 @PreDestroy
@Resource
-
作用相当于@Autowired,只不过@Autowired按照byType自动注入,而@Resource默认按照byName注入,@Resource中有两个属性比较重要,分别是name和type,Spring将@Resource注解的name属性解析为bean名称,这种方式类似通过数据库id查询,type属性解析为bean的类型,所有如果使用name属性就用byname策略,使用type属性时候则用byType的策略,不知道时候,通过放射机制使用byName自动注入。
- @Resource装配顺序
- 如果同时制定name, type,则从Spring上下文中找到唯一匹配进行装配,找不到抛出异常
- 指定了name则从上下文中查找名称匹配的bean进行装配,找不到则抛出异常
- 如果指定type,则从上下文中找到类似匹配的唯一bean进行装配,找不到抛出异常
- 既没有指定name也没有type,则按照默认byName的方式装配,如果没有匹配,则返回一个原始类型进行匹配,此时匹配到则自动装配