Reputation: 12110
I have defined the following interceptor:
@Aspect
public class OpenSessionInRequestInterceptor {
private Log log = LogFactory.getLog(getClass());
@Autowired
private SessionFactory sessionFactory;
public OpenSessionInRequestInterceptor() {
}
@Around("@annotation(com.sc2.master.aop.hibernate.OpenSession)")
public Object processAround(ProceedingJoinPoint pjp) throws Throwable {
log.info("Opening Hibernate Session in method "+pjp.getSignature());
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
Object ret = pjp.proceed();
session.close();
TransactionSynchronizationManager.unbindResource(sessionFactory);
log.info("Closing Hibernate Session in method "+pjp.getSignature());
return ret;
}
}
When I execute the following piece of code in a spring test
@OpenSession
public void call() {
BusinessCustomer customer = (BusinessCustomer) this.customerDao.loadAll().get(0);
System.out.println(customer.getContacts().size());
}
the aspect method is called. To start the test my test case class looks as follows:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:WebContent/WEB-INF/applicationContext.xml"})
@Transactional
However, when I have a method annotated with @OpenSession and deploy the application on my Tomcat server, the interceptor method is not called.
The application context definition looks as follows:
<aop:aspectj-autoproxy proxy-target-class="true">
</aop:aspectj-autoproxy>
<bean id="openSessionInRequestInterceptor" class="OpenSessionInRequestInterceptor"></bean>
I can absolutely not figure out, why AOP does not work when deployed on the tomcat. I hope you have some ideas.
Solution I found the solution. I places my aop configuration in the applicationContext.xml, but this will not work. I placed the configuration in the application-servlet.xml and now everything is fine. Has someone an idea why?
Upvotes: 3
Views: 5217
Reputation: 460
To answer why you have to put configuration in the servlet XML to get to work:
I assume you are using <context:component-scan ...>
tag and this is placed in the servlet XML. That is the reason why you need to have them both in servlet XML, otherwise they don't "see" each other. As a result, the connection is not properly established.
Upvotes: 1
Reputation: 597026
I admit I didn't have to make it work using a marker annotation, but I needed the annotation as argument, so this worked:
@Around("@annotation(foo)")
public Object invoke(ProceedingJoinPoint invocation, Foo foo) throws Throwable
But.. note that @Transactional
also starts a session if one isn't started, so perhaps you don't really need that.
Update: if your beans are defined in the child context, then the aop configuration of the parent context does not affect them. The parent context does not see the child context, and your x-servlet.xml
is a child context.
Upvotes: 2