前言:
@Autowired 和 @Resource 来自不同的“父类”,其中 @Autowired 是 Spring 定义的注解,而 @Resource 是 Java 定义的注解,它来自于 JSR-250(Java 250 规范提案)。当它们的实现类只有一个时,那么用法没有任何区别,但是如果有多个时,就需要额外处理了。
复现:
当存在多个实现类时,不做额外处理程序会报错无法运行。
@Autowired
在编译时就报错了,无法编译通过@Resource
在运行启动时报错,找不到加载哪一个实现类
目录结构:
- controller
- BaseController.java
- service
- BaseService.java
- impl
- MyServiceImpl.java
- YourServiceImpl.java
代码:
BaseContoller.java
package com.suhuamo.controller;
import com.suhuamo.service.BaseService;
import com.suhuamo.service.impl.MyServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
/**
* @author suhuamo
* @date 2023-06-21
* @slogan 也许散落在浩瀚宇宙的小行星们也知道
*/
@Controller
public class BaseController {
@Autowired
// @Qualifier(value = "myServiceImpl")
// @Resource
BaseService baseService;
public void saiHi() {
baseService.sayHi();
}
}
BaseService.java
package com.suhuamo.service;
/**
* @author suhuamo
* @date 2023-06-21
* @slogan 也许散落在浩瀚宇宙的小行星们也知道
*/
public interface BaseService {
/**
* 说hi
* @param
* @return void
*/
void sayHi();
}
MyServiceImpl.java
package com.suhuamo.service.impl;
import com.suhuamo.service.BaseService;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
/**
* @author suhuamo
* @date 2023-06-21
* @slogan 也许散落在浩瀚宇宙的小行星们也知道
*/
@Service
public class MyServiceImpl implements BaseService {
@Override
public void sayHi() {
System.out.println("MyServiceImpl say Hi");
}
}
YourServiceImpl.java
package com.suhuamo.service.impl;
import com.suhuamo.service.BaseService;
import org.springframework.stereotype.Service;
/**
* @author suhuamo
* @date 2023-06-21
* @slogan 也许散落在浩瀚宇宙的小行星们也知道
*/
@Service
public class YourServiceImpl implements BaseService {
@Override
public void sayHi() {
System.out.println("YourServiceImpl say Hi");
}
}
@Autowired
在只有一个实现类时,直接使用@Autowired 即可
有多个实现类时,需要做额外处理(如本文示例),有以下三种方法,优先级高到低。
再额外加一个注解@Qualifier(value = “myServiceImpl”),来表明需要注入的实现类, myServiceImpl 是对应实现类的类名首字母小写。即注入的MyServiceImpl类
@Autowired
@Qualifier(value = "myServiceImpl")
BaseService baseService;
在实现类上加上@Primary注解,来表明该实现类在自动注入时的为默认注入类。遇上@Qualifier则不生效(即@Qualifier优先级最高)。即注入的MyServiceImpl类
@Primary
@Service
public class MyServiceImpl implements BaseService {
@Override
public void sayHi() {
System.out.println("MyServiceImpl say Hi");
}
}
在自动注入定义变量时名称设置为实现类的类名,首字母小写。即注入的MyServiceImpl类
@Autowired
BaseService myServiceImpl;
@Resource
在只有一个实现类时,直接使用@Resource即可
有多个实现类时,需要做额外处理(如本文示例),有以下两种方法,优先级高到低。
在@Resource注解中加上name参数或者type参数,指定需要注入的实现类,可以两个都写,也可以只写一个。(都写时要注意是对应的同一个实现类,否则会报错)。即注入的YourServiceImpl类
@Resource(name = "yourServiceImpl", type = YourServiceImpl.class)
// @Resource(name = "yourServiceImpl")
// @Resource(type = YourServiceImpl.class)
BaseService baseService;
在自动注入定义变量时名称设置为实现类的类名,首字母小写。即注入的YourServiceImpl类
@Resource
BaseService yourServiceImpl;
提示:
- 在IDEA中,使用@Autowired会爆红,使用@Resource则不会。
- 因为@Resource是JAVA自带的,无论你使用什么框架都可以用,所以不用担心会报错,但是@Autowired只能在Spring框架中使用,如果你写的代码不是SPring的框架,那么就不能使用@Autowired,所以IDEA检测到@Autowired会出现爆红,但是@Resource不会。