创建服务
介绍 Introduction
与"entity" sub-generator 子发生器相比,这是一个非常简单的子发生器。
它的目标是生成Spring Service bean,这是应用程序的业务逻辑应该被编码的地方。
为了生成一个“Bar”服务bean,只需键入:
jhipster service Bar
这将产生一个简单的“BarService”:很少的代码行,但他们通常会有很多问题。我们正在尝试回答下面最常见的。
为什么通过"entity" 生成器生成的不是服务类? Why aren't Service classes generated by the "entity" generator?
我们在这里有两个主要的架构原理:
- 我们不想推广创建无用服务:如果您需要的是数据库上的基本CRUD,则不需要Service Bean。这就是为什么默认情况下,JHipster不会生成它们。
- 我们相信一个Service bean比存储库更粗糙。服务bean将使用多个存储库来提供业务价值。这就是为什么不能使用实体生成服务bean。
我们应该使用我们的服务Beans的接口么? Should we use interfaces with our Service Beans?
简短的回答: No.
如果你想要很长的答案, here it is:
使用Spring的主要兴趣之一是AOP。这是允许Spring在您的Bean之上添加新行为的技术:例如,这是事务或安全性的工作原理。
为了添加这些行为,Spring需要在你的类上创建一个代理,创建代理有两种方法:
- 如果您的类使用接口,Spring将使用Java提供的标准机制来创建动态代理。
- 如果你的类不使用接口,Spring将使用CGLIB来实时生成一个新的类:这不是一个标准的Java机制,但它的工作原理与标准机制一样。
有些人认为接口对于编写测试更好,但是我们相信我们不应该为了测试而修改生产代码,, Some people will also argue that interfaces are better for writing tests, but we believe we shouldn't modify our production code for tests, 而且所有新的 mocking 框架 (like EasyMock) 都允许您在没有任何接口的情况下创建非常好的单元测试。
所以,最后我们发现你的服务bean的接口大都是没用的,这就是为什么我们不推荐它们(但我们让你选择生成它们!)。
为什么要使用事物来延迟加载JPA的关系? Why should I use transactions to fetch lazy JPA relationships?
默认情况下JPA会延迟加载具有一对多或多对多关系的实体。如果您使用此默认配置,您可能会看到可怕的 LazyInitializationException
: 这意味着您尝试在事务之外使用未初始化的关系。
由于生成的Service类默认使用 @Transactional
注解, 所有的方法都是事务性的。这意味着您可以在这些业务方法中使用延迟加载而不用担LazyInitializationException
.
提示: 如果你不需要修改任何数据就可以在方法上使用@Transactional(readOnly = true)
。 这是一个不错的性能优化(Hibernate不需要刷新其第一级缓存,因为我们不修改任何东西),以及一些JDBC驱动程序的质量增强(Oracle不会允许您发送INSERT / UPDATE / DELETE语句)
Can we add security to Service Beans?
Yes! Just add Spring Security's @Secured
annotation on your class or on your methods, 并使用提供的AuthoritiesConstants类限制对特定用户权限的访问。
我们可以监视服务Bean吗? Can we monitor Service Beans?
Yes! Just add Metrics' @Timed
annotations on the methods you want to monitor.