HowToDoInJava

  • Python
  • Java
  • Spring Boot
  • Dark Mode
Home / Spring Transaction / Load-time weaving

Spring transactions on non-public methods with load-time weaving

In this tutorial, we will learn to apply transactions in any spring application on non-public methods (by deault spring AOP can only advise public methods of beans declared in the IoC container). Using this technique, you can manage transactions for nonpublic methods, or on any methods into objects which are created outside the Spring IoC container (i.e. not managed by IoC container).

Manage transaction using AnnotationTransactionAspect

Spring has an AspectJ aspect named AnnotationTransactionAspect that can manage transactions for any methods of any objects, even if the methods are non-public or the objects are created outside the Spring IoC container.

This aspect will manage transactions for any methods with the @Transactional annotation. To enable this useful aspect, you can change configuration in either of two ways given below:

  1. @EnableLoadTimeWeaving annotation
  2. <context:load-time-weaver />; configuration

Using @EnableLoadTimeWeaving annotation

@EnableLoadTimeWeaving annotation has to be used on your configuration class to picked up at loading time. All you need to do is to define the @EnableTransactionManagement annotation and set its mode attribute to aspectj.

aspect says that the container should use load-time or compile-time weaving to enable the transaction advice. The other value proxy says that the container should use the default Spring AOP mechanisms.

It’s important to note that the aspect mode doesn’t support configuration of the @Transactional annotation on interfaces (should be used only on classes).

An example configuration will look like this:

@Configuration
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
@EnableLoadTimeWeaving
public class MyApplicationConfiguration 
{ 
	//Configuration code
}

Using <context:load-time-weaver /> configuration

If you have used XML based configuration in your application, then you may use below configuration changes to enable this feature.

<beans>

    <context:load-time-weaver />
    <tx:annotation-driven mode="aspectj"/>  

    <!-- Other beans declarations-->

</beans>
To enable loadtime weaving you also have to include the spring-instrument module. If you’re using Maven, add the following dependencies to your project.
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>${spring.version}</version>
</dependency>

  <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-instrument</artifactId>
  <version>${spring.version}</version>
</dependency>

Drop me your questions and comments below.

Happy Learning !!

Reference : http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-aj-ltw

Share this:

  • Twitter
  • Facebook
  • LinkedIn
  • Reddit

About Lokesh Gupta

A family guy with fun loving nature. Love computers, programming and solving everyday problems. Find me on Facebook and Twitter.

Feedback, Discussion and Comments

  1. hello2333

    November 27, 2017

    I add the configuration as your post said, but my project cannot run and throws exception as below. How can I solve this problem? Thank you.

    java.lang.IllegalStateException: Failed to load ApplicationContext
    
    	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
    	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    	at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:44)
    	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
    	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver' defined in org.springframework.context.annotation.LoadTimeWeavingConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.instrument.classloading.LoadTimeWeaver]: Factory method 'loadTimeWeaver' threw exception; nested exception is java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
    	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
    	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
    	at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
    	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
    	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
    	... 25 more
    Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.instrument.classloading.LoadTimeWeaver]: Factory method 'loadTimeWeaver' threw exception; nested exception is java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
    	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
    	... 42 more
    Caused by: java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
    	at org.springframework.context.weaving.DefaultContextLoadTimeWeaver.setBeanClassLoader(DefaultContextLoadTimeWeaver.java:91)
    	at org.springframework.context.weaving.DefaultContextLoadTimeWeaver.(DefaultContextLoadTimeWeaver.java:67)
    	at org.springframework.context.annotation.LoadTimeWeavingConfiguration.loadTimeWeaver(LoadTimeWeavingConfiguration.java:84)
    	at org.springframework.context.annotation.LoadTimeWeavingConfiguration$$EnhancerBySpringCGLIB$$9f28d716.CGLIB$loadTimeWeaver$3()
    	at org.springframework.context.annotation.LoadTimeWeavingConfiguration$$EnhancerBySpringCGLIB$$9f28d716$$FastClassBySpringCGLIB$$f1ae5b21.invoke()
    	at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358)
    	at org.springframework.context.annotation.LoadTimeWeavingConfiguration$$EnhancerBySpringCGLIB$$9f28d716.loadTimeWeaver()
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    	... 43 more
  2. Binh Thanh Nguyen

    June 30, 2015

    Thanks, nice tip

Comments are closed on this article!

Search Tutorials

Meta Links

  • About Me
  • Contact Us
  • Privacy policy
  • Advertise
  • Guest and Sponsored Posts

Recommended Reading

  • 10 Life Lessons
  • Secure Hash Algorithms
  • How Web Servers work?
  • How Java I/O Works Internally?
  • Best Way to Learn Java
  • Java Best Practices Guide
  • Microservices Tutorial
  • REST API Tutorial
  • How to Start New Blog

Copyright © 2020 · HowToDoInjava.com · All Rights Reserved. | Sitemap

  • Java 15 New Features
  • Sealed Classes and Interfaces
  • EdDSA (Ed25519 / Ed448)