04-spring中的aop演示
1 xml配置
1 导包
2 准备对象
package www.test.service; public interface UserService { public abstract void add(); public abstract void delete(); public abstract void update(); public abstract void find(); }
package www.test.service; public class UserServiceImpl implements UserService { @Override //添加用户 public void add() { System.out.println("添加用户"); //int i = 1/0; } @Override //删除用户 public void delete() { System.out.println("删除用户"); } @Override //修改用户 public void update() { System.out.println("修改用户"); } @Override //查找用户 public void find() { System.out.println("查找用户"); } }
3 准备通知
package www.test.d_springaop; import org.aspectj.lang.ProceedingJoinPoint; //通知类 public class MyAdvice { //前置通知 // |-目标方法运行之前调用 //后置通知(如果出现异常不会调用) // |-在目标方法运行之后调用 //环绕通知 // |-在目标方法之前和之后都调用 //异常拦截通知 // |-如果出现异常,就会调用 //后置通知(无论是否出现 异常都会调用) // |-在目标方法运行之后调用 //================================================= //前置通知 public void before(){ System.out.println("这是前置通知"); } //后置通知 public void afterReturning(){ System.out.println("这是后置通知(如果出现异常不会调用)"); } //环绕通知 public Object around( ProceedingJoinPoint pjp) throws Throwable{ System.out.println("这是环绕通知之前的部分"); Object proceed = pjp.proceed(); System.out.println("这是环绕通知之后的部分"); return proceed; } //异常拦截通知 public void afterException(){ System.out.println("出事啦!出现异常了"); } //后置通知 public void after(){ System.out.println("这是后置通知(出现异常也会调用)"); } }
4 配置进行织入,将通知织入目标对象中
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <!-- 准备工作: 导入aop(约束)命名空间 --> <!-- 1.配置目标对象 --> <bean name="userService" class="www.test.service.UserServiceImpl"></bean> <!-- 2.配置通知对象 --> <bean name="myAdvice" class="www.test.d_springaop.MyAdvice"></bean> <!-- 3.配置将通知织入目标对象 --> <aop:config> <!-- 配置切入点 public void www.test.service.UserServiceImpl.add() void www.test.service.UserServiceImpl.add() * www.test.service.UserServiceImpl.add() * www.test.service.UserServiceImpl.*() * www.test.service.UserServiceImpl.*(..) * www.test.service.*ServiceImpl.*(..) * www.test.service..*ServiceImpl.*(..) //会找service下面的子包 --> <aop:pointcut expression="execution(* www.test.service.*ServiceImpl.*(..))" id="pc"/> <aop:aspect ref="myAdvice"> <!-- 指定名为before方法作为前置通知 --> <aop:before method="before" pointcut-ref="pc"/> <!-- 后置 如果出现异常不会调用--> <aop:after-returning method="afterReturning" pointcut-ref="pc"/> <!-- 环绕通知 --> <aop:around method="around" pointcut-ref="pc"/> <!-- 异常拦截通知 --> <aop:after-throwing method="afterException" pointcut-ref="pc"/> <!-- 后置 出现异常也会调用--> <aop:after method="after" pointcut-ref="pc"/> </aop:aspect> </aop:config> </beans>
5 测试
package www.test.d_springaop; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import www.test.service.UserService; //创建容器 @RunWith(SpringJUnit4ClassRunner.class) //指定配置文件的加载位置 @ContextConfiguration("classpath:www/test/d_springaop/applicationContext.xml") public class Demo { // @Resource(name="userService") private UserService us; @Test public void fun1(){ us.add(); } }
2 注解配置
1 导包
2 准备对象
package www.test.service; public interface UserService { public abstract void add(); public abstract void delete(); public abstract void update(); public abstract void find(); }
package www.test.service; public class UserServiceImpl implements UserService { @Override //添加用户 public void add() { System.out.println("添加用户"); //int i = 1/0; } @Override //删除用户 public void delete() { System.out.println("删除用户"); } @Override //修改用户 public void update() { System.out.println("修改用户"); } @Override //查找用户 public void find() { System.out.println("查找用户"); } }
3 准备通知
package www.test.d_springaop; import org.aspectj.lang.ProceedingJoinPoint; //通知类 public class MyAdvice { //前置通知 // |-目标方法运行之前调用 //后置通知(如果出现异常不会调用) // |-在目标方法运行之后调用 //环绕通知 // |-在目标方法之前和之后都调用 //异常拦截通知 // |-如果出现异常,就会调用 //后置通知(无论是否出现 异常都会调用) // |-在目标方法运行之后调用 //================================================= //前置通知 public void before(){ System.out.println("这是前置通知"); } //后置通知 public void afterReturning(){ System.out.println("这是后置通知(如果出现异常不会调用)"); } //环绕通知 public Object around( ProceedingJoinPoint pjp) throws Throwable{ System.out.println("这是环绕通知之前的部分"); Object proceed = pjp.proceed(); System.out.println("这是环绕通知之后的部分"); return proceed; } //异常拦截通知 public void afterException(){ System.out.println("出事啦!出现异常了"); } //后置通知 public void after(){ System.out.println("这是后置通知(出现异常也会调用)"); } }
4 配置进行织入,将通知织入目标对象中
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <!-- 准备工作: 导入aop(约束)命名空间 --> <!-- 1.配置目标对象 --> <bean name="userService" class="www.test.service.UserServiceImpl"></bean> <!-- 2.配置通知对象 --> <bean name="myAdvice" class="www.test.e_annotationaop.MyAdvice"></bean> <!-- 3.开启使用注解完成织入 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
package www.test.e_annotationaop; 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; //通知类 @Aspect //表示该类是一个通知类 public class MyAdvice { //前置通知 // |-目标方法运行之前调用 //后置通知(如果出现异常不会调用) // |-在目标方法运行之后调用 //环绕通知 // |-在目标方法之前和之后都调用 //异常拦截通知 // |-如果出现异常,就会调用 //后置通知(无论是否出现 异常都会调用) // |-在目标方法运行之后调用 //================================================= /*//前置通知 @Before("execution(* www.test.service..*ServiceImpl.*(..))") public void before(){ System.out.println("这是前置通知"); } //后置通知 @AfterReturning("execution(* www.test.service..*ServiceImpl.*(..))") public void afterReturning(){ System.out.println("这是后置通知(如果出现异常不会调用)"); } //环绕通知 @Around("execution(* www.test.service..*ServiceImpl.*(..))") public Object around( ProceedingJoinPoint pjp) throws Throwable{ System.out.println("这是环绕通知之前的部分"); Object proceed = pjp.proceed(); System.out.println("这是环绕通知之后的部分"); return proceed; } //异常拦截通知 @AfterThrowing("execution(* www.test.service..*ServiceImpl.*(..))") public void afterException(){ System.out.println("出事啦!出现异常了"); } //后置通知 @After("execution(* www.test.service..*ServiceImpl.*(..))") public void after(){ System.out.println("这是后置通知(出现异常也会调用)"); }*/ @Pointcut("execution(* www.test.service..*ServiceImpl.*(..))") public void pc(){}; //前置通知 @Before("MyAdvice.pc()") public void before(){ System.out.println("这是前置通知"); } //后置通知 @AfterReturning("MyAdvice.pc())") public void afterReturning(){ System.out.println("这是后置通知(如果出现异常不会调用)"); } //环绕通知 @Around("MyAdvice.pc()") public Object around( ProceedingJoinPoint pjp) throws Throwable{ System.out.println("这是环绕通知之前的部分"); Object proceed = pjp.proceed(); System.out.println("这是环绕通知之后的部分"); return proceed; } //异常拦截通知 @AfterThrowing("MyAdvice.pc()") public void afterException(){ System.out.println("出事啦!出现异常了"); } //后置通知 @After("MyAdvice.pc()") public void after(){ System.out.println("这是后置通知(出现异常也会调用)"); } }
5 测试
package www.test.e_annotationaop; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import www.test.service.UserService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:www/test/e_annotationaop/applicationContext.xml") public class Demo { @Resource(name="userService") private UserService us; @Test public void fun1(){ us.find(); } }