2 * Copyright 2004-2005 the original author or authors.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org
.codehaus
.groovy
.grails
.plugins
.services
18 import org
.codehaus
.groovy
.grails
.plugins
.support
.GrailsPluginUtils
19 import org
.springframework
.beans
.factory
.config
.MethodInvokingFactoryBean
20 import org
.springframework
.aop
.framework
.ProxyFactoryBean
21 import org
.springframework
.aop
.target
.HotSwappableTargetSource
22 import org
.springframework
.transaction
.interceptor
.TransactionProxyFactoryBean
23 import org
.codehaus
.groovy
.grails
.commons
.ServiceArtefactHandler
26 * A plug-in that configures services in the spring context
28 * @author Graeme Rocher
31 class ServicesGrailsPlugin
{
33 def version
= grails
.util
.GrailsUtil
.getGrailsVersion()
34 def loadAfter
= ['hibernate']
36 def watchedResources
= ["file:./grails-app/services/**/*Service.groovy",
37 "file:./plugins/*/grails-app/services/**/*Service.groovy"]
41 application
.serviceClasses
.each
{ serviceClass
->
42 def scope
= serviceClass
.getPropertyValue("scope")
44 "${serviceClass.fullName}ServiceClass"(MethodInvokingFactoryBean
) {
45 targetObject
= ref("grailsApplication", true)
46 targetMethod
= "getArtefact"
47 arguments
= [ServiceArtefactHandler
.TYPE
, serviceClass
.fullName
]
50 def hasDataSource
= (application
.config?
.dataSource
|| application
.domainClasses
.size() > 0)
51 if(serviceClass
.transactional
&& hasDataSource
) {
52 def props
= new Properties()
53 props
."*"="PROPAGATION_REQUIRED"
54 "${serviceClass.propertyName}"(TransactionProxyFactoryBean
) { bean
->
55 if(scope
) bean
.scope
= scope
56 target
= { innerBean
->
57 innerBean
.factoryBean
= "${serviceClass.fullName}ServiceClass"
58 innerBean
.factoryMethod
= "newInstance"
59 innerBean
.autowire
= "byName"
60 if(scope
) innerBean
.scope
= scope
62 proxyTargetClass
= true
63 transactionAttributes
= props
64 transactionManager
= ref("transactionManager")
68 "${serviceClass.propertyName}"(serviceClass
.getClazz()) { bean
->
79 def onChange
= { event
->
81 def serviceClass
= application
.addArtefact(ServiceArtefactHandler
.TYPE
, event
.source
)
82 def serviceName
= "${serviceClass.propertyName}"
83 def scope
= serviceClass
.getPropertyValue("scope")
86 if(serviceClass
.transactional
&& event
.ctx
.containsBean("transactionManager")) {
88 "${serviceClass.fullName}ServiceClass"(MethodInvokingFactoryBean
) {
89 targetObject
= ref("grailsApplication", true)
90 targetMethod
= "getArtefact"
91 arguments
= [ServiceArtefactHandler
.TYPE
, serviceClass
.fullName
]
93 def props
= new Properties()
94 props
."*"="PROPAGATION_REQUIRED"
95 "${serviceName}"(TransactionProxyFactoryBean
) { bean
->
96 if(scope
) bean
.scope
= scope
97 target
= { innerBean
->
98 innerBean
.factoryBean
= "${serviceClass.fullName}ServiceClass"
99 innerBean
.factoryMethod
= "newInstance"
100 innerBean
.autowire
= "byName"
101 if(scope
) innerBean
.scope
= scope
103 proxyTargetClass
= true
104 transactionAttributes
= props
105 transactionManager
= ref("transactionManager")
109 beans
.registerBeans(event
.ctx
)
115 "$serviceName"(serviceClass
.getClazz()) { bean
->
122 beans
.registerBeans(event
.ctx
)