Reputation: 57
I am new to Spring AOP and facing some issues in its implementation.
I am trying to implement logging as advice. But advice is not getting executed.
Following is the files I am using.
LoggingAspect.java
package com.demo.conference.aspects;
@Aspect
@Component
public class LoggingAspect {
@Pointcut("execution(* com.demo.conference.daoImpl.ConferenceDAOImpl.*(..))")
public void point(){}
@Pointcut("execution(public * *(..))") //this should work for the public pointcut
private void anyPublicOperation() {}
@Before("anyPublicOperation()")
public void log(){
System.out.println("--------------------->Aspect execuetd");
}
}
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:annotation-config/>
<mvc:annotation-driven />
<context:component-scan base-package="com.demo.conference"/>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
</beans>
applicationContext.xml // For AOP related config
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="com.demo.conference.aspects"/>
<aop:aspectj-autoproxy/>
</beans>
web.xml
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.11</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.11</version>
</dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
Firstly i was putting all xml configurations in single file(in dispatcher-servlet.xml), then it was throwing exception NoSuchBeanDefined.
Then i found in some post to declare AOP related config in seperate file. I did so.(If any one can explain the reason behind creating seperate files) Now there is not any exception but Advice is not getting executed.
Updated
package com.demo.conference.daoImpl;
@Component
@Repository
public class ConferenceDAOImpl implements ConferenceDAO {
@Autowired
private HibernateTemplate hibernateTemplate;
/**
* Method to list all the conferences
* @return list of conferences
*/
public List<Conference> listConference() {
System.out.println("***ConferenceDAOImpl : listConference");
System.out.println("Before fetching conferences");
List<Conference> conferenceList = hibernateTemplate.find("from "+ Conference.class.getName());
return conferenceList;
}
}
Upvotes: 1
Views: 825
Reputation: 52368
In dispatcher-servlet.xml
change the component scan to com.demo.conference.serviceControllers
and in applicationContext.xml
change the component scan to com.demo.conference
.
HibernateTemplate
and other beans which are not web related shouldn't be placed in dispatcher-servlet.xml
. These should be in applicationContext.xml
. In dispatcher-servlet.xml
you should have controllers, view resolvers and other beans related to web part only. Move any other beans to applicationContext.xml
and configure the component-scans as I mentioned: in dispatcher-servlet.xml
use com.demo.conference.serviceControllers
, in applicationContext.xml
use com.demo.conference
.
The story is like this: beans in dispatcher-servlet.xml
form an application context which has as a parent the application context formed by beans in applicationContext.xml
. When a bean is needed by something in dispatcher-servlet context it is searched in the containing context, if it's not found it is searched in parent contexts. So, every bean defined in applicationContext.xm
l should be easily accessible by beans in dispatcher-servlet context. But not vice-versa. Beans in applicationContext cannot access beans in dispatcher-servlet.
Also, use @Autowired
with the interfaces, not the concrete class: @Autowired private ConferenceDAO dao;
and @Autowired private ConferenceService service;
and restrict the range of your pointcut (use point() instead and comment anyPublicOperation())! Beans like HibernateTemplate are advised, as well, and Spring is creating a proxy for it. If you are injecting HibernateTemplate
which is a concrete class in your own classes, the proxy which is created is a JDK proxy (which implements an interface) whereas @Autowired
expects an instance of HibernateTemplate
.
Upvotes: 2