Spring之@Autowired和@Resource总结


总结

@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。

具体规则如下:

  1. 如果没有指定任何属性,根据默认的name获取,如果没找到,那么根据type获取
  2. 如果指定了属性,则根据属性(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 "";
}

参考

  1. @Resource和@Autowired:https://www.jianshu.com/p/5ecfe2c9304a
  2. @Autowired和@Resource的区别:https://blog.csdn.net/weixin_40423597/article/details/80643990
  3. Spring中@Qualifier的用法:https://blog.csdn.net/qq_36567005/article/details/80611139

猜你喜欢

转载自blog.csdn.net/qq_28379809/article/details/100529368
今日推荐