How to get Spring to create AOP proxies for my beans

In my Spring application, I have a whole group of beans (in this case, DAO) that were created as simple <bean> in my XML configuration. These annotations provide various annotations, including specifically @Transactional . I naturally have <tx:annotation-driven /> .

But for some of these objects, although only some of them are not proxies created (I confirmed this by turning on debug logging), and the @Transactional annotation has no effect. Instead, objects that contain (usually automatically) links to these DAOs receive a wired link to a direct class, not a proxy.

All classes have corresponding interfaces, and links using auto-connect always pass through these interfaces.

I can’t understand which classes receive proxies and which do not. I want them all. So my question is:

a) Under what circumstances does Spring not create a proxy for the class, even if it implements some interfaces?

b) How can I get Spring to create the proxies I need?

Please note that I did nothing to explicitly allow proxies, but I did not need to in the past. This usually works.

Tried both with Spring 3.1.3, and with 3.2.2.

I do not have SSCCE for this. Essentially my xml

 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:sec="http://www.springframework.org/schema/security" xmlns:context="http://www.springframework.org/schema/context" xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.2.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd "> <bean id="userDao" class="com.soschat.dao.spring.SpringUserDAO"/> <tx:annotation-driven transaction-manager="transactionManager" /> <bean id="transactionManager" class=" org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> <property name="globalRollbackOnParticipationFailure" value="false" /> </bean> ... etc ... </beans> 

and my code is more or less

 public class UserDaoImpl implements UserDao { @Override @Transactional @Cacheable public User getUserById(long userId) { // do stuff } } 

Not sure how much more needs to be added without further details.

One interesting addition - I can force it to create a proxy server using BeanNameAutoProxyCreator. But not one of the annotations that I introduced there really takes effect.

+4
source share
3 answers

In the end, I realized that it was failing due to some kind of dependency chain, starting with a bean that somehow loaded "too early" - in my case, Spring Security PermissionEvaluator . I still do not have SSCCE, but I am adding this answer here if someone had a similar problem.

The solution was to use very late binding. I made my PermssionEvaluator in ApplicationContextAware , and then wrote a private method to load local links from ApplicationContext , and this method is called only when it is needed first, which is not during initialization.

In other words, I had a bean like

 private AuthorizationServices authServices; 

and then in my main method something like

 if (authServices == null) initBeans(); 

and then

 private void initBeans() { authServices = ac.getBean(AuthorizationServices.class); } 
+2
source

The @Component tells Spring to create and process the bean of this class. You need your application (or another) to scan this class package with the <component-scan> element.

@Service , @Repository , @Controller work just like @Component .

As for proxying, Spring does not proxy everything, only instances of classes to which it needs to add behavior. For example, with @Transactional it needs to add the transaction behavior begin / commit / rollback. To do this, he reduces the methods of the class using his own code, so he needs a proxy. For the @Controller class @Controller it does not need to add any behavior, so it just creates an instance of your class.

+3
source

We ran into the same problem and realized that the bean was initialized before org.springframework.cache.ehcache.EhCacheCacheManager when the application started, so @Cacheable did not work.

We have finished moving the cache configuration to xml from the java configuration class, which forces (not sure how) the initialization of EHCacheManager before any beans application. We have both xml and java configuration in our application.

 <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcache"/> <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="classpath:ehcache.xml" p:shared="true"/> 
0
source

Source: https://habr.com/ru/post/1480165/


All Articles