Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

Spring Annotations: Proxy

1.394 visualizaciones

Publicado el

Unintentionally bypassing the Spring bean proxy.

Lightning talk at OSOCO (Programming Gotchas & Pitfalls Series).

Publicado en: Software
  • Inicia sesión para ver los comentarios

  • Sé el primero en recomendar esto

Spring Annotations: Proxy

  1. 1. Spring’s annotations: Proxy José Canfrán (Osoco) September 2015 Programming Gotchas & Pitfalls Series
  2. 2. @Transactional1
  3. 3. Ejemplo package es.osoco.lightTalk import org.springframework.transaction.annotation.Transactional class TransactionalService { @Transactional def firstMethod() { anotherMethod() // code } @Transactional // @Transactional(propagation = Propagation.REQUIRES_NEW) private anotherMethod() { // code } }
  4. 4. Spring: Proxy La anotación Transactional de Spring crea un proxy en tiempo de ejecución de la clase, el cual tiene a su vez una instancia de la clase original. Todas las llamadas a métodos transaccionales son interceptadas por el proxy, que es el encargado de iniciar una transacción, unirse a la existente… y llamar al método del servicio. Pero si se hace una llamada a métodos del mismo servicio, el proxy no podrá interceptarla al encontrarnos por debajo de él, en su instancia del servicio y no se ejecutará la condiciones de transacción que hayamos puesto.
  5. 5. Posibles soluciones ● Grails < 2.3.1 ○ Usar .withTransaction() ● Grails > 2.3.1 ○ Usar @grails.transaction.Transactional: Durante la compilación mediante una transformación AST, se crea un nuevo método por cada método anotado dentro de una GrailsTransactionTemplate que ejecuta el código del original con los ajustes de transacción.Ya no existe proxy y como se ha hecho la misma operación con todos los métodos no hay problemas con las llamadas directas. (Puede fallar con la anotación @CompileStatic)
  6. 6. @Cacheable2
  7. 7. Ejemplo package es.osoco.lightTalk import org.springframework.cache.annotation.Cacheable class CacheableService { def firstMethod() { anotherMethod(param1, param2) // code } @Cacheable private anotherMethod(param1, param2) { // code } }
  8. 8. Solución3
  9. 9. Obtener proxy: En el servicio package es.osoco.lightTalk import org.springframework.cache.annotation.Cacheable class CacheableService { def firstMethod() { proxy.anotherMethod(param1, param2) // code } @Cacheable private anotherMethod(param1, param2) { // code } private getProxy() { def proxy = grailsApplication.mainContext.cacheableService } } De este modo obtenemos el proxy para llamar al método a través de él.
  10. 10. Obtener proxy: Genérico class BootStrap { def grailsApplication def init = { servletContext -> for( sc in grailsApplication.serviceClasses) { sc.clazz.metaClass.getMyProxy = { -> grailsApplication.mainContext.getBean(sc.propertyName) } } } De este modo estará disponible la variable myProxy con el proxy correspondiente en cada servicio.
  11. 11. Bibliografía ◉ Programming Grails (0’Reilly) Burt Beckwith, ISBN: 9 781449 323936 ◉ Documentación Grails https://grails.org/documentation.html
  12. 12. Any questions ? You can find me at ◉ @jose_cg Thanks! This work is licensed under a Creative Commons Attribution 4.0 International License.

×