Struts 2 action method intercepting using Spring A

2019-06-06 09:22发布

问题:

I'm trying to intercept the Struts2 Action class's methods to print the method start and method end indication statement using Spring AOP.

The fact is , my Struts2 actions instance are also Spring beans (Struts2 and Spring integration done as per the url: http://www.mkyong.com/struts2/struts-2-spring-integration-example/). AOP configurations is as below:

<bean id="testAdviceBean" class="com.tcs.oss.plugins.SimpleAdvice"> 
</bean>

<aop:config>
  <aop:aspect ref="testAdviceBean" order="200">

     <aop:pointcut id="testPoint2"
           expression="execution(java.lang.String com.test..DeviceAction.*(..))"
     /> 

     <aop:around pointcut-ref="testPoint2" method="loggingAdvice" />  

  </aop:aspect>
</aop:config>

In the advice method loggingAdvice , I'm trying to print the method START and method END statement using the ProceedingJoinPoint API.The advice method is not called at all ... instead it's ending up with the error below after going through the struts default interceptor chain ...

But I'm getting the below ERROR TRACE:

09:26:49,093 TRACE [org.springframework.beans.factory.support.DefaultListableBeanFactory] (http-01h3463916-172.20.211.235-8543-5) Ignoring constructor [public org.apache.struts2.dispatcher.ServletDispatcherResult(java.lang.String)] of bean 'org.apache.struts2.dispatcher.ServletDispatcherResult': org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.apache.struts2.dispatcher.ServletDispatcherResult': Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.String]: : No matching bean of type [java.lang.String] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [java.lang.String] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

09:26:49,095 TRACE [org.springframework.beans.factory.support.DefaultListableBeanFactory] (http-01h3463916-172.20.211.235-8543-5) Not autowiring property 'urlHelper' of bean 'org.apache.struts2.dispatcher.ServletDispatcherResult' by name: no matching bean found

09:26:49,100 DEBUG [org.apache.struts2.dispatcher.ServletDispatcherResult] (http-01h3463916-172.20.211.235-8543-5) Forwarding to location /General/error.jsp

If I just remove the above AOP configurations, It's just working fine. What I'm doing wrong ?

回答1:

The advice method is not called because Action class was extending from ActionSupport class which in turn has a interface implementations... So , in this case, A JDK proxy was created for the Action class -- This type of proxy doesn't have any method specific(non-inheritance) to the Action class.

Adding proxy-target-class="true" attribute, in the AOP configuration, made the Spring to generate CGLib(need to add CGLib in the Classpath) based proxy.. which now has the non-inheritance methods too, of the Action class.



回答2:

After a bunch of digging, I think I found the issue (if you're using Spring to help with AOP, even if you're not you're probably going to need a different ObjectFactory), long and short of it is that you need to make sure that the struts ObjectFactory is setup properly:

<constant name="struts.objectFactory" value="org.apache.struts2.spring.StrutsSpringObjectFactory" />
<constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true"/>

or

<constant name="struts.objectFactory" value="spring" />
<constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true"/>

source: http://www.javawebdevelop.com/3294124/