在写依赖注入时,除了@Autowired,还经常看到@Resource的身影。@Resource与@Autowired有哪些区别和联系呢?
@Resource 是Java EE 提供的用于进行依赖注入的注解,它可以标注在字段、构造方法、Setter 方法或者配置类的方法上,完成依赖注入的操作。
与 @Autowired 注解不同的是,@Resource 是按照名称进行装配的,可以通过 name 属性指定要注入的 Bean 的名称。
一、@Resource源码
package javax.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Resource 注解标记了应用程序所需的资源。
*/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Resource {
/**
* 资源的 JNDI 名称。对于字段注解,默认为字段名称。对于方法注解,默认为 JavaBeans 属性名称。
*/
String name() default "";
/**
* 资源的 Java 类型。对于字段注解,这是字段的类型。对于方法注解,它是方法解析到的参数或返回类型的类型。默认为带注解的字段或参数的类型。
*/
Class<?> type() default java.lang.Object.class;
/**
* 用于此资源的身份验证类型。默认为 container。
*/
AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
/**
* 指示资源是否可以在此组件和其他组件之间共享。
*/
boolean shareable() default true;
/**
* 该资源应映射到的产品特定名称。
*/
String mappedName() default "";
/**
* 引用指向的资源的名称。它可以链接到同一环境中的另一个资源,也可以链接到不同环境中的资源,具体取决于容器定义的语法。
*/
String lookup() default "";
}
当使用 @Resource 注解时,如果指定了 name 属性,则容器会按照指定的名称在容器中查找对应的 Bean 进行注入;如果没有指定 name 属性,则容器会按照标注 @Resource 注解的字段或方法的名称来在容器中查找对应的 Bean 进行注入。
二、@Resource应用示例
四、最后总结
@Resource与@Autowired的联系
@Resource与@Autowired的区别:
总的来说,@Autowired 是Spring框架提供的依赖注入注解,更加灵活,但与Spring框架耦合度较高;而@Resource 是Java EE提供的依赖注入注解,更加通用,但功能相对较少。
-
在字段上应用 @Resource 注解:
public class Example { @Resource private DataSource dataSource; // 其他代码 }
-
在方法上应用 @Resource 注解:
public class Example { private DataSource dataSource; @Resource public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } // 其他代码 }
-
指定资源的名称:
@Resource(name = "myDataSource") private DataSource dataSource;
-
指定资源的类型:
@Resource(type = MyService.class) private MyService myService;
-
指定资源的身份验证类型:
@Resource(authenticationType = AuthenticationType.APPLICATION) private MyService myService;
-
指定资源是否可共享:
@Resource(shareable = false) private MyResource myResource;
-
指定资源的 JNDI 名称:
@Resource(mappedName = "java:comp/env/jdbc/myDataSource") private DataSource dataSource;
-
指定资源的查找名称:
@Resource(lookup = "java:comp/env/jdbc/myDataSource") private DataSource dataSource;
这些示例展示了 @Resource 注解在不同情境下的使用方法,可以根据具体需求来选择合适的用法。
三、使用@Resource注解注意事项
-
指定名称:如果使用@Resource注解进行依赖注入,可以通过name属性指定要注入的Bean的名称。如果不指定name属性,容器会按照标注@Resource注解的字段或方法的名称来在容器中查找对应的Bean进行注入。
-
避免名称歧义:如果容器中存在多个同类型的Bean,且没有通过name属性指定具体的Bean名称,容器会根据字段或方法的名称来进行注入。因此,在使用@Resource注解时,需要确保Bean名称的唯一性,避免名称歧义。
-
与@Autowired的区别:虽然@Resource和@Autowired都可以用于依赖注入,但它们的行为和用法有所不同。需要根据具体的使用场景和需求选择合适的注解。
-
都可以用来完成依赖注入,将一个Bean注入到另一个Bean中。
-
都可以标注在字段、构造方法、Setter方法或者配置类的方法上,完成依赖注入的操作。
-
@Autowired 是Spring框架提供的注解,而 @Resource 是Java EE提供的注解。
-
@Autowired 是按照类型进行自动装配的,如果容器中存在多个类型匹配的Bean,可以结合@Qualifier注解使用,也可以结合@Primary注解使用。而 @Resource 是按照名称进行装配的,可以通过name属性指定要注入的Bean的名称。
-
@Autowired 是Spring特有的注解,如果要使用它,必须导入Spring的包。而 @Resource 是Java EE的标准注解,不需要额外导入包。
-
在使用@Autowired时,如果找不到匹配的Bean,会抛出异常;而在使用@Resource时,如果找不到匹配的Bean,会返回null。