under the hood: using spring in grails

35
Burt Beckwith SpringSource Under the Hood: Using Spring in Grails

Upload: gr8conf

Post on 17-May-2015

4.295 views

Category:

Technology


7 download

DESCRIPTION

From GR8Conf EU 2012. Read the presentation abstract here: http://gr8conf.eu/Presentations/Under-the-Hood-Spring-in-Grails

TRANSCRIPT

Page 1: Under the Hood: Using Spring in Grails

Burt BeckwithSpringSource

Under the Hood:Using Spring in Grails

Page 2: Under the Hood: Using Spring in Grails

2CONFIDENTIAL 2CONFIDENTIAL

Who Am I

Page 3: Under the Hood: Using Spring in Grails

3CONFIDENTIAL 3CONFIDENTIAL

Who Am I

Java developer for over 13 years

Background in Spring, Hibernate, Spring Security

Grails developer for 5 years

SpringSource employee on the Grails team

Created or reworked over 40 Grails plugins

http://burtbeckwith.com/blog/

https://twitter.com/#!/burtbeckwith

Page 4: Under the Hood: Using Spring in Grails

4CONFIDENTIAL 4CONFIDENTIAL

Spring Overview

Main functions of Spring

• Bean container: ApplicationContext and BeanFactory

• Dependency Injection (DI) and Inversion of Control (IoC)

• Proxies

• Transactions

• Security

• Caching

• Event publishing and listening

• Exception conversion

Page 5: Under the Hood: Using Spring in Grails

5CONFIDENTIAL 5CONFIDENTIAL

Bean PostProcessors

Page 6: Under the Hood: Using Spring in Grails

6CONFIDENTIAL 6CONFIDENTIAL

Bean PostProcessors

o.s.b.factory.config.BeanPostProcessor

• Object postProcessBeforeInitialization(Object bean, 

String beanName)

• Object postProcessAfterInitialization(Object bean, 

String beanName)

Page 7: Under the Hood: Using Spring in Grails

7CONFIDENTIAL 7CONFIDENTIAL

Bean PostProcessors

o.s.b.factory.config.BeanFactoryPostProcessor

• void postProcessBeanFactory(ConfigurableListableBeanFactory 

beanFactory)

Page 8: Under the Hood: Using Spring in Grails

8CONFIDENTIAL 8CONFIDENTIAL

Bean PostProcessors

o.s.b.factory.support.BeanDefinitionRegistryPostProcessor

• extends BeanFactoryPostProcessor

• void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry 

registry)

Page 9: Under the Hood: Using Spring in Grails

9CONFIDENTIAL 9CONFIDENTIAL

Cloud Support Plugin (cloud­foundry, heroku)

dataSourceBean.driverClassName = updatedValues.driverClassName

dataSourceBean.url = updatedValues.url + suffix

dataSourceBean.username = updatedValues.userName

dataSourceBean.password = updatedValues.password

Page 10: Under the Hood: Using Spring in Grails

10CONFIDENTIAL 10CONFIDENTIAL

Alternate approach to BeanDefinition modification

def doWithSpring = {

   def mybeanDef = delegate.getBeanDefinition('mybean')

   mybeanDef.beanClass = NewClass

   mybeanDef.propertyValues.add("order",         application.config.plugin?.rendering?.order ?: 42)}

● Use loadAfter = ['plugin1', 'plugin2'] to

ensure the bean is loaded

● Only valid in a plugin, not the app's resources.groovy

Page 11: Under the Hood: Using Spring in Grails

11CONFIDENTIAL 11CONFIDENTIAL

Bean Aliases

Page 12: Under the Hood: Using Spring in Grails

12CONFIDENTIAL 12CONFIDENTIAL

Aliases

As of Grails 2.1 aliases work fully

• You can create aliases pre­2.1 but only if defined in the same 

resources.groovy or plugin (doWithSpring)

beans = {   springConfig.addAlias 'alias', 'realBean'}

Page 13: Under the Hood: Using Spring in Grails

13CONFIDENTIAL 13CONFIDENTIAL

Aliases

The cache plugin registers the alias cacheOperationSource for 

the bean registered as 

org.springframework.cache.annotation.AnnotationCacheOperationSource#0

Can use to have multiple implementations of a bean and choose 

one via configuration at startup, e.g. per­environment or some 

other rule

Page 14: Under the Hood: Using Spring in Grails

14CONFIDENTIAL 14CONFIDENTIAL

Spring MVC Controllers

Page 15: Under the Hood: Using Spring in Grails

15CONFIDENTIAL 15CONFIDENTIAL

Spring MVC

New in Grails 1.2

Annotate src/java or src/groovy classes with @Controller

Add all packages to the grails.spring.bean.packages list in

Config.groovy

• e.g.grails.spring.bean.packages = ['gr8conf.testapp.foo']

Page 16: Under the Hood: Using Spring in Grails

16CONFIDENTIAL 16CONFIDENTIAL

Spring MVC

Annotate methods with

@o.s.w.bind.annotation.RequestMapping

@RequestMapping("/mvc/hello.dispatch")public ModelMap handleRequest() {   return new ModelMap()      .addAttribute("text", "some text")      .addAttribute("cost", 42)      .addAttribute("config",          grailsApplication.getConfig().flatten()));}

Page 17: Under the Hood: Using Spring in Grails

17CONFIDENTIAL 17CONFIDENTIAL

Spring MVC

class UrlMappings {

   static mappings = {      …

      "/mvc/hello"(uri:"/mvc/hello.dispatch")

      "/mvc/other"(uri:"/mvc/other.dispatch")   }}

@RequestMapping URI value must end in .dispatch

Add entries in UrlMappings to create more natural URLs

Page 18: Under the Hood: Using Spring in Grails

18CONFIDENTIAL 18CONFIDENTIAL

Spring MVC

Use @Autowired for dependency injection (on fields in Groovy 

classes, on setters or constructors in Java)

private GrailsApplication grailsApplication;

@Autowiredpublic void setGrailsApplication(GrailsApplication app) {   grailsApplication = app;}

Page 19: Under the Hood: Using Spring in Grails

19CONFIDENTIAL 19CONFIDENTIAL

Transactions

Page 20: Under the Hood: Using Spring in Grails

20CONFIDENTIAL 20CONFIDENTIAL

Utility Methods

import o.s.t.interceptor.TransactionAspectSupportimport o.s.t.support.TransactionSynchronizationManager

for (sc in grailsApplication.serviceClasses) {   def metaClass = sc.clazz.metaClass

   …}

Page 21: Under the Hood: Using Spring in Grails

21CONFIDENTIAL 21CONFIDENTIAL

Utility Methods

// returns TransactionStatusmetaClass.getCurrentTransactionStatus = { ­>

if (!delegate.isTransactionActive()) {return null

}TransactionAspectSupport.currentTransactionStatus()

}

Page 22: Under the Hood: Using Spring in Grails

22CONFIDENTIAL 22CONFIDENTIAL

Utility Methods

// void, throws NoTransactionExceptionmetaClass.setRollbackOnly = { ­>

TransactionAspectSupport.currentTransactionStatus()         .setRollbackOnly()}

Page 23: Under the Hood: Using Spring in Grails

23CONFIDENTIAL 23CONFIDENTIAL

Utility Methods

// returns booleanmetaClass.isRollbackOnly = { ­>

if (!delegate.isTransactionActive()) {return false

}delegate.getCurrentTransactionStatus().isRollbackOnly()

}

Page 24: Under the Hood: Using Spring in Grails

24CONFIDENTIAL 24CONFIDENTIAL

Utility Methods

// returns booleanmetaClass.isTransactionActive = { ­>

TransactionSynchronizationManager         .isSynchronizationActive()}

Page 25: Under the Hood: Using Spring in Grails

25CONFIDENTIAL 25CONFIDENTIAL

Proxies

Page 26: Under the Hood: Using Spring in Grails

26CONFIDENTIAL 26CONFIDENTIAL

A Simple Proxied Bean – The interface

package gr8conf.eu.spring;

public interface ThingManager {

void method1();

int methodTwo(boolean foo);}

Page 27: Under the Hood: Using Spring in Grails

27CONFIDENTIAL 27CONFIDENTIAL

A Simple Proxied Bean – The implementation

package gr8conf.eu.spring;

public class ThingManagerImpl       implements ThingManager {

public void method1() {System.out.println("You called method1");

}

public int methodTwo(boolean foo) {System.out.println("You called methodTwo");return 42;

}}

Page 28: Under the Hood: Using Spring in Grails

28CONFIDENTIAL 28CONFIDENTIAL

A Simple Proxied Bean – The FactoryBean

package gr8conf.eu.spring;

public class ThingManagerProxyFactoryBean       implements FactoryBean<ThingManager>,                  InitializingBean {

   private ThingManager managerProxy;   private ThingManager target;

   public ThingManager getObject() {      return managerProxy;   }

   public Class<ThingManager> getObjectType() {      return ThingManager.class;   }

   public boolean isSingleton() {      return true;   }

Page 29: Under the Hood: Using Spring in Grails

29CONFIDENTIAL 29CONFIDENTIAL

A Simple Proxied Bean – The FactoryBean

public void setTarget(ThingManager manager) {   target = manager;}

public void afterPropertiesSet() {

   Assert.notNull(target,       "The proxied manager must be set");

   Class<?>[] interfaces = { ThingManager.class };

   InvocationHandler invocationHandler =      new InvocationHandler() {         public Object invoke(Object proxy,            Method m, Object[] args)               throws Throwable {

Page 30: Under the Hood: Using Spring in Grails

30CONFIDENTIAL 30CONFIDENTIAL

A Simple Proxied Bean – The FactoryBean

         System.out.println("Before invoke " +                            m.getName());

         Object value = m.invoke(target, args);

         System.out.println("After invoke " +                            m.getName());

         return value;      }   };

   managerProxy = (ThingManager)Proxy.newProxyInstance(      ThingManager.class.getClassLoader(),      interfaces,      invocationHandler);   }}

Page 31: Under the Hood: Using Spring in Grails

31CONFIDENTIAL 31CONFIDENTIAL

A Simple Proxied Bean – resources.groovy

import gr8conf.eu.spring.ThingManagerimport gr8conf.eu.spring.ThingManagerImplimport gr8conf.eu.spring.ThingManagerProxyFactoryBean

beans = {

   realThingManager(ThingManagerImpl) {      // properties, etc.   }

   thingManager(ThingManagerProxyFactoryBean) { bean ­>      // bean.scope = ...      // bean.lazyInit = true      // target = ref('realThingManager')   }}

Page 32: Under the Hood: Using Spring in Grails

32CONFIDENTIAL 32CONFIDENTIAL

A Simple Proxied Bean – resources.groovy

import gr8conf.eu.spring.ThingManagerimport gr8conf.eu.spring.ThingManagerImplimport gr8conf.eu.spring.ThingManagerProxyFactoryBean

beans = {

   thingManager(ThingManagerProxyFactoryBean) { bean ­>      // bean.scope = ...      // bean.lazyInit = true

      target = { ThingManagerImpl thing ­>         // properties, etc.      }   }}

Page 33: Under the Hood: Using Spring in Grails

33CONFIDENTIAL 33CONFIDENTIAL

Want More Information?

Page 34: Under the Hood: Using Spring in Grails
Page 35: Under the Hood: Using Spring in Grails

35CONFIDENTIAL 35CONFIDENTIAL

Thank You