Transactions, Caching and AOP: understanding proxy usage in Spring |
|

In the Spring framework, many technical features rely on proxy usage. We are going to go in depth on this topic using three examples: Transactions, Caching and Java Configuration.
All the code samples shown in this blog entry are available on my github account.
Transactions
First step: no transaction
The Service class below is not transactional yet. Let’s first look at it as is and then make it become transactional.
@Service
public class AccountServiceImpl implements AccountService {
//…
//Not specifying a transaction policy here!
public void create(Account account) {
entityManager.persist(account);
}
}
Since the method “create” is not transactional, it will most likely throw an exception (because this Account object should not be persisted outside of a transaction).
Here is what we have at runtime:

Second step: adding transactional behavior configuration
Let us now add @Transactional on top of the create(…) method:
@Service
public class AccountServiceImpl implements AccountService {
@PersistenceContext
private EntityManager entityManager;
@Transactional
public void create(Account account) {
entityManager.persist(account);
}
}
And here is the corresponding Spring configuration:
<bean id="transactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <tx:annotation-driven/>
Inside Spring generic configuration, we have used <tx:annotation-driven /> . It means that all @Transactional annotations should be scanned at startup time and the targeted methods should become transactional. So where is the transactional behavior happening?
Before startup, we still have the same files as before:
At startup time, a new class is created, called proxy. This one is in charge of adding Transactional behavior as follows:
The generated proxy class comes on top of AccountServiceImpl. It adds Transactional behavior to it [1].
So how to make sure that a proxy is indeed being used? For your own understanding, it’s interesting to go back into the code and see with your very eyes that you are indeed using a proxy.
A simple way is to print out the class name:
AccountService accountService = (AccountService) applicationContext.getBean(AccountService.class); String accountServiceClassName = accountService.getClass().getName(); logger.info(accountServiceClassName);
On my computer, it shows the following output:
INFO : transaction.TransactionProxyTest - $Proxy13
This class is a Dynamic Proxy, generated by Spring using the JDK Reflection API (more information here).
At shutdown (eg. When the application is stopped), the proxy class will be destroyed and you will only have AccountService and AccountServiceImpl on the file system:
How does Spring wire the proxy in-lieu of the target class?
@Controller
public class AccountController {
private AccountService accountService;
private void setAccountService(AccountService accountService) {
this.accountService=accountService;
}
//…
}
The attribute accountService is of type AccountService (interface). The variable dependency is on the interface type AccountService, not the implementation type, which reduces the coupling between classes. This is a best practice.
As seen before, both AccountServiceImpl and the generated Proxy implement the interface AccountService.
• If there is a proxy, Spring injects the proxy
• If not, Spring injects the instance of type AccountServiceImpl.
Caching
Declarative caching is a new feature in Spring 3.1 that works like Spring’s declarative transaction support.
The @Cacheable annotation should be used in that way:
public class AccountServiceImpl implements AccountService {
@Cacheable(value="accounts", key="#id")
public Account findAccount (long id) {
// only enter method body if result is not in the cache already
}
}
You should also have enabled caching inside Spring configuration as follows:
<cache:annotation-driven />
Here are the expected results:
accountService.findAccount (1); // Result stored into cache for key “1” accountService.findAccount (1); // Result retrieved from cache. Target method not called. accountService.findAccount (2); // Result stored into cache for key “2”
At runtime, a proxy is used to add Caching behavior.

Note: Spring 3.1 embeds a fairly simple cache implementation. It is usually recommended to use another implementation such as ehcache. On the sample application available here (https://github.com/michaelisvy/proxy-samples), you’ll find some examples using both the embedded cache implementation and ehcache.
What if the bean class does not implement any interface?
In the previous example, we mentioned that a proxy should implement the same Interface as your bean.
Thankfully, Spring can also proxy beans that don’t have an interface. There are many cases where implementing an interface is not the best way to go.
By default, if your bean does not implement an interface, Spring uses technical inheritance: at startup time, a new class is created. It inherits from your bean class and adds behavior in the child methods.
Note: this section requires some background knowledge of Java Configuration in Spring. Please feel free to skip it if you are not comfortable with this new configuration style.
You can learn more about Java Configuration here. There is also an excellent article which discusses the various configuration styles here.
@Configuration
public class JavaConfig {
@Bean
public AccountService accountService() {
return new AccountServiceImpl((accountRepository());
}
@Bean
public AccountRepository accountRepository () {
//…
}
}
Spring calls the method accountService() every time it needs to wire an instance of the bean “accountService” and this one returns a “new” object of type AccountService. If 10 beans are using a dependency of type AccountService, this method is called 10 times.
However, no matters the Spring configuration has been made using Java Configuration or not, every bean should be a singleton by default. How is that possible and where is the magic happening?
This diagram explains how things work internally:
So the Proxy is adding behavior there. In the case that your bean should be a singleton, the action to turn your Plain Old Java Object into a singleton is performed by a child class (Proxy).
Conclusion
We’ve seen some use-cases on how proxies are used inside the Spring framework. There are many other examples: Aspect Oriented Programming, Security (using Spring Security), thread safety, scopes, etc…
If you would like to know more on the impact on performance when using proxies, you can read Alef Arendsen’s blog entry here.
Similar Posts
- Getting started with Spring Data JPA
- Spring 3.1 M1: Cache Abstraction
- Another Reason to Love Spring 2.0: Interceptor Combining
- Migrating to Spring 3.1 and Hibernate 4.1
- Debunking myths: proxies impact performance











Nedo says:
Added on May 23rd, 2012 at 6:55 amGreat post and very precise explantion .
John Coleman says:
Added on May 23rd, 2012 at 11:17 amBeautiful post. I have a good feel for the mechanics of proxies but I am always glad to see you guys "demystify" Spring when you have the opportunity.
Nick T. says:
Added on May 23rd, 2012 at 2:09 pmWhat would happen if you tried to use the @Transaction and @Cacheable annotations on the same method, or (more realistically) just in the same class? It doesn't really make sense to want to cache an operation that requires a transaction, but even in your example you might want to cache a find method while wrapping a create, update, or delete method in a transaction. I imagine one proxy would wrap the proxy that wraps the base class, but is there a heuristic for which would wrap which?
Peter Davis says:
Added on May 23rd, 2012 at 11:20 pmCglib proxies delegate to a 2nd instance of the real class; they don't call "super" as your diagram indicates. Or has this changed since 3.1.x? It'd be helpful if you could explain the consequences of proxy delegation—if you call another method on "this", it will bypass the proxy along with any AOP.
I noticed that JavaConfig classes do NOT use delegates. Do you think Spring could ever expose this kind of non-delegate-cglib-inheritance-based proxies as an option for regular AOP? I think this would help avoid the ugly hacks to call methods on "this" (see the docs), but would it cause other problems?
Michael Isvy (blog author) says:
Added on May 24th, 2012 at 12:24 am@Nick: this is a very interesting question. And it's definitely possible to combine @Caching and @Transactional in the same class or even on the same method.
Like you said, combining Transactions and Caching is not the most obvious real-life example. However people commonly combine @Secured and @Transactional.
I've added one sample to my Github sample app here: https://github.com/michaelisvy/proxy-samples/tree/9b54268168c99dbdc0f56406de13ab55e5c85ebb/src/main/java/multi
Cheers,
Michael.
Marco Molteni says:
Added on May 24th, 2012 at 3:12 amThanks for the useful post Michael. We are introducing Spring in an old Struts application and we need to explain to the dev team how @Transactional work. You did it for us
Michael Isvy (blog author) says:
Added on May 24th, 2012 at 9:50 am@Peter: well I don't know much about CGlib internals myself so I have asked my colleague Chris Beams. Here is what we discussed:
In our @Configuration use, there's just one instance of the given @Configuration class, and it's the CGLIB dynamic subclass.
If you'd like to look at the code to see how it's been done, you can check how ConfigurationClassPostProcessor and ConfigurationClassEnhancer work together to swap out the original @Configuration bean class for the generated CGLIB subclass.
As a consequence the container only ever knows about the subclass and that's the only bean ever to be instantiated.
Regarding the fact that Java Configuration does not use delegates, please feel free to open a Jira issue. However, since CGlib is likely to be de-emphasized in Spring 3.2, I am not sure if we will put a high priority on improving CGlib support.
Cheers,
Michael.
Chris says:
Added on May 24th, 2012 at 9:16 pmThanks for the beautiful post.
Mario Guerrero says:
Added on May 24th, 2012 at 10:25 pmThanks, great doc.
Oliver Gierke says:
Added on May 25th, 2012 at 6:03 am@Nick, @Michael – it definitely makes sense to use @Transactional in combination with @Cacheable as you can have (and should) readOnly transactions. Setting the readOnly flag for a transaction can seriously performance of the call as the flag is handed to the underlying database driver to perform low level optimizations. Beyond that when using e.g. HibernateTransactionManager the flush mode is set to manual, so that no (potentially expensive) dirty checks occur on a huge object tree you might have loaded.
Beyond that the @Cacheable has higher priority so that no transaction would be triggered in case we have a cache hit.
Michael Isvy (blog author) says:
Added on May 25th, 2012 at 9:50 amThanx Oliver, that's a nice idea. I've added a finder method that is both Transactional (readOnly) and Cacheable.
hantsy says:
Added on May 28th, 2012 at 9:13 pmA stupid question about the @Transactional when I used in a Spring/JSF2 project.
I enabled OpenEntityManagerInView Filter to avoid lazy exception the rendering response of jsf.
But I encountered a problem, when I added readonly @Transactional on a query(select clause), the OpenEntityManagerInView did not work as expected, but after I removed the @Transactional, it worked.
What is the reason of this? OpenEntityManagerInView can not worked on a Proxy?
Thanks.
Hantsy
http://hantsy.cublog.cn
Michael Isvy (blog author) says:
Added on May 28th, 2012 at 10:37 pm@Hantsy well I am not a big fan of OpenSessionInViewFilter and OpenEntityManagerInViewFilter so I'm not the best person to answer.
I'm sure some people will help if you post a detailed description of your issue on the Spring forum here: http://forum.springsource.org/forumdisplay.php?27-Data
Cheers,
Michael.
hantsy says:
Added on May 29th, 2012 at 12:06 amThanks, Michael
McNinja says:
Added on May 30th, 2012 at 8:29 am"It is vitally important that you grasp the semantics of what that last statement actually means before you write your own aspects or use any of the Spring AOP-based aspects supplied with the Spring Framework."
SPRING DOCUMENTATION SEZ THIS IS VITALLLLLLLLLLL!
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/aop.html#aop-understanding-aop-proxies
Surendra says:
Added on May 31st, 2012 at 11:46 pmVery Nice Artical. Thanks
Rajiv says:
Added on June 13th, 2012 at 1:41 amIndeed one of the best article on this topic, never knew so much details about how proxy used in Spring. By the way how did you created those diagrams ?
Michael Isvy (blog author) says:
Added on June 13th, 2012 at 1:46 amThanx Rajiv. I have used Powerpoint for that. Simple and easy
.
janak says:
Added on June 22nd, 2012 at 3:18 amlearing material
Kumar says:
Added on July 11th, 2012 at 3:43 amWas really helpful. I have seen people using it blindly without understanding the semantics.
Thanks a lot.
KN says:
Added on August 21st, 2012 at 1:01 pmHi
We are having serious memory issue occured when i used aop with scoped bean (session) on applicationContext.xml. just trying to any known issue with this approach..
Michael Isvy (blog author) says:
Added on August 21st, 2012 at 11:50 pm@KN Sorry I don't think I can help much on that. Please feel free to use the dedicated section in the Spring forum.
kinghom says:
Added on September 27th, 2012 at 12:25 amit's easy to read
hackerster says:
Added on December 25th, 2012 at 10:41 amhello.I want to ask a question about AOP(@args).Can you tell me your email address or send me a email thanks very much.