突然想利用spring aop 实现 插入日志功能,于是编写了代码.在编码过程中碰到了些问题,通过自己找资料解决了,现将其记录下来,方便以后查询.
1 先将aop配置贴上,其余的spring与struts2整合相信各位已清楚。这里就不在多余贴出 spring aop 配置java 代码 注 注释的注解是基于零配置运行的,spring可通过xml配置文件和注解的实现功能,现将注解注视启用的是xml格式<aop:config> <!-- 切入点 --> <aop:pointcut expression="execution(* com.xuyw.action.*.*(..))" id="myPointcut" /> <!-- 切面: 将哪个对象中的哪个方法,织入到哪个切入点 --> <aop:aspect id="dd" ref="logService"> <!-- 前置通知 --> <aop:before method="before" pointcut-ref="myPointcut" /> <aop:after method="after" pointcut-ref="myPointcut" /> <aop:after-returning method="afterAndReturn" returning="returnObj" pointcut-ref="myPointcut"/> </aop:aspect> </aop:config>
package com.xuyw.log; import org.apache.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; //@Aspect // 该注解标示该类为切面类 //@Component // 注入依赖 public class LogService { private Logger logger = Logger.getLogger(this.getClass()); // @Before(value = "execution (* com.xuyw.action..*.*(..))") public void before(JoinPoint point) { // 此方法返回的是一个数组,数组中包括request以及ActionCofig等类对象 Object[] args = point.getArgs(); logger.info("目标参数列表:"); if (args != null) { for (Object obj : args) { logger.info(obj + ","); } } } public void after() { logger.info("-->调用完毕"); } // 有参并有返回值的方法 public void afterAndReturn(JoinPoint point, Object returnObj) { /* String toString(); //连接点所在位置的相关信息 03. String toShortString(); //连接点所在位置的简短相关信息 04. String toLongString(); //连接点所在位置的全部相关信息 05. Object getThis(); //返回AOP代理对象 06. Object getTarget(); //返回目标对象 07. Object[] getArgs(); //返回被通知方法参数列表 08. Signature getSignature(); //返回当前连接点签名 09. SourceLocation getSourceLocation();//返回连接点方法所在类文件中的位置 10. String getKind(); //连接点类型 11. StaticPart getStaticPart(); //返回连接点静态部分 */ Signature signature = point.getSignature(); String method = signature.getName(); Object cls = point.getTarget(); String className = cls.getClass().getName(); logger.info("[methodName:" + method + " className:" + className + "]"); // 此方法返回的是一个数组,数组中包括request以及ActionCofig等类对象 Object[] args = point.getArgs(); logger.info("目标参数列表:"); if (args != null) { for (Object obj : args) { logger.info(obj + ","); } logger.info("执行结果是:" + returnObj); } } }
本以为可以执行的,结果执行后报错. java.lang.NoSuchMethodException: $Proxy9.doLogin() 通过找资料得以解决: 在<aop:config>配置前加上 <aop:config proxy-target-class="true"/> <!-- 强制使用CGLIB代理-->或者struts 的action不继承ActionSupport 如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理。所有该目标类型实现的接口都将被代理。若该目标对象没有实现任何接口,则创建一个CGLIB代理。 如果你希望强制使用CGLIB代理,(例如:希望代理目标对象的所有方法,而不只是实现自接口的方法)那也可以。 当需要使用CGLIB代理和@AspectJ自动代理支持,请按照如下的方式设置 <aop:aspectj-autoproxy> 的 proxy-target-class 属性: <aop:aspectj-autoproxy proxy-target-class="true"/> 而实际使用的过程中才会发现细节问题的差别,The devil is in the detail. JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。
CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类。CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强。
这个问题解决了,随之而来的又是另外一个问题.当你进入action时会发现,spring自动注入action中的属性失效,调用是会发生经典的 java.lang.NullPointerException 在struts。xml加上 <!-- 使用spring aop 导致自动注入失败配置该属性-->
<constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true"/> 即可成功。 另外struts与spring的jar不能太老哦 否则配置也没用 http://www.java2s.com/Code/Jar/s/Downloadstruts2springplugin218jar.htm 从这即可下载新版本的jar
spring 整合struts2 使用 aop 碰到的问题
最新推荐文章于 2021-05-24 20:58:09 发布