Доброго времени суток! Недавно закрыл одну тему про Spring AOP и начал другую Я все-таки добился работы AOP в Spring-приложении, сконфигурированного аннотациями, только не знаю, насколько корректно мое решение. Я создал простейшее web-приложение с единственной кнопкой на форме, количество нажатий на которую подсчитывается при помощи аспекта и записывается в текстовый файл. Приведу его код: dispatcher-servlet.xml:| Код | <?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"> <aop:aspectj-autoproxy /> <context:component-scan base-package="study.spring" /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" /> </beans>
|
LoginController.java| Код | package study.spring.controllers;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView;
@Controller @RequestMapping("page.htm") public class LoginController implements org.springframework.web.servlet.mvc.Controller { @Override @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}) public ModelAndView handleRequest(HttpServletRequest hsr, HttpServletResponse hsr1) { return new ModelAndView("page"); } }
|
Calc.java (aspect):| Код | package study.spring.form;
import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component;
@Component @Aspect public class Calc { private int count; @Before("execution(* org.springframework.web.servlet.mvc.Controller.handleRequest(..))") public void setCount() { try (BufferedWriter writer = new BufferedWriter(new FileWriter("D://out.txt"))) { writer.write(String.valueOf(count++)); writer.newLine(); } catch (IOException e) { System.err.println(e.getMessage()); } } }
|
page.jsp:| Код | <%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" language="java" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Welcome</title> </head> <body> <form:form action="page.htm" > <input type="submit" title="input" /> </form:form> </body> </html>
|
Вот, в контроллере меня смущает реализация интерфейса org.springframework.web.servlet.mvc.Controller. В одной англоязчыной статье, которую я приводил в другой теме, упоминалось, что "the best thing you can do is to use a poincut like execution(* org.springframework.web.servlet.mvc.AbstractController.handleRequest(..)) because this is the method that is getting called from outside." Ну я так и поступил: сначала создав приложение с xml-конфигурацией, а потом переделал его так, как привел выше. Теперь я бы хотел узнать, не изобрел ли я костыли? Может, есть другое, лучшее решение? А то получается "масло масляное" - и аннотация контроллер и реализуемый интерфейс контроллер! Кроме того, АОП тут может применяться только к одному методу одного интерфейса, что сильно его ограничивает. |