不会触发切入点

时间:2013-10-15 18:14:40

标签: spring-aop pointcut

我有一个Spring 3.2.4 MVC应用程序,我想使用Spring AOP。因此,我创建了一个带有<aop:aspectj-autoproxy />的配置文件。

我也写了一个方面(采用网络上的代码):

@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);
    }
}

(我实现了构造函数只是为了看看bean是否在TOMCAT开始时实例化了...... 并且它是!

但是,每当我输入LoginLogoutController的login方法时,我的Aspect的xyz方法都不会被执行。我的Pointcut表达式错了吗?

我如何告诉Spring执行我的建议?

我的控制器:

@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);
    }
}
}

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>

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" /> -->


我已将大型appConfig-context.xml拆分为更小的部分:

  1. 根-config.xml中
  2. TX-context.xml中
  3. AOP-context.xml中
  4. appConfig-context.xml(DispatcherServlet的MVC上下文)
  5. 虽然在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>
    

    至少不考虑aop-context.xml。当我使用<beans:import resource="../aop-context.xml"/>在appConfig-context.xml中导入aop-context.xml时,我总是得到一个

    HTTP状态404 - /bar/WEB-INF/views/.jsp

    输入状态报告

    消息/bar/WEB-INF/views/.jsp

    来自浏览器中的TOMCAT。 description请求的资源不可用。

1 个答案:

答案 0 :(得分:1)

我从未成功地将Spring MVC(对于我的@Controller类)和所有其他好的AOP内容(例如@Transactional)放在一个类中。这也可能只是原因,但这是猜测,因为我们没有看到所有设置。


扩展答案(现在已提供配置):

你有三个相同的背景:

<aop:aspectj-autoproxy />
<mvc:annotation-driven />
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />

您应该为控制器和其他所有内容设置单独的上下文。请查看@Service are constructed twice以获取正确执行的参考。 AOP(以及事务)在控制器的上下文中不起作用。