@Resource
1. 介绍
@Resource
注解是JSR250规范中提供的注解,主要作用就是通过JNDI技术查找依赖的组件并注入到类、字段和方法中来。
默认情况下,不指定注解任何属性时,会默认按照byName的方式装配Bean对象,如果指定了name属性,没有指定type属性,则采用byName的方式装配Bean对象,
如果没有指定name属性,而是指定了type属性,则按照byType的方式装配bean对象。
当同时指定了type属性和name属性,则两个属性都会校验,任何一个不符合条件就会报错。
当存在多个类型相同的bean时,可以指定@Resource
注解的name属性指定装配哪个bean对象。相当于@Autowired
注解与@Qualifier
注解的组合。
@Resource
注解与@Qualifier
注解也可以搭配使用,通过@Qualifier
注解指定装配哪个bean。
2. @Resource
&& @Autowired
@Resource
注解时JSR250规范中提供的注解,如果使用的JDK8版本,则无需额外导入依赖,如果使用的JDK版本低于8或高于11,则需要额外导入依赖;@Autowired
注解时基于Spring框架提供的注解。
@Resource
注解默认通过byName的方式装配bean,找不到bean的话,就通过byType的方式装配Bean;@Autowired注解默认根据byType的方式装配bean,如果需要根据名称装配bean,则需要结合@Qualifier注解一起使用。
@Resource
注解标注到类、字段和方法上。@Autowired
注解标注到构造方法、方法、参数、字段、其他注解上。
3. 源码
package jakarta.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Resources.class)
public @interface Resource {
// 资源JNDI名称,装配指定名称的bean
String name() default "";
// 装备指定类型的bean
String lookup() default "";
// 引用指向的资源名称,可以使用JNDI名称只想任何兼容的资源。
Class<?> type() default Object.class;
// 执行身份验证类型
enum AuthenticationType {
CONTAINER,
APPLICATION
}
Resource.AuthenticationType authenticationType() default Resource.AuthenticationType.CONTAINER;
// 执行当前bean是否可以在多个组件之间共享
boolean shareable() default true;
// 指定资源的映射名称
String mappedName() default "";
// 指定资源的描述
String description() default "";
}
4. Demo
- 在构造方法上使用
import jakarta.annotation.Resource;
import javax.sql.DataSource;
public class DatabaseService {
private final DataSource dataSource;
// 使用@Resource注解注入DataSource
@Resource(name = "myDataSource")
public DatabaseService(DataSource dataSource) {
this.dataSource = dataSource;
}
public void performDatabaseOperation() {
// 使用dataSource执行数据库操作
}
}
- 在Setter方法上使用
import jakarta.annotation.Resource;
import javax.sql.DataSource;
public class DatabaseService {
private DataSource dataSource;
// 使用@Resource注解注入DataSource
@Resource(name = "myDataSource")
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void performDatabaseOperation() {
// 使用dataSource执行数据库操作
}
}
- 在字段上使用
import jakarta.annotation.Resource;
import javax.sql.DataSource;
public class DatabaseService {
// 使用@Resource注解注入特定类型的DataSource
@Resource(type = CustomDataSource.class)
private DataSource dataSource;
public void performDatabaseOperation() {
// 使用dataSource执行数据库操作
}
}
5. 补充
5.1 JDNI
JNDI是Java Naming and Directory Interface的缩写,即Java命名和目录接口。它是Java平台的一个标准扩展,提供了一组接口、类和关于命名空间的概念。JNDI是一个provider-based的技术,这意味着任何基于名字的技术都能通过JNDI提供服务,只要JNDI支持这项技术。JNDI目前所支持的技术包括LDAP、CORBA Common Object Service(COS)名字服务、RMI、NDS、DNS、Windows注册表等。
JNDI通过绑定的概念将对象和名称联系起来。在一个文件系统中,文件名被绑定给文件;在DNS中,一个IP地址绑定一个URL;在目录服务中,一个对象名被绑定给一个对象实体。JNDI中的一组绑定作为上下文来引用,每个上下文暴露的一组操作是一致的,例如查找操作,返回指定名字的相应对象,以及绑定和撤除绑定名字到某个对象的操作。
JNDI使用通用的方式来暴露命名空间,即使用分层上下文以及使用相同命名语法的子上下文。很多J2EE技术,包括EJB都依靠JNDI来组织和定位实体。简而言之,JNDI为Java应用程序提供了一个查找和访问各种命名和目录服务的通用统一的接口。
5.2 JSR
SR是Java Specification Requests的缩写,意思是“Java规范提案”。它是一种向Java社区进程(Java Community Process,简称JCP)提出的正式请求,用于新增一个标准化技术规范。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准,它允许Java开发者和授权者共同制定标准,这些标准随后会被软件厂商实现,从而推动Java技术的发展。
JCP是一个由来自世界各地的Java代表成员组成的组织,负责监督Java的发展。JCP维护的规范包括Java SE、Java EE、Java ME、XML、OSS、JAIN等。通过JSR,组织成员可以提交Java技术规范、参考实现(RI)和技术兼容包(TCK),这些内容最终会成为下一版本的规范的一部分。
5.3 JSR中定义的部分注解
- @Resource:这是JSR-250标准中定义的注解,用于依赖注入,可以完成属性注入。
@Resource
注解是JDK扩展包中的一部分,属于标准注解,具有通用性。它可以指定名称(name
)和类型(type
)等参数来注入特定的资源。 - @PostConstruct和@PreDestroy:这两个注解也是JSR-250标准中定义的,分别用于标注在方法上,表示在构造函数执行之后(
@PostConstruct
)和在销毁之前(@PreDestroy
)需要执行的方法。 - @Inject:这是JSR-330标准中定义的注解,用于依赖注入。它提供了一种声明式的方式来实现依赖注入,可以替代
@Autowired
注解在某些场景下的使用。 - @Named和@Singleton:这些注解来自JSR-330,
@Named
用于标注一个bean的名称,@Singleton
用于标注一个bean的作用域为单例。 - @Provider:这是JSR-330中定义的注解,用于标注一个实现了
javax.inject.Provider
接口的类,该接口提供了一个方法get()
来获取bean的实例。