public interface UserService { String add(); void delete(); }
@Service("userService") public class UserServiceImpl implements UserService { @Override public String add() { System.out.println("执行add()方法。。。"); return "李四"; } @Override public void delete() { System.out.println("执行delete()方法。。。"); } }
public interface StudentService { String findById(); String findAll(); }
@Service("studentService") public class StudentServiceImpl implements StudentService { @Override public String findById() { System.out.println("执行findById()方法。。。"); // 为了测试异常通知 System.out.println(1/0); return "stu张三1"; } @Override public String findAll() { System.out.println("执行findAll()方法。。。"); return "stu张三2"; } }
切面类 MyAdvices
package com.oy.entity; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; /** * 切面类:通知的集合 * @author oy * @version 1.0 * @date 2018年12月30日 * @time 下午7:25:27 */ @Component @Aspect public class MyAdvices { // 声明公共切入点 @Pointcut("execution(* com.oy.entity.*Impl.*(..))") private void myPointCut() { } @Before(value="execution(* com.oy.entity.*Impl.*(..))") public void myBefore(JoinPoint joinPoint){ //获取目标方法名:joinPoint.getSignature().getName() System.out.println("前置通知 ,目标方法名为:" + joinPoint.getSignature().getName()); } @AfterReturning(value="myPointCut()", returning="ret") // 将切入点的返回值ret传递给通知 public void myAfterReturning(JoinPoint joinPoint, Object ret){ System.out.println("后置通知 ,目标方法名为: " + joinPoint.getSignature().getName() + " , 返回值为-->" + ret); } @Around(value="myPointCut()") public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println("环绕通知,前增强代码。。。"); //手动执行目标方法 Object obj = joinPoint.proceed(); System.out.println("环绕通知,后增强代码。。。"); return obj; } @AfterThrowing(value="myPointCut()", throwing="e") // 将切入点的异常对象e传递给通知 public void myAfterThrowing(JoinPoint joinPoint, Throwable e){ System.out.println("=============执行抛出异常后的增强代码 start============="); System.out.println("抛出异常通知 ,异常信息: " + e.getMessage()); System.out.println("=============执行抛出异常后的增强代码 end============="); } @After(value="myPointCut()") public void myAfter(JoinPoint joinPoint){ System.out.println("最终通知:我是finally里面的代码。。。即使发生异常我也要执行。。。"); } }
beans.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:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 组件扫描 --> <context:component-scan base-package="com.oy.entity"/> <!-- 声明aop注解生效 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
测试类
package com.oy.test; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.oy.entity.StudentService; import com.oy.entity.UserService; /** * Spring AspectJ编程 * * @author oy * @version 1.0 * @date 2018年12月30日 * @time 上午10:01:18 */ public class UserServiceProxyTest { ClassPathXmlApplicationContext ctx = null; @Before public void before() { ctx = new ClassPathXmlApplicationContext("beans.xml"); } @After public void after() { ctx.close(); } /* * 测试结果: 环绕通知,前增强代码。。。 前置通知 ,目标方法名为:add 执行add()方法。。。 环绕通知,后增强代码。。。 最终通知:我是finally里面的代码。。。即使发生异常我也要执行。。。 后置通知 ,目标方法名为: add , 返回值为-->李四 ================================ 环绕通知,前增强代码。。。 前置通知 ,目标方法名为:delete 执行delete()方法。。。 环绕通知,后增强代码。。。 最终通知:我是finally里面的代码。。。即使发生异常我也要执行。。。 后置通知 ,目标方法名为: delete , 返回值为-->null */ @Test public void test1() { // getBean("目标类userServiceImpl的id"),从spring容器获得目标类,如果配置了aop,spring将自动生成代理 UserService userService = (UserService)ctx.getBean("userService"); userService.add(); System.out.println("================================"); userService.delete(); } /* * 测试结果: 环绕通知,前增强代码。。。 前置通知 ,目标方法名为:findById 执行findById()方法。。。 最终通知:我是finally里面的代码。。。即使发生异常我也要执行。。。 =============执行抛出异常后的增强代码 start============= 抛出异常通知 ,异常信息: / by zero =============执行抛出异常后的增强代码 end============= */ @Test public void test2() { StudentService stuentService = (StudentService)ctx.getBean("studentService"); stuentService.findById();// 测试异常通知时,这句代码抛出异常,后面代码无法执行。 System.out.println("================================"); stuentService.findAll(); } }
---