在Spring框架中,`@Resource`和`@Autowired`是两个常用的注解,用于实现依赖注入。尽管它们的功能相似,但它们之间有一些关键的区别。
Spring 提供了以下多个注解,这些注解可以直接标注在 Java 类上,将它们定义成 Spring Bean。
注解 | 说明 |
---|---|
@Component | 该注解用于描述 Spring 中的 Bean,它是一个泛化的概念,仅仅表示容器中的一个组件(Bean),并且可以作用在应用的任何层次,例如 Service 层、Dao 层等。 使用时只需将该注解标注在相应类上即可。 |
@Repository | 该注解用于将数据访问层(Dao 层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。 |
@Service | 该注解通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。 |
@Controller | 该注解通常作用在控制层(如SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。 |
我们对这些Bean的注入一般用`@Resource`和`@Autowired`进行注入
来源
- @Resource:这个注解是Java扩展包的一部分,遵循JSR-250规范。这使得它成为一个标准注解,具有更广泛的适用性。
- @Autowired:这个注解是Spring框架自带的,专门用于Spring框架的上下文中。
默认注入方式
- @Resource:默认情况下,`@Resource`通过名称(byName)进行注入。如果没有指定名称,它会使用属性名作为Bean的名称。如果通过名称找不到对应的Bean,它会回退到通过类型(byType)进行注入。
- @Autowired:默认情况下,`@Autowired`通过类型(byType)进行注入。如果需要通过名称进行注入,需要与`@Qualifier`注解一起使用。
使用范围
@Resource:可以用在属性和setter方法上。
@Autowired:可以用在属性、setter方法、构造方法和构造方法参数上。
依赖引入
- 对于JDK 8,不需要额外引入依赖。
- 对于JDK 11或低于JDK 8,需要引入`jakarta.annotation-api`依赖。
示例场景
场景一:根据名称注入
代码语言:java复制@Repository("myUserDao")
public class UserDaoImpl implements UserDao {
// ...
}
@Service
public class UserServiceImpl implements UserService {
@Resource(name = "myUserDao")
private UserDao myUserDao;
// ...
}
在这个场景中,我们通过指定名称`myUserDao`来进行注入。
场景二:未指定名称的注入
代码语言:java复制@Service
public class UserServiceImpl implements UserService {
@Resource
private UserDao myUserDao;
// ...
}
当`@Resource`注解没有指定名称时,它会使用属性名`myUserDao`作为Bean的名称进行注入。
场景三:其他情况
代码语言:java复制@Service
public class UserServiceImpl implements UserService {
@Resource
private UserDao userDao1;
// ...
}
如果没有指定名称,并且根据属性名`userDao1`找不到对应的Bean,`@Resource`会尝试通过类型进行注入。如果存在多个相同类型的Bean,这可能会导致异常。
总结
@Resource注解默认先尝试通过名称进行注入,如果找不到对应的名称,则通过类型进行注入。但是,当通过类型注入时,要求该类型的Bean在容器中必须是唯一的。`@Autowired`注解则默认通过类型进行注入,如果需要通过名称注入,则需要与@Qualifier注解配合使用。了解这些区别,可以帮助我们更准确地选择合适的注解来实现依赖注入。