一个用户服务接口
public interface UserService{
void add(User user){}
}
有老师和学生的两个具体服务
@Service //注入服务
public class StudentService implements UserService{
public void add(User user){
}
}
@Service //注入服务
public class TeacherService implements UserService{
public void add(User user){
}
}
老鸟:如果只定义如上代码,启动spring服务,是否会报错?
菜鸟:不会,那为什么?
老鸟:默认spring以实现类的类名首字母小写注入服务,即不同的实现类有不同的类名,故不会冲突,不报错。
那在对应的StudentController和TeacherController如何使用基于UserService接口,注入具体的实现?
@Controller
@RequestMapping("teachers")
public class TeacherController{
@Autowired //此处这样引用会不会报错?
private UserService userService
@PostMapping()
@ResponseBody
public ResultResponse add(Teacher teacher){
}
}
上面的通过@Autowired来引用服务会不会报错?
菜鸟:不会?会
老鸟:会报错,因为现在UserService接口有两个实现类,要指定具体的实现,那如何实现?你有几种方式解决?(ps:只能以接口方式来引用,不能注入实现类)
<p>@Resource(name = "studentService")</p>
private UserService userService;
<h4>引用来自“学而不思则罔”的评论</h4>
public interface UserService {
void addUser(String userName);
}
@Service("studentService")
public class StudentServiceImpl implements UserService {
@Override
public void addUser(String userName) {
System.out.println("StudentServiceImpl-->" + userName);
}
}
@Service("teacherService")
public class TeacherServiceImpl implements UserService {
@Override
public void addUser(String userName) {
System.out.println("TeacherServiceImpl-->" + userName);
}
}
public class UserServiceTest extends BaseSprintTestCase {
@Autowired
private UserService studentService;
@Autowired
private UserService teacherService;
@Test
public void testAddUser() {
System.out.println("================测试注入start==============");
studentService.addUser("学生");
teacherService.addUser("老师");
System.out.println("================测试注入end==============");
}
}
工作这么多年,我一直习惯这么用写。
注入的变量名就用studentService或teacherService还是接口方式注入。
ps:楼主说会报错,我编辑了下,把自己的源码和测试类都贴上来了,另外附上测试结果:
回复 <a class="referer" target="_blank">@学而不思则罔</a> : 好吧,现在做得更智能了? Autowired不是按类型来注入,很能自动根据变量名来。
回复 <a class="referer" target="_blank">@rabbitgg</a> : 一直在用,你再看看吧,我把我的代码和测试类都放上来了,还有测试截图。
你可以试试,会报错
回复 <a class="referer" target="_blank">@rabbitgg</a> :
不是告诉你了吗? @Autowired //此处这样引用会不会报错? private UserService studentService;
@Autowired private UserService teacherService;
我要的是怎么引用?
<p>使用泛型就好了</p>
泛型,怎么做?
使用qualifer指定
这是其中的一个解决方案,还能想到更多?
qualifier
<pre><code>@Controller
@RequestMapping("teachers") public class TeacherController{ @Autowired //扩展经常使用,可以注入任意多个 private Map<String,UserService> userServices;
@PostMapping() @ResponseBody public ResultResponse add(Teacher teacher){ UserService userService = chooseUserService(teacher); //userService业务逻辑 } /*选择合适的接口实现类/ private UserService chooseUserService(Teacher teacher)){ String id = xxxx(teacher); return userServices.get(id);
}
}
<p>UserService<StudentService> userService这样</p>
这样能做?
<p>使用@Qualifier注解可以解决这个问题。</p>
首先在两个实现上定义不同的beanid:
@Service("studentService") //定义beanid为studentService
public class StudentService implements UserService{
public void add(User user){
}
}
@Service("teacherService") //定义beanid为teacherService
public class TeacherService implements UserService{
public void add(User user){
}
}
注入的时候通过@Qualifier("beanid")指定其中一个:
@Controller
@RequestMapping("teachers")
public class TeacherController{
@Autowired
@Qualifier("teacherService") //通过beanid指定注入的服务
private UserService userService
@PostMapping()
@ResponseBody
public ResultResponse add(Teacher teacher){
}
}
<p>可以使用@Resource注解啊</p>
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。