在Spring框架中,@Autowired
和@Resource
都是用来进行依赖注入的注解
@Autowired和@Resource所属的包不同,这反映了它们不同的来源和设计理念
@Autowired:这个注解是由Spring框架提供的,属于包。它是Spring框架的一部分,用于实现依赖注入的功能。Spring框架从2.5版本开始对依赖注入的方式进行了改进,使得@Autowired成为了一个更加便捷和强大的注解。
@Resource:与@Autowired不同,@Resource注解来源于Java的JSR-250规范提案,属于包。这意味着@Resource是Java平台的一部分,而不是特定于Spring框架的。它需要JDK1.6及以上版本才能使用。由于JSR-250是一个通用的注解,因此它可以在不同的Java EE容器中使用,而不仅仅是Spring。
依赖查找顺序不同
当使用@Autowired注解进行依赖注入时,Spring会按照以下顺序进行匹配:
按类型匹配:首先根据被注入属性的类型查找容器中是否存在对应的bean。如果存在多个相同类型的bean,则继续下一步的匹配。
按名称匹配:如果存在多个相同类型的bean,Spring会根据被注入属性的名称与容器中的bean名称进行匹配。如果找到与名称匹配的bean,则将其注入到目标对象中。
抛出异常:如果没有找到匹配的bean,则会抛出NoSuchBeanDefinitionException异常。
举例说明:
假设我们有一个接口UserService
和两个实现类UserServiceImplA
和UserServiceImplB
,它们都实现了UserService
接口。同时,在Spring容器中定义了两个bean,分别名为userServiceA
和userServiceB
。
public interface UserService {
void doSomething();
}
public class UserServiceImplA implements UserService {
@Override
public void doSomething() {
("UserServiceImplA is doing something");
}
}
public class UserServiceImplB implements UserService {
@Override
public void doSomething() {
("UserServiceImplB is doing something");
}
}
在Spring配置文件中定义了这两个bean:
<bean class="" />
<bean class="" />
现在我们有一个类UserController
,其中有一个属性需要注入UserService
:
public class UserController {
@Autowired
private UserService userService;
public void execute() {
();
}
}
在这种情况下,Spring会先按类型匹配,发现有两个相同类型的bean(UserServiceImplA
和UserServiceImplB
),然后根据名称进行匹配。由于UserController
中没有指定具体的bean名称,所以Spring会选择其中一个bean进行注入。具体选择哪个bean取决于容器中bean的定义顺序。
@Qualifier
注解用于指定需要注入的 bean 的名称。当有多个相同类型的 bean 时,可以使用 @Qualifier
来指定具体需要注入的 bean。
@Resource
注解则是先根据名称进行匹配,如果未找到与名称匹配的bean,再按类型进行查找。
如果我们在UserController
中使用@Resource
注解进行依赖注入:
public class UserController {
@Resource(name = "userServiceA")
private UserService userService;
public void execute() {
();
}
}
在这种情况下,Spring会先根据名称进行匹配,找到名为userServiceA
的bean,并将其注入到UserController
中。如果找不到与名称匹配的bean,才会按类型进行匹配。
注入方式不同
@Autowired
支持构造方法注入、属性注入和Setter注入,而@Resource
仅支持属性注入和Setter注入。
构造方法注入:@Autowired
可以通过在类的构造方法上添加注解来实现依赖注入。这种方式可以在对象创建时就完成依赖的注入,使得对象在创建后即可使用,而不需要等待其他依赖注入完成。
public class MyClass {
private MyDependency myDependency;
@Autowired
public MyClass(MyDependency myDependency) {
= myDependency;
}
}
属性注入:@Autowired
和@Resource
都支持通过在类的属性上添加注解来实现依赖注入。这种方式简单直接,适用于依赖关系较为明确的情况。
@Autowired
示例代码
public class MyClass {
@Autowired
private MyDependency myDependency;
}
@Resource
示例代码:
public class MyClass {
@Resource
private MyDependency myDependency;
}
Setter注入:@Autowired
和@Resource
也都支持通过在类的setter方法上添加注解来实现依赖注入。这种方式符合JavaBean的规范,适用于需要在依赖注入前后进行一些处理的情况。
public class MyClass {
private MyDependency myDependency;
@Autowired
public void setMyDependency(MyDependency myDependency) {
= myDependency;
}
}
@Resource
示例代码:
public class MyClass {
private MyDependency myDependency;
@Resource
public void setMyDependency(MyDependency myDependency) {
= myDependency;
}
}
参数支持不同
@Autowired
和@Resource
注解在参数支持方面存在一些差异
@Autowired:@Autowired
注解来自Spring框架,它支持设置一个参数,即要注入的依赖。这意味着在使用@Autowired
时,通常不需要指定额外的参数,因为Spring会自动根据类型进行匹配,如果存在多个相同类型的bean,则会根据名称进行查找。
Resource:@Resource
注解来自于JSR-250规范,它支持设置七个参数。这些参数为@Resource
提供了更多的灵活性,允许开发者指定更详细的依赖注入规则。例如,可以通过参数指定具体的名称、类型、甚至是注入的方式(如通过名称或类型)。
name
参数:用于指定要注入的bean的名称。
public class MyClass {
@Resource(name = "myDependency")
private MyDependency myDependency;
}
type
参数:用于指定要注入的bean的类型。
public class MyClass {
@Resource(type = )
private MyDependency myDependency;
}
mappedName
参数:用于指定要注入的bean在JNDI中的名称。
authenticationType
参数:用于指定身份验证类型
shareable
参数:用于指定是否共享资源。
description
参数:用于提供对资源的简短描述。
lookup
参数:用于指定自定义的查找逻辑。
作用位置不同
@Autowired:可以是类、属性、构造方法、Setter方法和配置方法
@Resource 属性和方法
默认设计模式不同
Autowired
默认为单例(Singleton)。这意味着在使用@Autowired
进行依赖注入时,Spring容器会创建一个共享的bean实例,并将其注入到需要的地方。如果多个地方都使用了同一个bean,那么它们都将引用同一个实例。
Resource
默认为原型(Prototype)。这意味着在使用@Resource
进行依赖注入时,每次请求都会创建一个新的bean实例,并将其注入到需要的地方。这样可以避免多个地方共享同一个实例的问题。
虽然@Autowired
和@Resource
的默认值不同,但开发者可以通过设置参数来改变它们的默认设计模式。例如,可以使用@Scope
注解来指定@Autowired
或@Resource
的设计模式。