Why my aspect doesn’t work?

I want to print “Hell yeah” in console after @ValidPassword annotation appears. This is how I did.

Annotation:

public @interface ValidPassword {

}

Aspect:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;


@Aspect
public class ValidPasswordAspect {


    @Before("@annotation(ru.tenet.smsc.annotation.ValidPassword)")
    public void myAdvice(){ 
        System.out.println("Hell yeah");
    }



}

xml:

<bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <array>
            <bean class = "org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
            </bean>
        </array>
    </property>
</bean>


    <context:annotation-config />
    <context:component-scan base-package="ru.tenet.smsc" />
    <mvc:resources mapping="/resources/**" location="/resources/" />



    <bean id="saveBatchService" class="ru.tenet.smsc.service.SaveBatchServiceImpl" />   


    <context:component-scan base-package="ru.tenet.smsc" />


    <mvc:annotation-driven />
    <tx:annotation-driven />
    <task:annotation-driven />


<bean id="multipartResolver"  
  class="org.springframework.web.multipart.commons.CommonsMultipartResolver" >

  <property name="maxUploadSize" value="6666666" />
  <property name="maxInMemorySize" value="6666666" />
  </bean>  



<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetClass"><value>org.springframework.security.core.context.SecurityContextHolder</value></property>
    <property name="targetMethod"><value>setStrategyName</value></property>
    <property name="arguments">
        <list>
            <value>MODE_INHERITABLETHREADLOCAL</value>
        </list>
    </property>
</bean>

<bean name="validPasswordAspect" class="ru.tenet.smsc.aop.ValidPasswordAspect" />




    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>



    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation">
            <value>/WEB-INF/db/hibernate.cfg.xml</value>
        </property>
        <property name="configurationClass">
            <value>org.hibernate.cfg.AnnotationConfiguration</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.dialect"> org.hibernate.dialect.OracleDialect</prop>
                <prop key="hibernate.connection.useUnicode">true</prop>
                <prop key="hibernate.connection.characterEncoding">UTF-8</prop>
                <prop key="hibernate.connection.charSet">UTF-8</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>




    <bean id="tilesConfigurer"
        class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/tiles.xml</value>
            </list>
        </property>
    </bean>

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.tiles2.TilesView" />
    </bean>

Usage:

@RequestMapping(value = "/sms/single", method = RequestMethod.GET)
    @ValidPassword
    public String singleSMSPage(Map<String, Object> map,
            @ModelAttribute("singleSMSForm") SingleSMSForm singleSMSForm) {
        map.put("title", "Отправка одного сообщения");
        return "singleSMS";
    }

But no “Hell Yeah” in console. Why?

Answer

aop:aspectj-autoproxy needs to be specified in the same application context where you want it to act on, meaning where your controllers are defined (or auto-detected).

This is a mistake that happens often and the reason it is not working is that the Aspect detection and implementation works as a result of BeanPostProcessors work. And BeanPostProcessors act in the application context they are defined. In a web app, usually there are two such application contexts and many times aop stuff, transactional, autowiring can fail if such behaviors are not defined in the correct application context.

Leave a Reply

Your email address will not be published. Required fields are marked *