上一篇文章介绍了下Spring中的AOP xml配置方式。想了解的同学可以点击这里查看。
这次写一下标签形式。
<aop:aspectj-autoproxy />
首先要在spring配置文件中加入上面的标签,类似于
<context:annotation-config />
自动扫面相关的标签。
切面类:
package com.du;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
public class TimeHandler {
@Before("execution(* com.du.HelloWorld.*(..))")
public void sayTime(){
System.out.println(""+System.currentTimeMillis());
}
@After("execution(* com.du.HelloWorld.*(..))")
public void after(){
System.out.println("after");
}
}
还是上一篇中的切面类,我的bean还是在配置文件中配置的,并未用标签配置,如果你没有在spring配置文件中配置此切面类,请加上@Component标签。
接下来介绍around,即为环绕增强,可以理解为包含了before和after。
Test类来模拟事务
package com.du;
public class Test {
public void say(String s){
System.out.println(s);
}
}
TimeHandler切面类中新增around方法:
package com.du;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class TimeHandler {
@Before("execution(* com.du.HelloWorld.*(..))")
public void sayTime() {
System.out.println("" + System.currentTimeMillis());
}
@After("execution(* com.du.HelloWorld.*(..))")
public void after() {
System.out.println("after");
}
@Around("execution(* com.du.Test.*(..))")
public void around(ProceedingJoinPoint pjp) throws Throwable {
Object[] objs = pjp.getArgs();
if (objs[0] instanceof String) {
String s = (String) objs[0];
System.out.println("拦截到方法的第一个参数为:" + s);
// 将要执行方法的第一个参数修改为"hehe"
objs[0] = "hehe";
}
// 将修改后的参数传回方法,开始执行方法。
pjp.proceed(objs);
System.out.println("拦截到的方法执行完成");
}
}
main方法如下,此处传入的参数为"haha":
package com.du;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Show {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("appliacationcontext.xml");
Test test = (Test) ac.getBean("testaop");
test.say("haha");
}
}
运行结果如下:
扫描二维码关注公众号,回复:
1852937 查看本文章
可以看到修改了say方法的参数。拦截一词用的不准确,请忽略掉。
除此之外,还可以修改方法的返回值
package com.du;
public class Test {
public void say(String s){
System.out.println(s);
}
public int get(int i){
return i;
}
}
TimeHandler 类中修改后的around方法:
@Around("execution(* com.du.Test.*(..))")
public int around(ProceedingJoinPoint pjp) throws Throwable {
Object[] objs = pjp.getArgs();
int i = (Integer) pjp.proceed(objs);
System.out.println("原方法运行结果为" + i);
return i+1;
}
main方法:
package com.du;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Show {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("appliacationcontext.xml");
Test test = (Test) ac.getBean("testaop");
int i = test.get(0);
System.out.println("" + i);
}
}
运行结果: