问题
I have a Spring 3.2.4 MVC application and I want to use Spring AOP. Hence, I have created a config file with an <aop:aspectj-autoproxy />
.
I also have written an Aspect (adopted to code found in the web):
@Component
@Aspect
public class PerformanceMonitoring {
private static final Logger logger = Logger.getLogger(PerformanceMonitoring.class);
public PerformanceMonitoring() {
System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++");
}
// @Around("execution(* com.silabs.moka.*(..))")
// @Pointcut(value="execution(public * *(..))")
// @Before("execution(* * com.foo.bar.controller.*.*(..))")
@Before("execution(public DefaultClientResponse<UserProfile> com.foo.bar.controller.LoginLogoutController.login(..))")
public void xyz(JoinPoint joinPoint) {
Signature signature = joinPoint.getSignature();
String methodName = signature.getName();
String stuff = signature.toString();
String arguments = Arrays.toString(joinPoint.getArgs());
System.out.println("################################################");
logger.info("Write something in the log... We are just about to call method: "
+ methodName + " with arguments " + arguments + "\nand the full toString: "
+ stuff);
}
}
(I implemented the constructor just to see if the bean gets instantiated during the start of TOMCAT… and it is!)
However, whenever I enter the login method of the LoginLogoutController the xyz method of my Aspect is not executed. Is the expression of my Pointcut wrong?
How can I tell Spring to execute my Advice?
My Controller:
@Controller
@PropertySource("classpath:xxx.properties")
public class LoginLogoutController {
private static final Logger logger = Logger.getLogger(LoginLogoutController.class);
@Inject
protected Environment env;
/**
* Returns a json list of first names.
*
* @param term the beginning part of the first name
* @return json string array of first names
*/
@RequestMapping(value = "/login", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public DefaultClientResponse<UserProfile> login(final @RequestParam String userName, final @RequestParam String passWord, final @RequestParam(required = false) String deviceToken, HttpServletRequest req) {
logger.info("login: " + userName + ", passWord: " + passWord + ", deviceToken: " + deviceToken);
// logger.info("Communicating with host: " + env.getProperty("url.base"));
UserProfile up = null;
up = userProfileService.findUserProfileByNameAndPassword(userName, passWord);
if (up != null) {
logger.info("UserProfile for " + up.getFirstName() + " " + up.getLastName() + " found.");
HttpSession session = req.getSession(true);
logger.info("Created session with ID:[" + session.getId() + "]");
// Set session parameters
session.setMaxInactiveInterval(Integer.valueOf(env.getProperty("xxx.session.timeout")) * 60 * 60);
session.setAttribute("isAuthenticated", true);
session.setAttribute("deviceToken", deviceToken);
session.setAttribute("authInfo", up.getAuthInfo());
session.setAttribute("KundenID", up.getUserProfileId());
...
return new DefaultClientResponse<UserProfile>(session.getId(), 0, "", up);
} else {
return new DefaultClientResponse<UserProfile>(null, 1, String.format("No user for gogin <%1$s> and password <%2$s> registered.", userName, passWord), null);
}
}
}
The aop_config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<aop:aspectj-autoproxy />
</beans:beans>
The appConfig-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.2.xsd">
<mvc:annotation-driven />
<task:annotation-driven/>
<context:component-scan base-package="com.foo.bar">
<context:include-filter type="aspectj" expression="com.foo.bar.aop.PerformanceMonitoring" />
</context:component-scan>
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!--Placeholder configuration-->
<beans:bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<beans:property name="locations">
<beans:list>
<beans:value>classpath:xxx.properties</beans:value>
</beans:list>
</beans:property>
<beans:property name="ignoreUnresolvablePlaceholders" value="true"/>
</beans:bean>
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:xxx_messages" />
<beans:property name="defaultEncoding" value="UTF-8"/>
</beans:bean>
<beans:bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang" />
</beans:bean>
<!-- Declare the Resolver -->
<beans:bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<beans:property name="defaultLocale" value="de"/>
</beans:bean>
<beans:bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<beans:property name="interceptors">
<beans:ref bean="localeChangeInterceptor" />
</beans:property>
</beans:bean>
<beans:bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<beans:property name="contentNegotiationManager">
<beans:bean class="org.springframework.web.accept.ContentNegotiationManager">
<beans:constructor-arg>
<beans:bean class="org.springframework.web.accept.PathExtensionContentNegotiationStrategy">
<beans:constructor-arg>
<beans:map>
<beans:entry key="json">
<util:constant static-field="org.springframework.http.MediaType.APPLICATION_JSON_VALUE" />
</beans:entry>
<beans:entry key="xml">
<util:constant static-field="org.springframework.http.MediaType.APPLICATION_XML_VALUE" />
</beans:entry>
</beans:map>
</beans:constructor-arg>
</beans:bean>
</beans:constructor-arg>
</beans:bean>
</beans:property>
</beans:bean>
<!-- Resolves views selected for rendering by @Controllers to .jsp resources
in the /WEB-INF/views directory -->
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<!--Persistence data source-->
<beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/m12"
p:username="root"
p:password="">
</beans:bean>
<!--Persistence JPA-->
<jpa:repositories base-package="com.foo.bar.repository"/>
<beans:bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<beans:property name="entityManagerFactory"
ref="entityManagerFactory" />
<beans:property name="jpaDialect">
<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</beans:property>
</beans:bean>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />
<beans:bean id="entityManagerFactory"
autowire="default"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="packagesToScan" value="com.foo.bar.repository, com.silabs.moka.domain" />
<beans:property name="jpaVendorAdapter">
<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<beans:property name="generateDdl" value="false" />
<beans:property name="showSql" value="false" />
<beans:property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>
<beans:property name="database" value="MYSQL"/>
</beans:bean>
</beans:property>
<!-- put any ORM specific stuff here -->
<beans:property name="jpaProperties">
<beans:props>
<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<!-- <beans:bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" /> -->
I have split up the large appConfig-context.xml into smaller pieces:
- root-config.xml
- tx-context.xml
- aop-context.xml
- appConfig-context.xml (MVC context for DispatcherServlet)
Although having this in web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/aop-context.xml
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/tx-context.xml
</param-value>
</context-param>
at least the aop-context.xml seems not to be considered. When I import aop-context.xml in appConfig-context.xml using <beans:import resource="../aop-context.xml"/>
I always get a
HTTP Status 404 - /bar/WEB-INF/views/.jsp
type Status report
message /bar/WEB-INF/views/.jsp
from TOMCAT in the browser. description The requested resource is not available.
回答1:
I never succeeded in having both Spring MVC (for my @Controller
classes) and all the other nice AOP stuff (such as @Transactional
) in one class. This might be just the cause here as well, but that’s a guess given we do not see all the setup.
Extended answer (now that config is given):
You have these three for the same context:
<aop:aspectj-autoproxy />
<mvc:annotation-driven />
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />
You should have separate contexts for controllers and everything else. Please have a look at @Service are constructed twice for reference to do it correctly. AOP (and thus transactions) will not work in the context for controllers.
来源:https://stackoverflow.com/questions/19388214/pointcuts-are-not-triggered