The question is published on by Tutorial Guruji team.
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 BeanPostProcessor
s work. And BeanPostProcessor
s 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.