注解@autowired与@resources的区别
@Resource和@Autowired都是用于bean的依赖注入,其实@Resource并不是Spring的注解,它是J2EE的,它的包是javax.annotation.Resource,而@Autowired的包是org.springframework.beans.factory.annotation.Autowired,但Spring支持该@resources的注入(Spring支持几个JSR-250规范定义的注解,它们分别是@Resource、@PostConstruct、@PreDestroy)。
1、@autowired
源码
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
boolean required() default true;
}
2、@resources
源码
package javax.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
@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 "";
/**
* Description of this resource. The description is expected
* to be in the default language of the system on which the
* application is deployed. The description can be presented
* to the Deployer to help in choosing the correct resource.
*/
String description() default "";
}
3、共同点
都可以标注在字段和setter方法上。当然,如果标注在字段上,则不需要再写Setter方法。
4、不同点
(1)@autowired
只按照byType注入。默认情况下要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false。如:@Autowired(required=false),如果我们想使用byName注入,可以结合@Qualifier注解进行使用,如下:
@Autowired(required=false)
@Qualifier("userService")
private SserService userService;
problem:从源码上看@autowired是根据type进行依赖注入,但是当把其所依赖的类命名后,哪怕同一个接口存在多个实现类,也不会导致依赖冲突,这里究竟如何实现的?
(2)@Resource默认按照byName自动注入,有两个重要属性:name和type。Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用那么属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略,如果既不指定name也不指定type属性,这是将通过反射机制使用byName自动注入。
@RestController
public class UserController {
@Autowired
private UserMapper userMapper;
@Resource
//@Rsource(name = "userService")
private UserService userService;
@Resource(name="userService",type=userService.class)
public void setUserService(UserService userService) { // 用于属性的setter方法上
this.userService = userService;
}
}
@Resource
装配规则:
1、如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
2、如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
3、如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或找到多个,都会抛出异常。
4、如果既没有指定name,也没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个byType进行匹配,如果匹配则自动装配。通过设置CommonAnnotationBeanPostProcessor 的‘fallbackToDefaultTypeMatch’属性为“false”(默认值是“true”)可以禁用这一特性。