一直就用spring的IOC,遗憾spring的另一重要组成部分AOP却没用过,所以近几天抽空研究了下AOP,学了些东西,在这里记录下spring2.0的aop配置,以一个简单的记录日志的实例来说明,先介绍下用XMLSchema来配置,下一篇介绍annotation配置,废话不多说,开始吧
先新建个web工程,将spring的包加进去,为方便就把全部的jar包加进去。
先来看个接口,很简单就两个方法
public
interface
Print {
public String print(String name);
public String sleep(String name);
}
public String print(String name);
public String sleep(String name);
}
接下来是实现类
public
class
SystemPrint
implements
Print{
public String print(String name){
String result = " hello " + name;
System.out.println(result);
return result;
}
public String sleep(String name){
String result = name + " is sleep now " ;
System.out.println(result);
return result;
}
}
public String print(String name){
String result = " hello " + name;
System.out.println(result);
return result;
}
public String sleep(String name){
String result = name + " is sleep now " ;
System.out.println(result);
return result;
}
}
下面是所要织入的代码,也就是我们要用来记录日志的
public
class
GetLog {
public void getLog(ProceedingJoinPoint joinpoint) throws Throwable {
String reslut = (String)joinpoint.proceed();
// 这里是记录日志的
System.out.println( " result=== " + reslut);
}
}
public void getLog(ProceedingJoinPoint joinpoint) throws Throwable {
String reslut = (String)joinpoint.proceed();
// 这里是记录日志的
System.out.println( " result=== " + reslut);
}
}
再来看spring配置文件,没有注释的很清楚,可以去网上查查
<?
xml version="1.0" encoding="UTF-8"
?>
< beans xmlns ="http://www.springframework.org/schema/beans"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop ="http://www.springframework.org/schema/aop"
xmlns:tx ="http://www.springframework.org/schema/tx"
xmlns:jee ="http://www.springframework.org/schema/jee"
xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd" >
<!-- 这个bean是作为切面 -->
< bean id ="log" class ="spring2aop.GetLog" ></ bean >
<!--
注意这里:expression="execution(* spring2aop.*.print*(..))"
括号里面第一个*号代表返回值 接下来 spring2aop.*. 是你要切入的代码的大概路径,这里为什么用大概路径来形容呢
因为这里的意思是符合以spring2aop的路径都会作为选择的对象,也不详细介绍,查下就明白了, print*(..)是指
方法名以print开头的都符合,括号里面的 .. 表示参数是随意的都可以。
-->
< aop:config >
< aop:aspect ref ="log" >
< aop:pointcut id ="printMethods" expression ="execution(* spring2aop.*.print*(..))" />
< aop:after-returning method ="getLog" pointcut-ref ="printMethods" returning ="retVal" />
</ aop:aspect >
</ aop:config >
< aop:config >
< aop:aspect ref ="log" >
< aop:pointcut id ="sleepMethods" expression ="execution(* spring2aop.*.sle*(..))" />
< aop:after-returning method ="getLog" pointcut-ref ="sleepMethods" returning ="retVal" />
</ aop:aspect >
</ aop:config >
<!-- 要织入代码的bean -->
< bean id ="print" class ="spring2aop.SystemPrint" ></ bean >
</ beans >
< beans xmlns ="http://www.springframework.org/schema/beans"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop ="http://www.springframework.org/schema/aop"
xmlns:tx ="http://www.springframework.org/schema/tx"
xmlns:jee ="http://www.springframework.org/schema/jee"
xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd" >
<!-- 这个bean是作为切面 -->
< bean id ="log" class ="spring2aop.GetLog" ></ bean >
<!--
注意这里:expression="execution(* spring2aop.*.print*(..))"
括号里面第一个*号代表返回值 接下来 spring2aop.*. 是你要切入的代码的大概路径,这里为什么用大概路径来形容呢
因为这里的意思是符合以spring2aop的路径都会作为选择的对象,也不详细介绍,查下就明白了, print*(..)是指
方法名以print开头的都符合,括号里面的 .. 表示参数是随意的都可以。
-->
< aop:config >
< aop:aspect ref ="log" >
< aop:pointcut id ="printMethods" expression ="execution(* spring2aop.*.print*(..))" />
< aop:after-returning method ="getLog" pointcut-ref ="printMethods" returning ="retVal" />
</ aop:aspect >
</ aop:config >
< aop:config >
< aop:aspect ref ="log" >
< aop:pointcut id ="sleepMethods" expression ="execution(* spring2aop.*.sle*(..))" />
< aop:after-returning method ="getLog" pointcut-ref ="sleepMethods" returning ="retVal" />
</ aop:aspect >
</ aop:config >
<!-- 要织入代码的bean -->
< bean id ="print" class ="spring2aop.SystemPrint" ></ bean >
</ beans >
测试类:
public
class
Test {
/**
* @Description 方法实现功能描述
* @param args
* void
* @throws 抛出异常说明
*/
public static void main(String[] args) {
ApplicationContext act = new ClassPathXmlApplicationContext(
" applicationContext20.xml " );
Print t = (Print)act.getBean( " print " );
t.print( " ding " );
System.out.println( " ----------------- " );
t.sleep( " laoding " );
}
}
/**
* @Description 方法实现功能描述
* @param args
* void
* @throws 抛出异常说明
*/
public static void main(String[] args) {
ApplicationContext act = new ClassPathXmlApplicationContext(
" applicationContext20.xml " );
Print t = (Print)act.getBean( " print " );
t.print( " ding " );
System.out.println( " ----------------- " );
t.sleep( " laoding " );
}
}
运行这个类,得到如下结果:
hello ding
hello ding
result===hello ding
-----------------
laoding is sleep now
laoding is sleep now
result===laoding is sleep now
这里的hello ding 打印了两次,不用担心,这是因为执行到getLog切面类的
String reslut = (String)joinpoint.proceed();这句代码的时候再执行了一次,这句代码是取回
返回结果的,可以设置个断点来测试下好了这里就输出的result就是记录的日志,当然
这里只是个很简单的实现,但是很简单的实现却很容易说清楚原理。