(15)Spring AOP 注解 AspectJ

来源:互联网 发布:淘宝助理顺丰新模板 编辑:程序博客网 时间:2024/06/05 22:35

使用注解,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;@Aspectpublic 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



原创粉丝点击