class CountryService {
static transactional = true
}
import org.springframework.transaction.annotation.*
class BookService {
@Transactional(readOnly = true)
def listBooks() { Book.list() }
@Transactional
def updateBook() { }
}
class BookController {
def bookService //对应BookService
…
}
package bookstore;
public class BookConsumer {
private BookStore store;
public void setBookStore(BookStore storeInstance) {
this.store = storeInstance;
}
…
}
<bean id="bookConsumer" class="bookstore.BookConsumer">
<property name="bookStore" ref="bookService" />
</bean>
Grails 1.2参考文档速读(16):服务层
最新推荐文章于 2025-08-10 11:14:23 发布
服务层的作用就是封装复杂业务逻辑,尤其是这种逻辑涉及到多个Domain Class的时候。
我们在前面的文章中已经看到,实际上在 Controller中就可以畅通无阻的使用Domain Class,那为什么还要搞出来一个单独的服务层呢?原因很简单,职责清晰。从架构上讲,Controller仍属于Web层的范畴,它的主要作用还是为了View的显示做好准备工作,或是针对请求准备好响应的数据。而业务逻辑则属于业务层的内容,两者混在一起,不仅让Controller变得复杂,而且也为测试造成了麻烦。基于这种原因,一般建议:不要在Controller中包含核心业务逻辑,凡是涉及多个Domain Class的操作,就封装成Service,由Controller调用。
服务的创建非常简单,使用命令:grails create-service,即可。和其他的Grails组件一样,服务也有自己的存放位置:grails-app/services。当然,服务本身也同样是普通的Groovy类。
服务要和多个Domain Class打交道,这当然就离不开事务了。关于编程性事务的内容,我们已经在GORM部分讲过,在此就不再啰嗦。现在来看看声明性事务是如何定义的,这也很简单,只要在服务类中写上:static transactional = true就行了:
特点:
Grails也完全支持Spring的事务注解:
在使用事务注解时,无需任何配置,只需使用即可,Grails会负责把这些东西自动串起来。
用过Spring的读者应该对Spring 的scope不会陌生,它决定了bean的创建方式和生命周期,跟并发性不无联系。一般状况,服务是Singleton,scope的值包括:
改变缺省的Scope(在服务定义中)增加:static scope = "以上之一"。
至于 DI,Grails遵守的约定适用于Controller、Service、Domain Class、Command Object、Tag等:
需要注意:
除了一般的Groovy类,我们同样可以在Java类中使用服务:
不论以上哪种方式,在Java端: