복붙노트

[SPRING] Annotated 컨트롤러에 대한 Spring AOP 권고

SPRING

Annotated 컨트롤러에 대한 Spring AOP 권고

주석 처리 된 컨트롤러 후에 AOP를 사용하여 일부 처리를 수행하려고합니다. 모든 것이 오류없이 실행되지만 조언은 실행되지 않습니다.

다음은 컨트롤러 코드입니다.

@Controller
public class HomeController {       
    @RequestMapping("/home.fo")
    public String home(ModelMap model) {
        model = new ModelMap();
        return "home";
    }   
}

application-config의 설정

<aop:aspectj-autoproxy/>

<bean id="testAdvice" class="com.test.TestAdvice">
</bean>

<bean id="testAdvisor"
    class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor">
    <property name="advice" ref="testAdvice" />
    <property name="expression" value="execution(* *.home(..))" />
</bean>

실제 조언

public class TestAdvice implements AfterReturningAdvice {

    protected final Log logger = LogFactory.getLog(getClass());

    public void afterReturning(Object returnValue, Method method, Object[] args,
            Object target) throws Throwable {
        logger.info("Called after returning advice!");
    }
}

주석이 달린 컨트롤러에 대한 조언을받을 수 있습니까? 나는 봄 2.5를 사용하고있다.

해결법

  1. ==============================

    1.주석이 달린 컨트롤러에 대한 조언을받을 수 있습니다.

    주석이 달린 컨트롤러에 대한 조언을받을 수 있습니다.

    @Controller 주석이 달린 클래스에서 모든 메소드를 실행 한 후에 조언을 원한다고 가정합니다.

    다음은 그 예입니다.

    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    
    @Aspect
    public class ControllerAspect {
    
        @Pointcut("within(@org.springframework.stereotype.Controller *)")
        public void controllerBean() {}
    
        @Pointcut("execution(* *(..))")
        public void methodPointcut() {}
    
        @AfterReturning("controllerBean() && methodPointcut() ")
        public void afterMethodInControllerClass() {
            System.out.println("after advice..");
        }
    }
    

    Spring AOP를 AspectJ 구문과 함께 사용하려면 다음과 같은 설정 파일이 필요하다.

    <?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:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="
                http://www.springframework.org/schema/aop 
                http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
                http://www.springframework.org/schema/beans 
                http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    
        <bean id="controllerAspect" class="controller.ControllerAspect" />
    
        <aop:aspectj-autoproxy>
            <aop:include name="controllerAspect" />
        </aop:aspectj-autoproxy>
    </beans>
    

    참고 : Spring AOP를 사용하면 Spring 컨테이너가 Spring Bean을 구성하게된다. @Controller 객체가 Spring 빈이 아니라면 AspectJ 직조를 사용해야한다.

  2. ==============================

    2.Repository에 대한 조언이 작동하는 것과 동일한 문제가 있었지만 Controller에 대한 조언은 그렇지 않았습니다. 마지막으로 해결책을 찾았습니다. 즉, AOP 정의가 다른 컨텍스트가 아닌 Servlet 컨텍스트에로드되어 있는지 확인해야합니다.

    Repository에 대한 조언이 작동하는 것과 동일한 문제가 있었지만 Controller에 대한 조언은 그렇지 않았습니다. 마지막으로 해결책을 찾았습니다. 즉, AOP 정의가 다른 컨텍스트가 아닌 Servlet 컨텍스트에로드되어 있는지 확인해야합니다.

    필자의 경우 Spring AOP 정의는 tools-config.xml에 정의되어있다. 여기에서 옮긴 후

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/tools-config.xml</param-value>
    </context-param>
    
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    

    여기로,

    <servlet>
        <servlet-name>petclinic</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/mvc-core-config.xml, classpath:spring/tools-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    

    컨트롤러에 대한 조언이 작동 중입니다.

  3. ==============================

    3.MVC 컨트롤러의 경우, 인터셉터를 사용하여 수행하려는 작업을 수행하는 데 선호되는 방법이 있습니다. http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor를 참조하십시오.

    MVC 컨트롤러의 경우, 인터셉터를 사용하여 수행하려는 작업을 수행하는 데 선호되는 방법이 있습니다. http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor를 참조하십시오.

  4. from https://stackoverflow.com/questions/3310115/spring-aop-advice-on-annotated-controllers by cc-by-sa and MIT license