Spring中关于AOP的实践之Scheme方式实现通知

Posted kaithy-rookie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring中关于AOP的实践之Scheme方式实现通知相关的知识,希望对你有一定的参考价值。

(刚开始写东西,不足之处还请批评指正)

关于AOP的通知编写方式有两种,使用Schema-baesd或者使用AspectJ方式,本篇主要介绍Schema-baesd方式的代码实现。

(注:代码中没有添加任何业务逻辑,只是单纯的输出语句,若读者大人有什么业务逻辑希望本人实现作为参考的可以给我留言)

一. 实现通知方法

1.前置通知需要实现:MethodBeforeAdvice接口,并重写before方法

 1 import java.lang.reflect.Method;
 2 import org.springframework.aop.MethodBeforeAdvice;
 3 
 4 public class BeforAdvice implements MethodBeforeAdvice {
 5 
 6   @Override
 7   public void before(Method method, Object[] objects, Object o) throws Throwable {
 8     System.out.println("准备设备,准备武器弹药,组织救援人员");
 9   }
10 }

其中的几个参数:

1)Method method:切点方法

2)Object[] objects:切点方法参数(可能有多个或者没有)

3)Object o:切点所在类的对象

2.后置通知的实现需要实现:AfterReturningAdvice接口,并重写afterReturning方法

 1 import java.lang.reflect.Method;
 2 import org.springframework.aop.AfterReturningAdvice;
 3 
 4 public class AfterAdvice implements AfterReturningAdvice {
 5 
 6   @Override
 7   public void afterReturning(Object o, Method method, Object[] objects, Object o1)
 8       throws Throwable {
 9     System.out.println("人员已救出,生命状态良好,无生命危险");
10   }
11 }

其中的几个参数解释:

1)Object o:切点方法的返回值

2)Method method:切点方法

3)Object[] onjects:切点方法参数

4)Object o1:切点所在的类的对象

 

3.异常通知的实现需要实现:ThrowsAdice接口,由于ThrowsAdvice接口没有方法可重写,可以自己自定义一个方法,唯一要注意的是方法参数是切点将会抛出的异常名称,如果嫌麻烦可以使用Exception作为方法参数

1 import org.springframework.aop.ThrowsAdvice;
2 
3 public class ErrorAdvice implements ThrowsAdvice {
4   public void afterThrowing(Exception e)throws Throwable{
5     System.out.println("任务执行异常,任务失败");
6 
7   }
8 
9 }

 

4.环绕通知的实现需要实现:MethodInterceptor接口,并重写invoke方法

 1 import org.aopalliance.intercept.MethodInterceptor;
 2 import org.aopalliance.intercept.MethodInvocation;
 3 
 4 public class ArroundAdvice implements MethodInterceptor {
 5 
 6   @Override
 7   public Object invoke(MethodInvocation methodInvocation) throws Throwable {
 8     //前置通知
 9     System.out.println("环绕通知:准备设备,准备武器弹药,组织救援人员");
10     //放行,调用切点方法
11     Object result=methodInvocation.proceed();
12     //后置通知
13     System.out.println("环绕通知:人员已救出,生命状态良好,无生命危险");
14     return result;
15   }
16 }

二. 实现切点所在的类

 1 package com.xkx.pojo;
 2 
 3 public class People {
 4   private int age;
 5   private String name;
 6   private String sexual;
 7 
 8   public int getAge() {
 9     return age;
10   }
11 
12   public void setAge(int age) {
13     this.age = age;
14   }
15 
16   public String getName() {
17     return name;
18   }
19 
20   public void setName(String name) {
21     this.name = name;
22   }
23 
24   public String getSexual() {
25     return sexual;
26   }
27 
28   public void setSexual(String sexual) {
29     this.sexual = sexual;
30   }
31 
32 
33 
34   @Override
35   public String toString() {
36     return this.getAge()+"--"+this.getName()+"--"+this.getSexual();
37   }
38 
39   public People() {
40   }
41 
42   public People(int age, String name, String sexual) {
43     this.age = age;
44     this.name = name;
45     this.sexual = sexual;
46 
47   }
48   public void crraped(){
49     System.out.println(this.getName()+"已被绑架");
50   }
51 
52   public void show(){
53     System.out.println("切点执行:解救"+this.getName()+"任务");
54   }
55 
56  
57   public void covert(){
58     System.out.println("解救成功,召开新闻发布会");
59   }
60 
61 
62 }

 

三. 在Spring的配置文件:applicationContext.xml中进行配置

1.添加aop依赖,可以去spring-framework中的Core technologies中搜索文档,搜索关键字:xmlns:aop

2.添加配置

<?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 ="beforeAdvice" class="com.xkx.adviceDemo.BeforAdvice"></bean>
  <bean id="afterAdvice" class="com.xkx.adviceDemo.AfterAdvice"></bean>
  <bean id="errorAdvice" class="com.xkx.adviceDemo.ErrorAdvice"></bean>
  <bean id="arroundAdvice" class="com.xkx.adviceDemo.ArroundAdvice"></bean>

  <aop:config>
    <aop:pointcut expression="execution(* com.xkx.pojo.People.show())" id="mypeople" ></aop:pointcut>
    <aop:advisor advice-ref="beforeAdvice" pointcut-ref="mypeople"></aop:advisor>
    <aop:advisor advice-ref="afterAdvice" pointcut-ref="mypeople"></aop:advisor>
    <aop:advisor advice-ref="errorAdvice" pointcut-ref="mypeople"></aop:advisor>
    <aop:advisor advice-ref="arroundAdvice" pointcut-ref="mypeople"></aop:advisor>
  </aop:config>

  <bean id ="people" class="com.xkx.pojo.People">
    <constructor-arg index="0" name="age" type="int" value="22"></constructor-arg>
    <constructor-arg index="1" name="name" type="java.lang.String" value="吾先生"></constructor-arg>
    <constructor-arg index="2" name="sexual" type="java.lang.String" value="male"></constructor-arg>
  </bean>
</beans>

四. 测试

 1 package com.xkx.demotest;
 2 
 3 import com.xkx.pojo.People;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 public class Test2 {
 8 
 9   public static void main(String[] args) {
10 
11     ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
12     People people = ac.getBean("people",People.class);
13     people.crraped();
14     people.show();
15     people.covert();
16 
17   }
18 
19 }

 

以上是关于Spring中关于AOP的实践之Scheme方式实现通知的主要内容,如果未能解决你的问题,请参考以下文章

Spring学习4-面向切面(AOP)之schema配置方式

面试中关于Spring AOP和代理模式的那些事

Spring-AOP之工作实践

Spring-AOP之工作实践

Spring入门之AOP实践:@Aspect + @Pointcut + @Before / @Around / @After

Spring之@EnableAspectJAutoProxy开启AOP功能原理