AspectJ 学习笔记(一)

软件环境 : Eclipse3.1.1 , AJDT 1.3 , JDK1.4.2 , AspectJ1.5, Struts1.1 , Jetty5.1.6

场景介绍 : workspace中已存在一个java项目,并已部署与Jetty服务器上,这里我采用了一个简单的struts项目,我将演示如何在不改变原有项目的任何代码和配置的基础上,在runtime对struts项目中的一些代码进行拦截。

首先,让我们来新建已个AspectJ项目,名字为AspectJDemo。
AspectJ 学习笔记(一)
在新建project的build path中加入aspectjrt.jar
AspectJ 学习笔记(一)
在Aspectj InPath中加入aspectj代码中需要用到的类及jar,这边我加入了struts的所有jar及StrutsDemo的类编译路径
AspectJ 学习笔记(一)
好,接下来说一下我要拦截的代码片断,在原项目中有一个名叫UserLoginForm的FormBean,希望在runtime的时候,当struts调用这个form中的setUsername方法时拦截代码,相关的struts代码如下:
public class UserLoginForm extends ActionForm {
	private String username;
	private String password;
	
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}	
}

public class UserLoginAction extends Action {
	private final String LOGIN_FAILURE = "failure";
	private final String LOGIN_SUCCESS = "success";
	
	public ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Exception {
	UserLoginForm ulf = (UserLoginForm)form;
	LOG.info("Username:"+ulf.getUsername()+"+Password:"+ulf.getPassword());
		
	return mapping.findForward(LOGIN_FAILURE);
}
}

<html:form action="/login" focus="username" onsubmit="">
<table border="0" width="100%">
<tr>
	<th align="right">Username:</th>
	<td align="left">
	<html:text property="username" size="16" maxlength="18" />
	</td>
</tr>
<tr>
	<th align="right">Password:</th>
	<td align="left">
	<html:password property="password" size="16" maxlength="18" redisplay="false" />
	</td>
</tr>
<tr>
	<td align="right"><html:submit value="Submit" /></td>
	<td align="left"><html:reset /></td>
</tr>
</table>
</html:form>

OK,现在让我们在AspectJDemo中建一个aspect吧
public aspect LoginAspect {
    //建立一个pointcut,这个pointcut对所有方法签名为 
     //public void setUsername(String) 的方法被执行的时候有效
    public pointcut setUsername() :
    	execution (public void setUsername(String));
    //设定拦截位置,在setUsername这个pointcut执行前打印出一段message
    before() : setUsername() {
    	System.out.println("setUsername method has been invoked!!!");
    }
}

接下来,我们需要一些配置文件,首先在StrutsDemo下我们新建一个Jetty5.xml的jetty配置文件,当然这个文件可以拷贝jetty_home/ect/jetty.xml,但必须定义你项目的context
<Call name="addWebApplications">
    <Arg></Arg>
    <Arg>./webapp/</Arg>
    <Arg><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Arg>
    <Arg type="boolean">true</Arg><!--extract WARs-->
    <Arg type="boolean">false</Arg><!-- java 2 compliante class loader -->
  </Call>

然后在AspectJDemo/src/META-INF下建立aop.xml,定义我们的aspect列表
<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
	<aspects>
		<aspect name="lenson.presentation.LoginAspect"/>
	</aspects>
</aspectj>

代码都写完了,我们怎么让我们的setUsername方法在runtime时被拦截呢?我们需要对Jetty服务器启动方式进行一些改变,让我们来新建一个AspectJ Load-Time Weaving Application,非常类似于Java Application
AspectJ 学习笔记(一)
选中StrutsDemo项目,当然我们需要在classpath中加入jetty运行时所需要的jar
AspectJ 学习笔记(一)
然后,我们需要把我们的AspectJDemo放到LTW Aspectpath中
AspectJ 学习笔记(一)
最后,我们需要设定Jetty启动时所需要的arguments
AspectJ 学习笔记(一)
Jetty Home Path
-Djetty.home="D:\development\jetty-5.1.6"

jetty.xml Path (注意我的working directory都在StrutsDemo下)
./jetty5.xml

大功告成,点run运行一下我们的项目吧。访问jsp,提交你的表单
setUsername method has been invoked!!!
21:51:59,211  INFO UserLoginAction:22 - Username:test+Password:test

WOW~~~
希望这片文章对刚起步开始学aspectj的朋友有些帮助。

你可能感兴趣的:(spring,AOP,框架,xml,struts)