1.普通service的开发
新建一个service
弹出的输入框中可以输入包名+类名,注意IDE会自动给类名后边加上Service,例如:输入com.xx.Abc,生成的service命名就是com.xx.AbcService。也可以输入Domain的类命名(可用Alt + /提示),生成的类名为domain的类名加service
生成两个文件,一个是测试类,一个是服务类。
在生成的测试类里写些测试代码
@TestFor(TestService)
class TestServiceTests {
void testSomething() {
assert 1==service.serviceMethod(null)
}
}
这里需要注意的是,由于TestFor的annotation的缘故,内置的service变量被自动注入了TestService的实例。不需要手工实例化TestService了。(为啥生成的服务方法叫serviceMethod,生成的测试方法不叫testServiceMethod捏?)
实现一下serviceMethod
class TestService { def serviceMethod(String input) { log.info('I\'m service') return 1 } }
这里的log是commons-log的log,已经被自动注入,不需要显示声明。
修改一下Config.groovy里的log4j配置
log4j = {
// Example of changing the log pattern for the default console
// appender:
//
appenders {
console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n')
}
info 'grails.app.services'
error 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails.web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
'org.springframework',
'org.hibernate',
'net.sf.ehcache.hibernate'
root{
warn 'stdout'
}
}
root的配置是不想后台输出太多日志,这里主要配置文中标红的那句。注意的是grails.app.services是默认的,这样配才能控制service的日志输出,而不是写的包名。
运行一下测试
test-app是运行整个程序的测试,可以使用test-app 类全名,来指定运行单个测试类。这里不详细说了。
运行后会打很多日志,其中一行就是
test.TestService I'm service
2.service之间的依赖和spring的ioc
grails默认加入了spring的Ioc,使我们可以轻松的使用。
依照1的方法再建一个service。测试代码忽略。
实现代码如下:
class AnotherService { def serviceMethod() { log.info("I'm from another Service") } }
很简单
在原service上加上引用
class TestService { def anotherService def serviceMethod(String input) { anotherService.serviceMethod() log.info('I\'m service') return 1 } }
在service的test里使用spring ioc需要做点工作,测试代码如下:
@TestFor(TestService) class TestServiceTests { void testSomething() { defineBeans { anotherService(AnotherService) } assert 1==service.serviceMethod(null) } }
defineBeans也是内置的,不需要引用。
跑一下test-app,结果:
test.AnotherService I'm from another Service
test.TestService I'm service
3.引用JAVA service
原有的遗留程序,或者某些groovy无法做的工作可以将由java完成。既然groovy和java是亲戚,那就应该能无缝调用。
在src/java里建一个java类,代码如下:
public class JavaTestService {
Logger log = Logger.getLogger(JavaTestService.class);
public void javaTestMethod(){
log.info("I'm from java");
}
}
这里Log用的是log4j
修改一下测试代码:
@TestFor(TestService) class TestServiceTests { void testSomething() { defineBeans { anotherService(AnotherService) javaTestService(test.JavaTestService) } assert 1==service.serviceMethod(null) } }
修改一下TestService
class TestService { def anotherService def javaTestService def serviceMethod(String input) { anotherService.serviceMethod() javaTestService.javaTestMethod() log.info('I\'m service') return 1 } }
这里两个引用都使用了def定义,不指定类型,当然也可以使用类型声明,不过这样会在调试web的时候产生一点问题,而且写def的话可以不依赖于相关类。另外,当然也可以让java的类实现一个接口来实现注入。spring ioc这里是按名称注入的,不支持类型注入。
log4j的配置中也需要改一下:
info 'grails.app.services','test'
因为java的service并非grails的service,grails.app.services无法控制他,所以把java类的包名加上。
跑一下测试,结果:
test.AnotherService I'm from another Service
test.JavaTestService I'm from java
test.TestService I'm service