文章目录
总结
@Autowired
@Autowired默认是根据类型获取bean的,如果想要根据name去获取,可以与@Qualifier注解组合使用,比如:
@Autowired
UserService userService; // 默认方式,根据类型找到bean
@Autowired
@Qualifier("userServiceImpl")
UserService userService; // 与@Qualifier组合使用,根据name获取bean,注意首字母要小写。
注:如果不使用@Qualifier,那么对应的Bean只能有一个实现。如果有多个实现类,就会出现以下异常:
Description:
Field helloService in com.example.autowireddemo.HelloAction required a single bean, but 2 were found:
......
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
@Resource
@Resource默认是根据name获取bean,也可以通过指定name或type的值来更改获取方式。如果两个属性都指定了,就去找符合条件的唯一bean。
具体规则如下:
- 如果没有指定任何属性,根据默认的name获取,如果没找到,那么根据type获取
- 如果指定了属性,则根据属性(name或type)获取
举例:
// interface: UserService, impl: UserServiceImpl
@Resource
UserService userService; // 未指定属性,先根据userService这个name获取,然后再根据类型获取,最终会获取到UserServiceImpl类
@Resource(name="userServiceImpl")
UserService userService; // 根据name获取
@Resource(type=UserServiceImpl.class)
UserService userService; // 根据type获取
@Resource(name="userServiceImpl", type=UserServiceImpl.class)
UserService userService; // 根据name和type获取唯一bean
如果UserService有UserServiceImpl和UserServiceImpl2两个实现类呢,那么必须要指定name或者type了,否则@Resource首先会根据name获取,显然userService对应的Bean是获取不到的,然后会根据type获取,发现有两个实现类,就会报以下异常:
Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.example.autowireddemo.HelloService' available: expected single matching bean but found 2: helloServiceImpl,helloServiceImpl2
源码
@Autowired
package org.springframework.beans.factory.annotation;
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
boolean required() default true;
}
@Resource
package javax.annotation;
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
String name() default "";
String lookup() default "";
Class<?> type() default java.lang.Object.class;
enum AuthenticationType {
CONTAINER,
APPLICATION
}
AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
boolean shareable() default true;
String mappedName() default "";
String description() default "";
}
参考
- @Resource和@Autowired:https://www.jianshu.com/p/5ecfe2c9304a
- @Autowired和@Resource的区别:https://blog.csdn.net/weixin_40423597/article/details/80643990
- Spring中@Qualifier的用法:https://blog.csdn.net/qq_36567005/article/details/80611139