1、在开发中,为了解耦和规范我们通常先制定一套接口,然后再去写实现类,如果实现类的代码发生变化,没有必要去改变接口层面的代码,可以做到解耦。有时候一个通用接口则可能有不同的功能实现,我们在引用接口的时候应该如何去选择特定的实现类呢?
比如一个简单接口如下:
public interface UserService {
String getUserName();
}
该接口有两个实现类
// 实现类1
@Service(value = "defaultUserService")
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public String getUserName() {
return "default Name";
}
}
// 实现类2
@Service(value = "englishUserService")
public class EnglishUserServiceImpl implements UserService {
@Override
public String getUserName() {
return "English UserName";
}
}
在controller层该如何通过接口调用具体的实现类呢?实际上借助springboot 中@Autowired 注解和@Qualifier(value="xxx")注解组合指定注入的具体类名称即可,可以看到通过@Qualifier(value=“xxx”)注解可以人为指定注入的接口实现类
@Autowired
@Qualifier(value = "defaultUserService")
private UserService userService1;
@Autowired
@Qualifier(value = "englishUserService")
private UserService userService2;
另外也可以使用@Resource(name="xxx")注解指定注入的特定实现类
// @Autowired
// @Qualifier(value = "defaultUserService")
@Resource(name = "defaultUserService")
private UserService userService1;
// @Autowired
// @Qualifier(value = "englishUserService")
@Resource(name = "englishUserService")
private UserService userService2;
最后使用@Autowired 时,属性名称使用实现类中交由spring container管理的bean名称,也可实现相同的功能。
@Autowired
// @Qualifier(value = "defaultUserService")
// @Resource(name = "defaultUserService")
private UserService defaultUserService;
@Autowired
// @Qualifier(value = "englishUserService")
// @Resource(name = "englishUserService")
private UserService englishUserService;
scope作用域注解
另外@Scope注解可以指定bean的作用域,默认是singleton,即是单例的,整个spring容器中该bean就一个实例,另外也可切换为prototype 多实例,每次从spring IOC容器中取出的都是不同的实例
所有的作用域包括: singleton、prototype、request、session、global session
@Scope(value = "prototype")
public class UserServiceImpl implements UserService {
测试代码如下:
@RequestMapping(value = "/beanScope", method = RequestMethod.GET)
public String beanScope() {
UserServiceImpl bean1 = SpringBeanContext.getBean(UserServiceImpl.class);
System.out.println("bean1的hashcode: "+bean1.hashCode());
UserServiceImpl bean2 = SpringBeanContext.getBean(UserServiceImpl.class);
System.out.println("bean2的hashcode: "+bean2.hashCode());
return "ok";
}
结果: 当使用prototype 时输出如下:两个实例的hashcode是不同的:
bean1的hashcode: 1043281337
bean2的hashcode: 2066594840
当使用默认的singleton时,两个实例的hashcode是相同的:
bean1的hashcode: 1812452140
bean2的hashcode: 1812452140
欢迎关注博主公众号,后台回复 207 可领取2021最新Java全栈视频教程