博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Spring开发】—— AOP之方法级拦截
阅读量:6297 次
发布时间:2019-06-22

本文共 4216 字,大约阅读时间需要 14 分钟。

前言:

前面介绍了等概念。这篇讲解一下spring的另一个重点,AOP面向切面编程。

  说道AOP不得不提到几个概念:

  切面:也就是我们自己的一些业务方法。

  通知:用于拦截时出发的操作。

  切点:具体拦截的某个业务点。

  这样说可能还是有点抽象,举个例子,下面是一个纸糊的多面体。

  每个面都是一个业务方法,我们通过刺穿每一个面,都可以进入到内部,这个面就是一个切面

  刺穿的时候会发出声响,这就是一种通知

  而具体从哪个面刺入,这就是一个切入点的选择了。

  这样说,应该能稍微了解一点。

 

  那么下面看一个简单的例子:

  为了便于理清关系,先放上一张相关的类图:

  首先定义个接口

1 public interface IService {2  public void withAop();3  public void withoutAop();4 }

  有了接口,当然需要一个实现类

1 public class TestAOP implements IService { 2  private String name; 3  public void withAop() { 4   System.out.println("with AOP name:"+name); 5  } 6  public void withoutAop() { 7   System.out.println("without AOP name:"+name); 8  } 9  public String getName() {10   return name;11  }12  public void setName(String name) {13   this.name = name;14  }15 }

  这个实现类实现了接口定义的两个方法,下面我们定义几种拦截方式,这些拦截方式通过拦截的位置或者时机不同而不同。

  通常有方法前拦截方法后拦截,以及异常拦截。通过在这些拦截中编写自己的业务处理,可以达到特定的需求。

  方法前拦截,需要实现MethodBeforeAdvice接口,并填写before方法。这样,当拦截到某个方法时,就会在方法执行前执行这个before()方法。

1 public class BeforeAOPInterceptor implements MethodBeforeAdvice{2  public void before(Method method, Object[] args, Object instance)3    throws Throwable {4   System.out.println("before()"+method.getName());5  }6 }

  同理,方法后拦截,也是如此。需要实现AfterReturningAdvice接口。

1 public class AfterAOPInterceptor implements AfterReturningAdvice{2  public void afterReturning(Object value, Method method, Object[] args,3    Object instance) throws Throwable {4   System.out.println("after()"+method.getName());5  }6 }

  以及异常拦截。

1 public class ThrowsAOPInterceptor implements ThrowsAdvice{ 2  public void afterThrowing(Method method,Object[] args,Object instance,AccountException ex) throws Throwable{3   System.out.println("after()"+method.getName()+"throws exception:"+ex);4  }5  public void afterThrowing(NullPointerException ex) throws Throwable{6   System.out.println("throws exception:"+ex);7  }8 }

  接下来就需要配置一下spring的配置文件,把拦截器与切面方法关联起来。

  参考上面的图,可以看到配置文件中的层次关系。

1 
2
6
7
15
16   
17     
18       
19     
20   
21     
22       
.*out.*
23     
24   
25   
26   
27     
28       
29     
30     
31       
32         
.*out.*
33       
34     
35   
36   
37     
38       
39     
40     
41       
42         
.*out.*
43       
44     
45   
46
47   
48     
49       
50         
before
51         
after
52         
exception
53       
54     
55     
56       
57         
58       
59     
60   
61

  ProxyFactoryBean下有两个属性,一个想要拦截的目标类,一个是拦截器。而拦截器又包括两种,主要是因为定位方法的不同而分类。分别是:

  RegexpMethodPointcutAdvisor 通过正则表达式来定位业务方法。

  NameMatchMethodPointcutAdvisor 通过名字来定位业务方法。

  定位到了业务方法,还需要添加响应的拦截器,拦截器就是上面的三种。

  最后看一下测试的方法:

public class TestMain { public static void main(String[] args) {  XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContextAOP.xml"));  IService hello = (IService)factory.getBean("aopService");  hello.withAop();  hello.withoutAop(); }}

  我们上面通过正则表达式定位到所有包含out的方法,其实就是withoutAOP方法。这样当执行withoutAop方法时,会触发拦截器的操作。

  执行结果:

2014-12-4 16:46:58 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions信息: Loading XML bean definitions from class path resource [applicationContextAOP.xml]with AOP name:Hellobefore()withoutAopwithout AOP name:Helloafter()withoutAop

  总结:

  这是通过定义切入点的方式来实现AOP,通过这种编程方式,可以针对业务方法进行包装或者监控

  举个例子,比如有个业务方法想要进行数据的查询,那么可以再这个查询前面获取JDBC连接池的连接,这样就对用户屏蔽掉了复杂的申请过程。而销毁就可以放在方法后拦截函数里。

  再比如,想要监控某个业务方法呗执行了多少次,那么就可以通过这样一种拦截方式,进行信息的统计,计数或者计时!

  妙处多多,还待完善!

  参考:《java web王者归来》《spring实战》《spring权威指南》

本文转自博客园xingoo的博客,原文链接:,如需转载请自行联系原博主。
你可能感兴趣的文章
Enumberable
查看>>
开发者论坛一周精粹(第五十四期) 求购备案服务号1枚!
查看>>
validate表单验证及自定义方法
查看>>
javascript 中出现missing ) after argument list的错误
查看>>
使用Swagger2构建强大的RESTful API文档(2)(二十三)
查看>>
Docker容器启动报WARNING: IPv4 forwarding is disabled. Networking will not work
查看>>
(转)第三方支付参与者
查看>>
程序员修炼之道读后感2
查看>>
DWR实现服务器向客户端推送消息
查看>>
js中forEach的用法
查看>>
Docker之功能汇总
查看>>
!!a标签和button按钮只允许点击一次,防止重复提交
查看>>
(轉貼) Eclipse + CDT + MinGW 安裝方法 (C/C++) (gcc) (g++) (OS) (Windows)
查看>>
还原数据库
查看>>
作业调度框架 Quartz.NET 2.0 beta 发布
查看>>
mysql性能的检查和调优方法
查看>>
项目管理中的导向性
查看>>
Android WebView 学习
查看>>
(转)从给定的文本中,查找其中最长的重复子字符串的问题
查看>>
HDU 2159
查看>>