Вот, пожалуй, продолжу досаждать вам (: Надеюсь, мой монолог кто-нить да прервёт. Проблема, как я писал выше, была решена. Нет вопросов, если нам нужно нацепить 1 из 4 advice на стратсовский экшн. Но мне не удаётся повесить его на метод, вызываемый из экшена. Звучит как-то странно, но так оно и есть, убил уже пару часов. Вот мой простенький тестовый (но нерабочий) пример:
есть 2 jsp: one.jsp, two.jsp. Есть экшн для перехода от первой ко второй. struts-config.xml:| Код | <struts-config> <action-mappings> <action input="/one.jsp" path="/one2two" type="action.One2twoAction" validate="false"> <forward name="go" path="/two.jsp" /> </action> </action-mappings>
<message-resources parameter="ApplicationResources" />
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextConfigLocation" value="/WEB-INF/classes/applicationContext.xml" /> </plug-in> </struts-config>
|
Реализация экшена проста: вызываю метод say() класс logic.Logic (на этот метод я и пытаюсь повесить interceptor). Там просто создаю объект Logic и заодно создаю с помощью BeanFactory
| Код | package action; import ...
public class One2twoAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { Logic logic1 = new Logic(); BeanFactory bf = new ClassPathXmlApplicationContext("applicationContext.xml"); Logic logic2 = (Logic) bf.getBean("oldLogic"); logic1.say(); logic2.say(); return mapping.findForward("go"); } }
|
Ниже код класса Logic и его интерфейса ILogic:
| Код | //interface package logic;
public interface ILogic{ public void say(); }
//class package logic;
public class Logic implements ILogic{ public void say(){ System.out.println("Logic.say"); } }
|
Ниже код applicationContext.xml, где конфигурируются advice'ы. Пытаюсь повесить before, after и arround advice как и использованием точек входа (pointcut), так и без них
| Код | <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans> <bean id="oldLogic" class="logic.Logic" /> <bean id="adviceAround" class="logic.Advice" /> <bean id="adviceBefore" class="logic.AdviceBefore" /> <bean id="adviceAfter" class="logic.AdviceAfter" />
<bean id="adviceBeforePointcut" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="mappedName"> <value>*</value> </property> <property name="advice"> <ref bean="adviceBefore" /> </property> </bean>
<bean id="adviceAroundRegExp" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="patterns"> <list> <!-- От отчаяния пытаюсь и так и эдак --> <value>.*say.*</value> <value>.*</value> <value>*</value> <value>say*</value> </list> </property> <property name="advice"> <ref bean="adviceAround" /> </property> </bean>
<bean id="adviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>logic.ILogic</value> </property> <property name="interceptorNames"> <list> <value>adviceAroundRegExp</value> <value>adviceBeforePointcut</value> <value>adviceAfter</value> </list> </property> <property name="target"> <ref bean="oldLogic" /> </property> </bean> </beans>
|
Реализация advice'ов тоже незамысловата: они там чё-нить выводят на консоль. Для полноты картины вот их код:
| Код | // class Advice package logic; import ... public class Advice implements MethodInterceptor {
public Object invoke(MethodInvocation arg0) throws Throwable { System.out.println("around"); return arg0.proceed(); } }
// class AdviceAfter package logic; import ... public class AdviceAfter implements AfterReturningAdvice{
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable { System.out.println("after"); } }
// class AdviceBefore package logic; import ... public class AdviceBefore implements MethodBeforeAdvice {
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable { System.out.println("before"); } }
|
В результате при переходе с первой страницы на вторую в экшене должен вызываться не метод say(), а выполняться adive's. Но на практике ... вывод на консоль:
В чём моя ошибка, вроде делал всё по шпаргалке Spring in action. Для полноты картины в web.xml добавил:
| Код | <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/classes/applicationContext.xml </param-value> </context-param>
|
Вот такая вот телега-вопрос |