(15)Spring AOP 注解 AspectJ

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



猜你喜欢

转载自blog.csdn.net/shuair/article/details/78762785