Showing posts with label Bean. Show all posts
Showing posts with label Bean. Show all posts

Tuesday, November 21, 2017

Grails Groovy Use Groovy Source Class As Singleton Bean | Custom Bean Definition | Transactional Bean



This will act as a transnational bean

First put the below settings to 'Config.groovy'

grails.hibernate.cache.queries = true
grails.databinding.convertEmptyStringsToNull = true

Need to add/modify below contents to 'BuildConfig.groovy' to enable database connection using MYSQL:

grails.project.dependency.resolver = "maven" // or ivy
grails.project.dependency.resolution = {
    // inherit Grails' default dependencies
    inherits("global") {
        // specify dependency exclusions here; for example, uncomment this to disable ehcache:
        // excludes 'ehcache'
    }
    log "error" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
    checksums true // Whether to verify checksums on resolve
    legacyResolve false // whether to do a secondary resolve on plugin installation, not advised and here for backwards compatibility

    repositories {
        inherits true // Whether to inherit repository definitions from plugins

        grailsPlugins()
        grailsHome()
        mavenLocal()
        grailsCentral()
        mavenCentral()
        // uncomment these (or add new ones) to enable remote dependency resolution from public Maven repositories
        //mavenRepo "http://repository.codehaus.org"
        //mavenRepo "http://download.java.net/maven/2/"
        //mavenRepo "http://repository.jboss.com/maven2/"
        mavenRepo "https://oauth.googlecode.com/svn/code/maven"
    }

    dependencies {
        // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes e.g.
        compile "org.springframework:spring-orm:$springVersion"
        runtime 'mysql:mysql-connector-java:5.1.29'
        runtime 'org.springframework:spring-test:4.0.5.RELEASE'
        runtime "commons-httpclient:commons-httpclient:3.1"
        runtime "org.apache.httpcomponents:httpclient:4.3.3"
        runtime 'net.oauth.core:oauth-httpclient4:20090913'
    }

    plugins {
        build ":tomcat:7.0.55"
        runtime ":hibernate4:4.3.6.1"
        compile ":rendering:1.0.0"
        compile ":browser-detection:0.4.3"
        compile ':cache:1.1.8'
        compile ":mail:1.0.5"
        compile ":asset-pipeline:1.9.9"
        compile ':quartz:1.0.2'
    }
}

Below may be you database configuration (DataSource.groovy):

dataSource {
    pooled = true
    jmxExport = true
    driverClassName = "com.mysql.jdbc.Driver"
    dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
    dbCreate = "update"
    username = "root"
    password = ""
    logSql = false
    loggingSql = false
    properties {
        maxActive = 1000
        maxIdle = 100
        minIdle = 50
        initialSize = 1
        minEvictableIdleTimeMillis = 60000
        timeBetweenEvictionRunsMillis = 60000
        numTestsPerEvictionRun = 3
        maxWait = 10000
        testOnBorrow = true
        testWhileIdle = true
        testOnReturn = true
        validationQuery = "SELECT 1"
        minEvictableIdleTimeMillis = 1800000
        timeBetweenEvictionRunsMillis = 1800000
    }
}
hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = true
    cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
    cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
    format_sql = false
    use_sql_comments = false
}

// environment specific settings
environments {
    development {
        dataSource {
            url = "jdbc:mysql://localhost/db_name?useUnicode=yes&characterEncoding=UTF-8"
            logSql = true
            loggingSql = true
        }
    }
    test {
        dataSource {
            url = "jdbc:mysql://localhost/db_name?useUnicode=yes&characterEncoding=UTF-8"
            logSql = true
            loggingSql = true
        }
    }
    production {
        dataSource {
            url = "jdbc:mysql://localhost/db_name?useUnicode=yes&characterEncoding=UTF-8"
        }
    }
}
log4j = {
    debug 'org.hibernate.SQL'
    trace 'org.hibernate.type.descriptor.sql.BasicBinder'
}

Now create a domain class like below:

package com.pritom

class Home {
    Long id
    String name
    String roll

    static constraints = {
        name blank: false
        roll blank: false, unique: true
    }
}

Below is the most important class which will be act as a singleton bean in our system:

package com.pritom

import org.springframework.transaction.annotation.Transactional
/**
 * Created by pritom on 21/11/2017.
 */
@Transactional(rollbackFor = [Exception, NoClassDefFoundError])
class MyBean {
    {
        println("BEAN-INITIALIZATION----------------$from------------------")
    }

    private String from = null

    void setFrom(String x) {
        this.from = x
    }

    void testPrint(String a) {
        println("Bean-class=${this.toString()}===${a}-----------$from")
        Thread.sleep(2000L)
        if (true) new Home(name: "Home-" + Home.count(), roll: String.valueOf(System.currentTimeMillis())).save()
        println("Home-count=${Home.count()}")
        if (true) throw new NoClassDefFoundError("Yeah!!!")
    }
}

We are not completed yet, need to initialize bean from resource.groovy as below:

beans = {
    myBean(MyBean) { bean ->
        bean.scope = 'singleton' // Set bean as singleton
        from = "Resource.groovy" // Set value to a field of class MyBean when initializing
    }
}

And finally test bean from some controller like below:

package com.pritom

class HomeController {
    def myBean

    def index() {
        try {
            myBean.testPrint("1")
            myBean.testPrint("2")
        }
        catch (Throwable ex) {
            println("Error=${ex.getMessage()}")
        }
        render ""
    }
}

And you can download source code from here

Monday, October 21, 2013

Registering new bean classes in grails application programmatically by registerBeanDefinition

As part of amazing goodies of grails is the ability to extend your applications - registering new classes problematically is a breeze


GenericApplicationContext context = new GenericApplicationContext();

context.setParent(applicationContext);
/* OR */
context.setParent(grailsApplication.mainContext);

// Create class from string
Class clazz = new GrailsAwareClassLoader().parseClass(classString);

// First create a bean definition
def myBeanDef = new GenericBeanDefinition()

// Set bean class
myBeanDef.setBeanClass(clazz)

// Set scope
myBeanDef.setScope(BeanDefinition.SCOPE_SINGLETON)

context.registerBeanDefinition("beandefName", myBeanDef);

Wednesday, August 7, 2013

Grails bean/service initialization dynamically to handle circular dependency

Suppose you have a service named OneService and another service named TwoService;
Now if you try to initiate TwoService in OneService and OneService in TwoService then you have some error regarding circular depency.

class OneService {
    def twoService;
}

class TwoService {
    def oneService;
}
To handle this you may need some trick.
First create a private static variable myTwoService and then initiate it when call it.

import org.codehaus.groovy.grails.web.context.ServletContextHolder as SCH
import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes as GA

class OneService {
    def ctx
    private static TwoService myTwoService;

    def getTwoService() {
        if(!ctx) {
            ctx = SCH.servletContext.getAttribute(GA.APPLICATION_CONTEXT)
        }
        if(!myTwoService) {
            myTwoService = ctx.getBean("twoService");
        }
        return myTwoService;
    }

    def someFunction = {
        def str = twoService.callSomeFunction();  
        /* it actually call getTwoService */
    }
}
And change you TwoService to call OneService such this way.

How do I get an instance of a Grails service programmatically

The Grails documentation describes a way to get a service when in a servlet. This might be useful, if you can obtain the same objects in your context:

ApplicationContext ctx = (ApplicationContext)ApplicationHolder.getApplication().getMainContext();
CountryServiceInt service = (CountryServiceInt) ctx.getBean("countryService");
String str = service.sayHello("Some String!");