使用注解,aop不在xml里面配置了,而是写到一个java类里面,然后在xml引用并开启AspectJ风格就可以了。
package shuai.spring.study.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class HelloAspectJ {
@Pointcut(value = "execution(* shuai.spring.study.service..*.*(..)) && args(param0,param1)", argNames = "param0,param1")
public void beforePointcut(String param0, String param1) {
};
// 前置通知
@Before(value = "beforePointcut(param0,parm1)", argNames = "param0,parm1")
public void beforeHello(String param0, String parm1) {
System.out.println("===========beforeHello(前置通知)==" + param0 + "==" + parm1);
}
// 后置返回通知
public void afterReturningHello(String param, String param0, String parm1) {
System.out.println("===========afterReturningHello(后置返回通知)==被拦截方法参数为:==" + param0 + "==" + parm1 + "==结果为:==" + param);
}
// 后置异常通知
public void afterThrowingHello(Exception param, String param0, String parm1) {
System.out.println("===========afterThrowingHello(后置异常通知)==被拦截方法参数为:==" + param0 + "==" + parm1 + "==异常为:==" + param);
}
// 后置最终通知
public void afterHello(String param0, String parm1) {
System.out.println("===========afterHello(后置最终通知)==被拦截方法参数为:==" + param0 + "==" + parm1);
}
// 环绕通知
public void aroundHello(ProceedingJoinPoint pjp, String param0, String parm1) throws Throwable {
System.out.println("===========aroundHello(环绕通知)==被拦截方法参数为:==" + param0 + "==" + parm1);
Object retVal = pjp.proceed(new Object[] { "你好", "世界" });
System.out.println("===========aroundHello(环绕通知)==被拦截方法返回值为:==" + retVal);
}
}
在类名加注解:@Aspect,声明一下
写个方法:加上注解:@Pointcut(value = "execution(* shuai.spring.study.service..*.*(..)) && args(param0,param1)", argNames = "param0,param1"),配置哪些方法是要拦截的,可以带参数
其它的就是各种通知的方法了,前置通知是:@Before(value = "beforePointcut(param0,parm1)", argNames = "param0,parm1"),这里的value要与@Pointcut对应
配置xml
<?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" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="iHelloService" class="shuai.spring.study.service.impl.HelloServiceImpl"/>
<aop:aspectj-autoproxy/>
<bean id="helloAspectJ" class="shuai.spring.study.aop.HelloAspectJ"/>
</beans>
要开启aspectj,<aop:aspectj-autoproxy/>
配置一下定义切面的类,<bean id="helloAspectJ" class="shuai.spring.study.aop.HelloAspectJ"/>,就是一个普通的bean
测试一下
接口
package shuai.spring.study.service;
public interface IHelloService {
public void sayHello();
public void sayHello(String param0, String param1);
public String returnHello(String param0, String param1);
}
实现
package shuai.spring.study.service.impl;
import shuai.spring.study.Info;
import shuai.spring.study.service.IHelloService;
public class HelloServiceImpl implements IHelloService {
@Override
public void sayHello() {
System.out.println("============Hello World!");
}
@Override
public void sayHello(String param0, String param1) {
System.out.println("两个参数:" + param0 + "和" + param1);
}
@Override
public String returnHello(String param0, String param1) {
System.out.println("返回前输出,两个参数:" + param0 + "和" + param1);
return Info.info(param0, param1);
}
}
随便定义一个输出的类Info
package shuai.spring.study;
public class Info {
public static String info() {
System.out.println("返回时输出:hello world 1");
return "返回值:hello world 1";
}
public static String info(String param0, String param1) {
System.out.println("返回时输出:" + param0 + "," + param1);
return "返回值为:" + param0 + "," + param1;
}
}
测试类
package shuai.spring.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import shuai.spring.study.service.IHelloService;
public class HelloTest {
@Test
public void testHelloWorld() {
@SuppressWarnings("resource")
ApplicationContext context = new ClassPathXmlApplicationContext("HelloWorld.xml");
IHelloService iHelloService = context.getBean("iHelloService", IHelloService.class);
iHelloService.returnHello("hello", "world");
}
}
测试结果:
===========beforeHello(前置通知)==hello==world
返回前输出,两个参数:hello和world
返回时输出:hello,world
再定义一个后置返回通知,@AfterReturning
修改通知类的一个方法
// 后置返回通知
@AfterReturning(value = "execution(* shuai.spring.study.service..*.*(..)) && args(param0,param1)", argNames = "param,param0,param1", returning = "param")
public void afterReturningHello(String param, String param0, String parm1) {
System.out.println("===========afterReturningHello(后置返回通知)==被拦截方法参数为:==" + param0 + "==" + parm1 + "==结果为:==" + param);
}
测试结果:
===========beforeHello(前置通知)==hello==world
返回前输出,两个参数:hello和world
返回时输出:hello,world
===========afterReturningHello(后置返回通知)==被拦截方法参数为:==hello==world==结果为:==返回值为:hello,world
其实每个方法都可以加一个参数JoinPoint joinPoint,貌似只能作为第一参数
修改前置通知
// 前置通知
@Before(value = "beforePointcut(param0,parm1)", argNames = "param0,parm1")
public void beforeHello(JoinPoint joinPoint, String param0, String parm1) {
String methodName = joinPoint.getSignature().getName();
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("The method " + methodName + " begins with " + args);
System.out.println("===========beforeHello(前置通知)==" + param0 + "==" + parm1);
}
测试结果:
The method returnHello begins with [hello, world]
===========beforeHello(前置通知)==hello==world
返回前输出,两个参数:hello和world
返回时输出:hello,world
===========afterReturningHello(后置返回通知)==被拦截方法参数为:==hello==world==结果为:==返回值为:hello,world
其它的看开涛老师的:http://jinnianshilongnian.iteye.com/blog/1420689