为什么Controller注入的是Service,而不是ServiceImpl(实现类)?

shaft_V 2017-04-24 04:23:54
能否去掉service层?controller直接注入ServiceImpl? 今天看到直接注入Service实现类的,不理解,感觉有些别扭。恳请坛友们讲解下原因。。谢谢!
...全文
10213 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
viaco2love 2019-04-29
  • 打赏
  • 举报
回复 2
这种写法就是想换成不同的serviceImpl,意思就是只画了个虎头,身体没画。虎身自己慢慢画。
shaft_V 2019-03-03
  • 打赏
  • 举报
回复 2
引用 22 楼 zk_1325572803 的回复:
解耦,测试方便,面向接口编程,代理方式不同(@autowired的对象是通过接口的话会使用jdk动态代理,jdk动态代理只能对实现接口的类生成代理,而不能针对类)
谢谢坛友回答帮助。
好名全被用 2019-03-02
  • 打赏
  • 举报
回复 1
解耦,测试方便,面向接口编程,代理方式不同(@autowired的对象是通过接口的话会使用jdk动态代理,jdk动态代理只能对实现接口的类生成代理,而不能针对类)
rain_sound 2018-09-06
  • 打赏
  • 举报
回复
最好注入service接口类,不然用maven管理会报错
折翼仍飛 2018-08-17
  • 打赏
  • 举报
回复
spring的jdk代理是基于接口的,事务需要用到aop,aop需要代理类,好像是这样
qq_40859262 2018-05-05
  • 打赏
  • 举报
回复
@Service @Transactional(readOnly = true) public class BizResDoctorService extends CrudService<BizResDoctorDao, BizResDoctor> { public BizResDoctor get(String id) { return super.get(id); } } @Controller @RequestMapping(value = "${adminPath}/doctor/bizResDoctor") public class DoctorController extends BaseController { @Autowired private BizResDoctorService bizResDoctorService; } 不要质疑代码的正确性,不能跑我会来百度? 楼主提过疑问了,为什么在controller中直接调用继承service接口的serviceimpl不行,可是在我这里确实是可以,我这里的service其实是相当于你们口中的serviceimpl 注:CrudService是基类 求大牛给出解释,谢谢
DawsonSYD 2017-08-20
  • 打赏
  • 举报
回复
为了让程序可扩展。
xiejin90314 2017-04-26
  • 打赏
  • 举报
回复
也可以注入接口 也可以注入实现类。切面不一样 用的jar也不一样
Java-moon 2017-04-26
  • 打赏
  • 举报
回复
引用 15 楼 shaft_V 的回复:
[quote=引用 14 楼 GetIndex 的回复:] [quote=引用 10 楼 shaft_V 的回复:] [quote=引用 9 楼 GetIndex 的回复:]
http://blog.csdn.net/lllliulin/article/details/52032670[/quote] 谢谢。 我现在可能懂了。 controller --service--serviceImpl--dao 模式下,controller内 注入service接口(@Resource),serviceImpl实现类上添加注解@Service(不含参数),实现类内部注入dao接口(@Resource), 因为上面提到的接口接收实现类,因为唯一,所以调用的是ServiceImpl 里对应的方法。 class HumanContrller{ @Resource private HumanService humanService; } interface HumanService{} @Service class HumanServiceImpl implements HumanService{ @Resource private HumanDao humandao } 这种注解@Resource和@Service内不含参数的情况下,也是能正常运行的。我不太懂的是:注解并没有参数,它是怎么从Humanservice找到HumanServieImpl,难道是因为实现humanService接口的只有HumanServiceImpl一个,所以就注入它了? controller --serviceImpl--dao 模式下, 去掉了service层。controller内注入serviceImpl类(@Resource), serviceImpl实现类依旧添上@Service(不含参数),内部注入dao接口(@Resource), 这个时候也能正常运行。 因为这次也都没有参数,也指定的类型唯一,HumanServiceImpl只有一个。[/quote] @Autowired默认是按类型匹配的方式,在容器查找匹配的bean,当且仅有一个匹配的bean时,Spring将其注入到@Autowired所标注的变量中。如果容器中有一个以上匹配的bean时,则可以通过@Qualifier注解限定bean的名称
棒棒不是糖_ 2017-04-25
  • 打赏
  • 举报
回复
引用 12 楼 shaft_V 的回复:
[quote=引用 11 楼 lqs365 的回复:] [quote=引用 5 楼 shaft_V 的回复:] [quote=引用 3 楼 lqs365 的回复:] 注入的是Imp对象,接收的类型为接口。
原来如此,谢谢。 请问,如果该Service有多个实现类,它怎么知道该注入哪个ServiceImpl类?[/quote] 每个service的imp都可以指定名称(使用@service(“名称”)),然后注入的时候也可以使用名称来指定注入哪一个。 用@qualifier(“名称”)这个来指定使用哪一个。[/quote] 谢谢。 如果直接使用@Service, 帖子10楼的情况下会怎么样?[/quote] 运行一下,应该是会报错的。 一般在实际开发中,@service都会指定名称,注入的时候使用@autowire,然后用@qualifier来指定使用哪个。 http://blog.csdn.net/clerk0324/article/details/25198457
shaft_V 2017-04-25
  • 打赏
  • 举报
回复
引用 11 楼 lqs365 的回复:
[quote=引用 5 楼 shaft_V 的回复:] [quote=引用 3 楼 lqs365 的回复:] 注入的是Imp对象,接收的类型为接口。
原来如此,谢谢。 请问,如果该Service有多个实现类,它怎么知道该注入哪个ServiceImpl类?[/quote] 每个service的imp都可以指定名称(使用@service(“名称”)),然后注入的时候也可以使用名称来指定注入哪一个。 用@qualifier(“名称”)这个来指定使用哪一个。[/quote] 谢谢。 如果直接使用@Service, 帖子10楼的情况下会怎么样?
棒棒不是糖_ 2017-04-25
  • 打赏
  • 举报
回复
引用 5 楼 shaft_V 的回复:
[quote=引用 3 楼 lqs365 的回复:] 注入的是Imp对象,接收的类型为接口。
原来如此,谢谢。 请问,如果该Service有多个实现类,它怎么知道该注入哪个ServiceImpl类?[/quote] 每个service的imp都可以指定名称(使用@service(“名称”)),然后注入的时候也可以使用名称来指定注入哪一个。 用@qualifier(“名称”)这个来指定使用哪一个。
shaft_V 2017-04-25
  • 打赏
  • 举报
回复
引用 9 楼 GetIndex 的回复:
谢谢! 是,这样就在controller里注入可 接口/接口实现类(人/医生)? 在controller调用xxxService.add()方法时,它怎么知道是实现了service接口的哪个类,比如实现该service的可能有多个类。 接口 interface HumanService{} 接口实现类 @Service class TeacherServiceImpl imeplements HumanService{} @Service class DoctorServiceImpl imeplements HumanService{} 控制器 @Controller class WorldController{ @Resource private HumanService humanService; } 这样的情况下会怎么样,humanService接口的是哪个实现类?
shaft_V 2017-04-25
  • 打赏
  • 举报
回复
引用 14 楼 GetIndex 的回复:
[quote=引用 10 楼 shaft_V 的回复:] [quote=引用 9 楼 GetIndex 的回复:]
http://blog.csdn.net/lllliulin/article/details/52032670[/quote] 谢谢。 我现在可能懂了。 controller --service--serviceImpl--dao 模式下,controller内 注入service接口(@Resource),serviceImpl实现类上添加注解@Service(不含参数),实现类内部注入dao接口(@Resource), 因为上面提到的接口接收实现类,因为唯一,所以调用的是ServiceImpl 里对应的方法。 class HumanContrller{ @Resource private HumanService humanService; } interface HumanService{} @Service class HumanServiceImpl implements HumanService{ @Resource private HumanDao humandao } 这种注解@Resource和@Service内不含参数的情况下,也是能正常运行的。我不太懂的是:注解并没有参数,它是怎么从Humanservice找到HumanServieImpl,难道是因为实现humanService接口的只有HumanServiceImpl一个,所以就注入它了? controller --serviceImpl--dao 模式下, 去掉了service层。controller内注入serviceImpl类(@Resource), serviceImpl实现类依旧添上@Service(不含参数),内部注入dao接口(@Resource), 这个时候也能正常运行。 因为这次也都没有参数,也指定的类型唯一,HumanServiceImpl只有一个。
GetIndex 2017-04-25
  • 打赏
  • 举报
回复
引用 10 楼 shaft_V 的回复:
[quote=引用 9 楼 GetIndex 的回复:]
谢谢! 是,这样就在controller里注入可 接口/接口实现类(人/医生)? 在controller调用xxxService.add()方法时,它怎么知道是实现了service接口的哪个类,比如实现该service的可能有多个类。 接口 interface HumanService{} 接口实现类 @Service class TeacherServiceImpl imeplements HumanService{} @Service class DoctorServiceImpl imeplements HumanService{} 控制器 @Controller class WorldController{ @Resource private HumanService humanService; } 这样的情况下会怎么样,humanService接口的是哪个实现类? [/quote] 第一、@Service() 里面必须带有标识符 例如@Service("humanService") 第二、当注入的时候会首先默认名称一样的 也就是你注入的时候 HumanService 的时候回去找 @Service("humanService") 第三、不能出现两个@Service("humanService"),也就是@Service中的值不能重复,重复则报错 http://blog.csdn.net/lllliulin/article/details/52032670
GetIndex 2017-04-24
  • 打赏
  • 举报
回复
引用 4 楼 shaft_V 的回复:
[quote=引用 1 楼 GetIndex 的回复:] 本来就是注入的 实现类 ,只不过拿接口来接收的
有道理,谢谢。 请问,如果该Service有多个实现类,它怎么知道该注入哪个ServiceImpl类?[/quote] 你看哈,Spring 默认按照名字来注入的,比如 @Service("userService") class UserService 引用的时候 @Resource private UserService; 默认注入类名小写的(约定大于配置)也就是userService 如果多个的话 。可以用 @Service("userService1") @Resource(name="userService1") 来对应获取
月明星稀灬 2017-04-24
  • 打赏
  • 举报
回复
用接口做代理
Scaarf 2017-04-24
  • 打赏
  • 举报
回复
多态啊,我。。。我。我是这么理解的。。。。
shaft_V 2017-04-24
  • 打赏
  • 举报
回复
引用 2 楼 x324235r325 的回复:
面向接口编程
谢谢。
shaft_V 2017-04-24
  • 打赏
  • 举报
回复
引用 3 楼 lqs365 的回复:
注入的是Imp对象,接收的类型为接口。
原来如此,谢谢。 请问,如果该Service有多个实现类,它怎么知道该注入哪个ServiceImpl类?
加载更多回复(4)
Spring-generator 是基于 javafx8 开发的图形界面 Spring 代码生成器,使用 Apache FreeMarker 作为代码文件的模板,用户可以一键将数据库中的表生成为任意风格的 .java 代码文件(比如经典的三层模型)。 Spring-generator 不是框架,它不会影响现有的任何机构,它只是一个解决你重复做某些事情的工具,它也不拘束与某个语言,它的使命就是将数据库表结构取出来,剩下的就取决于你怎么使用 FreeMarker 编写模板生成你想要的文件。 工具支持所有实现 JDBC 规范的数据库;默认集成了Oracle、SqlServer、MySQL、PostgreSql 数据库驱动 jar 包,其他数据库可以自己添加依赖。 工具默认集成了以 MyBatis 作为持久化层的模板,如果需要 JPA 相关等模板可以自己参考工具的文档进行编写。 特色功能预览 生成实体 生成 WEB API相关接口 Controller 生成业务逻辑相关的 Service/ServiceImpl 生成操作数据库的 Dao 接口与 Mapper.xml 映射文件 生成单元测试等 软件最大的特色就是操作 SQL 的 Assist 查询帮助(Assist 是特别定制的查询工具,使用该工具一切操作都会变得超简单,比如:分页通过 Assist 只需要设置2个参数就可以实现,比如参数1=10,参数2=5,查询出来就是第10行到15行的数据,同时也可以防注入动态添加查询添加,去重,排序,自定义返回列等); 生成的实体(可以自己修改模板按自己的风格生成): Dao 接口: Mapper.xml 文件:

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧