springSecurityService in resources.groovy grails file? - grails

I'm having trouble accessing springSecurityService from resources.groovy file, I'm trying to load user locale setting and create LocaleResolver
import User
beans = {
localeResolver(org.springframework.web.servlet.i18n.SessionLocaleResolver) {
def user = User.get(springSecurityService.principal.id)
if (user?.settings?.locale) {
defaultLocale = new Locale(user?.settings?.locale)
java.util.Locale.setDefault(defaultLocale)
}
}
}
Thanks,
Mika

Your code above doesn't make a lot of sense. In resources.groovy you're supposed to define the implementation class of Spring beans and set their dependencies. It looks like you're trying to actually write the implementation class in resources.groovy.
Instead you should write your own LocaleResolver class
package org.example
class MyLocaleResolver extends AbstractLocaleResolver {
def springSecurityService
// implementation of methods omitted, because I haven't clue how you want to resolve Locales
}
Then in resources.groovy, define a bean of this type that replaces the default localeResolver bean
beans = {
localeResolver(org.example.MyLocaleResolver) {
springSecurityService = ref('springSecurityService')
}
}

Related

Accessing Grails services from src/groovy

Grails services are abstractions used for implementing business logic (as well as connecting to backing services/DBs, etc.) outside of a controller. So in a typical controller you might have:
class DashboardController {
StatisticsService statsService
def index() {
// Fetches all the stats that need to be displayed to the
// admin on the dashboard.
AdminDashboardMetrics adm = statsService.getAdminStats()
render(view: "/dashboard", model: [ adm: adm ])
}
}
Here, Grails automatically injects the DashboardController with a bean instance of StatisticsService (provided of course that the service was properly created with grails create-service ...).
But what happens when I need to access StatisticsService outside of a controller, and particularly, under src/groovy?
// src/groovy/com/example/me/myapp/FizzBuzzer.groovy
class FizzBuzzer {
StatisticsService statsService
FizzBuzzer(StatisticsService statsService) {
super()
this.statsService = statsService
}
def doSomething(MyData input) {
MoreData result = statsService.calculate(input)
// use 'result' somehow, etc....
}
}
How do I properly inject FizzBuzzer with the same StatisticsService instance ad what is passed into DashboardController?
You can inject grails service in spring bean by defining injection login in resources.groovy under conf > spring
As I made an ExampleService and Example class in src/groovy
ExampleService
class ExampleService {
def serviceMethod() {
println "do something"
}
}
Example Class under src/groovy
class Example {
ExampleService exampleService
def doSomething() {
def result = exampleService.serviceMethod()
}
}
resources.groovy under conf>spring
beans = {
ex(Example){ bean ->
exampleService = ref('exampleService')
}
}
so I can define Example ex as spring bean in grails-app and it will have ExampleService injected by itself.
Hope this helps. Thanks
You can also get a service using grails.util.Holders
Example:
For injecting MyService service class, use Holders.applicationContext.getBean("myService")
Where "myService" is the name of your service class in lower camel case.
One way of achieving this is by using ServletContext-
ApplicationContext ctx = (ApplicationContext)ServletContextHolder.
getServletContext().getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT)
statisticsService = (StatisticsService ) ctx.getBean("statisticsService ")
see this blog - http://www.grailsbrains.com/availing-grails-goodies-in-srcjava-or-srcgroovy/

How to inject Grails services into src/groovy classes

Grails 2.4.x here. If I created a Grails service using grails create-service com.example.Widget, then how can I inject a reference of that service (a "bean") into a class under src/groovy?
This is actually not explained anywhere in the official Grails docs, and extensive searching turned back nadda.
1) You can use Spring Beans to inject a service into a non-artefact groovy file, using resources.groovy:
MyClass.groovy
class MyClass {
def widgetService
...
}
resources.groovy
beans = {
myclass(com.example.MyClass) {
widgetService = ref('widgetService')
}
}
2) There is also an additional #Autowired annotation that can do the same thing:
MyClass.groovy
import org.springframework.beans.factory.annotation.Autowired
class MyClass {
#Autowired
def widget
...
}
resources.groovy
beans = {
myclass(com.example.MyClass) {}
}
Notice - this time the myclass bean doesn't need the reference to the widget.
3) There is an alternative to injecting the WidgetService - using the Holders class to get the grailsApplication which will have a reference to the existing bean.
import grails.util.Holders
class MyClass {
def widgetService = Holders.grailsApplication.mainContext.getBean('widgetService')
...
}
**Update**
4) There is another option that is a hybrid of 1) and 2) -
Having the bean(s) injected by autowire=true within resources.groovy:
MyClass.groovy
class MyClass {
def widgetService
...
}
resources.groovy
beans = {
myclass(com.example.MyClass) { bean ->
bean.autowire = true
}
}
This is the approach I've been using locally as I feel it's the cleanest, but it does take more advantage of Grail's 'magic' (for better or worse).

Dependency injection not working inside Grails service

I have a class that I moved under the grails-app/services directory in order to inject the springSecurityService. This class is the implementation (Is that the proper terminology?) of the spring userDetailsService class. Here is my declaration in resources.groovy:
userDetailsService(com.company.product.PracticeUserDetailsService) {
grailsApplication = ref('grailsApplication')
}
This class is extending GormUserDetailsService.
My attempted dependencyInjection results in a null object.
class PracticeUserDetailsService extends GormUserDetailsService{
def springSecurityService
UserDetails loadUserByUsername(String username, boolean loadRoles) throws UsernameNotFoundException {
// impl omitted
}
}
If I create some test controller or some service in grails and inject the springSecurityService, it works fine. So, there is perhaps something about this particular class that is not placing it in the Grails ecosystem. I checked out this to try to manually inject it as follows:
beans = {
springSecurityTEST(grails.plugins.springsecurity.SpringSecurityService) {}
}
Move PracticeUserDetailsService from grails-app/services to src/groovy and change your Spring bean definition in resources.groovy to:
userDetailsService(com.company.product.PracticeUserDetailsService) {
grailsApplication = ref('grailsApplication')
springSecurityService = ref('springSecurityService')
}
For me it happened when I used GrailsApp.run(Application, args) to run the app...

Grails - Bootstrap - null pointers instead of services

I'd like to use data generator at init in my application. It works fine when create objects using .save() method, but it doesn't work when I want to use dedicated services, because of null pointers instead of injected services. That's my code:
I have defined DataGenerator bean inside conf/spring
beans = {
dataGenerator(DataGenerator)
}
My Bootstrap.groovy looks like:
class BootStrap {
def dataGenerator
def init = { servletContext ->
dataGenerator.generateData()
}
}
In `DataGenerator' I have:
class DataGenerator{
BookService bookService
def generateData() {
log.info("Generating books")
createBooks()
}
def createBooks(){
(1..40).each() {
CreateBookCommand command = new CreateBookCommand()
/* some command populate code*/
bookService.create(command);
}
}
}
The problem is, that I cannot invoke create() method, because bookService is always null
BookService is simple grails service with some dependencies, of course placed in grails-app/services
class BookService {
UserService userService
SpringSecurityService springSecurityService
def create(CreateBookCommand command){
Book book = new Book()
command.bindTo(book)
book.save(flush:true, failOnError:true)
}
/*some other methods*/
}
Could you tell me how to fix it?
Try this in resources.groovy
beans = {
dataGenerator(DataGenerator) { bean ->
bean.autowire = 'byName'
}
}
I assume DataGenrator being a class outside the grails artifact (that is: placed in src/groovy), you can refer the already available service class in the context as:
beans = {
dataGenerator(DataGenerator){
bookService = ref('bookService')
}
}
or try autowiring byName as mentioned by #sudhir.

Grails 2.x service injection in Groovy/src

I'd like to inject my service in Groovy/src class. The normaln dependency injection doesn't work:
...
def myService
...
I'm able to use this (it works):
def appCtx = ApplicationHolder.application.getMainContext()
def myService = appCtx.getBean("myService");
but the ApplicationHolder is deprecated. Is there any better solution?
Thanks for any suggestion
The replacement of ApplicationHolder can be Holders, you can also use it in static scope:
import grails.util.Holders
...
def myService = Holders.grailsApplication.mainContext.getBean 'myService'
Check following Grails FAQ to get access to the application context from sources in src/groovy - http://grails.org/FAQ#Q: How do I get access to the application context from sources in src/groovy?
There is no ApplicationContextHolder class equivalent to ApplicationHolder. To access to a service class called EmailService from a Groovy class in src/groovy, access the Spring bean using:
import org.codehaus.groovy.grails.web.context.ServletContextHolder as SCH
import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes as GA
def ctx = SCH.servletContext.getAttribute(GA.APPLICATION_CONTEXT)
def emailService = ctx.emailService
You can easily register new (or override existing) beans by configuring them in grails-app/conf/spring/resources.groovy:
// src/groovy/com/example/MyClass.groovy
class MyClass {
def myService
...
}
// resources.groovy
beans = {
myclass(com.example.MyClass) {
myService = ref('myService')
}
}
Also you can check this question about How to access Grails configuration in Grails 2.0?
Yo can do it from the resources.groovy:
// src/groovy/com/example/MyClass.groovy
class MyClass {
def myService
...
}
// resources.groovy
beans = {
myclass(com.example.MyClass) {
myService = ref('myService')
}
}
or just using the autowired anotation:
// src/groovy/com/example/MyClass.groovy
import org.springframework.beans.factory.annotation.Autowired
class MyClass {
#Autowired
def myService
...
}
// resources.groovy
beans = {
myclass(com.example.MyClass) {}
}

Resources