欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

AOP后发现原来能注入的变量都没注入,一个很有意思的问题

程序员文章站 2024-03-12 20:45:08
...

今天要给系统增加日志功能,系统使用struts2+spring2.5+hibernate3.0框架开发。

我第一反应就是使用AOP,又快又方便。

我这么修改:

1、修改spring配置文件,增加如下内容:

<aop:aspectj-autoproxy/>
<bean id="actionTrack" class="com.sa.ActionTrack" />

 配置文件原来就已经配置了

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 ..."

  所以就免了。

而actionTrack就是我的日志跟踪类,如下:

@Aspect
public class ActionTrack
{
	@Pointcut("execution(* com.xx..*.*Action.*(..))")
	public void actionPointCut(){};

	
	public Object roundLog(ProceedingJoinPoint pjp) throws Throwable
	{
		Signature sig = pjp.getSignature();
		Object obj = pjp.getTarget();
		String str="calling "+obj.getClass().toString() + "  " + sig.getName();
		System.out.println(str);
		Object retVal = pjp.proceed();
		str="calling over  "+obj.getClass().toString() + "  " + sig.getName();
		return retVal;
	}
	
	@Before("target(com.xx.struts2.action.BaseAction)")
	public void beforeLog(JoinPoint jp) 
	{
		Signature sig = jp.getSignature();
		Object obj = jp.getTarget();
		String str="before calling "+obj.getClass().toString() + "  " + sig.getName();
		System.out.println(str);
		//Object retVal = pjp.proceed();
		//str="calling over  "+obj.getClass().toString() + "  " + sig.getName();
		//return retVal;
	}
	
	@AfterThrowing(pointcut="target(com.xx.struts2.action.BaseAction) ",throwing="ex")
	public void exceptionLog(Exception ex)
	{
		ex.printStackTrace();
	}
}
 

 然后启动tomcat,登录系统,查看日志,发现打印before calling xxxx "  " xxx后就打印出异常,大概如下:

java.lang.NullPointerException
 at com.xx.xxAction.list(GridProcessorAction.java:161)
 at com.xx.xxAction$$FastClassByCGLIB$$21cf86ce.invoke(<generated>)

跟踪进去list方法发现如下代码

xxService.query(xxx);

中xxService是空指针,xxService是成员变量,自动注入的,如下:

 @Resource(name="xxService")
 private xxServiceImpl xxService;

其中xxServiceImpl是xxService的接口。

 

明明声明了自动注入,不应该为空啊,而且我把切面去了,就一切正常,真莫名其妙。

后来我发现这个xxAction的类开头并没有注解声明

@Repository("login") @Scope("prototype")

但是在没用切面前,它的属性却能正确注入,真的怪了。于是跟踪struts的配置文件,发现struts是这么写的

<action name="Login_*" class="com.xx.xxAction" method="{1}">
            <result name="input">xx</result>
            <result>xx</result>
        </action>

 

按理说struts+spring时,这个class应该是写spring组件的ID,但这里却写具体类。从目前的配置看,也就是struts的所有action都不有Spring托管,但是Spring却能注入变量,真神奇了。

我把上面的配置改成

<action name="Login_*" class="login" method="{1}">
            <result name="input">xxx</result>
            <result>xx</result>
        </action>

 

然后在xxAction的类开头加上注解,如下

@Repository("login") @Scope("prototype")
xxAction

 

然后再运行切面,一切正常,问题解决了。

 

但遗留下疑问,struts+spring是struts的action明明没有被spring托管,怎么会自动注入变量的。这个也是系统的一个设计缺陷

 

 

 

 

相关标签: aop di