前言:

前面介绍了Spring的核心模块以及相关的依赖注入等概念。这篇讲解一下spring的另一个重点,AOP面向切面编程。

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

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

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

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

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

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

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

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

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

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

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

  首先定义个接口

 public interface IService {
public void withAop();
public void withoutAop();
}

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

 public class TestAOP implements IService {
private String name;
public void withAop() {
System.out.println("with AOP name:"+name);
}
public void withoutAop() {
System.out.println("without AOP name:"+name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

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

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

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

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

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

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

  以及异常拦截。

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

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

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

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- 通过名字匹配 -->
<!--
  <bean id="before" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
    <property name="advice">
      <bean class="com.test.pointcut.beforeAOP"></bean>
    </property>
    <property name="mappedName" value="withoutAop"></property>
  </bean>
-->
<!-- 通过正则表达式 匹配 -->
  <bean id="before" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    <property name="advice">
      <bean class="com.test.pointcut.BeforeAOPInterceptor"></bean>
    </property>
  <property name="patterns">
    <list>
      <value>.*out.*</value>
    </list>
  </property>
  </bean>
  <bean id="after" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    <property name="advice">
      <bean class="com.test.pointcut.AfterAOPInterceptor"></bean>
    </property>
    <property name="patterns">
      <list>
        <value>.*out.*</value>
      </list>
    </property>
  </bean>
  <bean id="exception" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    <property name="advice">
      <bean class="com.test.pointcut.ThrowsAOPInterceptor"></bean>
    </property>
    <property name="patterns">
      <list>
        <value>.*out.*</value>
      </list>
    </property>
  </bean>
<!-- -->
  <bean id="aopService" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="interceptorNames">
      <list>
        <value>before</value>
        <value>after</value>
        <value>exception</value>
      </list>
    </property>
    <property name="target">
      <bean class="com.test.pointcut.TestAOP">
        <property name="name" value="Hello"></property>
      </bean>
    </property>
  </bean>
</beans>

  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:Hello
before()withoutAop
without AOP name:Hello
after()withoutAop

  总结:

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

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

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

  妙处多多,还待完善!

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

【Spring开发】—— AOP之方法级拦截的更多相关文章

  1. Spring2.5那些事之基于AOP的方法级注解式日志配置

    在日常开发中经常需要在代码中加入一些记录用户操作日志的log语句,比如谁在什么时间做了什么操作,等等. 把这些对于开发人员开说无关痛痒的代码写死在业务方法中实在不是一件很舒服的事情,于是AOP应运而生 ...

  2. Spring的AOP,Struts2的拦截器(Interceptor),以及springMVC的(interceptor)

    参考外链:http://www.ibm.com/developerworks/cn/java/j-lo-springaopfilter/ 1.首先,spring的AOP作用范围很广,可以使用Aspec ...

  3. Spring Security 之方法级的安全管控

    默认情况下, Spring Security 并不启用方法级的安全管控. 启用方法级的管控后, 可以针对不同的方法通过注解设置不同的访问条件. Spring Security 支持三种方法级注解, 分 ...

  4. 使用Spring实现AOP(XML+注解)

    一.Spring对AOP的支持 AOP并不是Spring框架特有的,Spring只是支持AOP编程的框架之一,每一个框架对AOP的支持各有特点,有些AOP能够对方法的参数进行拦截,有些AOP对方法进行 ...

  5. Spring的AOP开发的相关术语

    转载自 https://www.cnblogs.com/ltfxy/p/9873618.html SpringAOP简介: AOP思想最早是由AOP联盟组织提出的.Spring使用这种思想最好的框架. ...

  6. spring cglib实现嵌套方法拦截

    使用spring 的拦截器对方法进行拦截,不管是动态代理,还是cglib, 只能拦截到被代理对象的调用方法,对于被调用方法里再调用同一对象里的其他方法就无法拦截到,就是我们说的嵌套拦截,之前文章里提及 ...

  7. 十一 Spring的AOP开发的相关术语

    SpringAOP简介: AOP思想最早是由AOP联盟组织提出的.Spring使用这种思想最好的框架. Spring的AOP有自己实现的方式,但是非常繁琐.AspectJ是一个AOP框架,Spring ...

  8. Spring3系列10- Spring AOP——Pointcut,Advisor拦截指定方法

    Spring3系列10- Spring AOP——Pointcut,Advisor 上一篇的Spring AOP Advice例子中,Class(CustomerService)中的全部method都 ...

  9. Spring的AOP基于AspectJ的注解方式开发3

    上上偏博客介绍了@Aspect,@Before 上篇博客介绍了spring的AOP开发的注解通知类型:@Before,@AfterThrowing,@After,@AfterReturning,@Ar ...

随机推荐

  1. PIE SDK波段合成

    1.算法功能简介 波段合成功能主要用于将多幅图像合并为一个新的多波段图像(即波段的叠加打包,构建一个新的多波段文件),从而可根据不同的用途选择不同波长范围内的波段合成 RGB 彩色图像. PIE支持算 ...

  2. windows下dubbo-admin的安装

    本来以为十分钟就能搞定的东西结果搞了一个小时,也是菜到抠脚,赶紧记录一下. 下载dubbo源码,下载地址:https://download.csdn.net/download/huangzhang_/ ...

  3. Python 函数运行时更新

    Python 动态修改(运行时更新) 特性 实现函数运行时动态修改(开发的时候,非线上) 支持协程(tornado等) 兼容 python2, python3 安装 pip install realt ...

  4. 前端测试框架 puppeteer 文档翻译

    puppeteer puppeteer 是一个通过DevTools 协议提供高级API 来控制 chrome,chromium 的 NODE库; puppeteer默认运行在 headless 模式, ...

  5. [转]微信小程序登录逻辑梳理

    本文转自:http://www.jianshu.com/p/d9996cafdb31 官方文档 文档相关地址: 用户登录 获取用户数据 用户数据的签名验证和加解密                   ...

  6. webpack起步

    为什么要使用webpack 很牛逼的样子 https://www.webpackjs.com/comparison/ 基本概念 1. 入口(entry) module.exports = { entr ...

  7. 前端之CSS——CSS选择器

    一.CSS介绍 为什么需要CSS(CSS的作用)? 在没有CSS之前,我们想要修改HTML元素的样式需要为每个HTML元素单独定义样式属性,当HTML内容非常多时,就会定义很多重复的样式属性,并且修改 ...

  8. CRM——销售与客户

    一.销售与客户——表结构 1.客户类型 (1)公共客户(公共资源) 必备条件:没有报名: 在必备条件满足的情况下,满足以下任意条件都是公共客户: 3天没有跟进:15天没有成单. (2)我的客户 原销售 ...

  9. 在MAC上搭建python数据分析开发环境

    最近工作转型到数据开发领域,想在本地搭建一个数据开发环境.自己有三年python开发经验,马上想到使用numpy.scipy.sklearn.pandas搭建一套数据开发环境. ubuntu的环境,百 ...

  10. [原创]vs2012创建的ado.net模型无法实例化的问题

    最近从vs2010升级到vs2012,建立数据模型,发现生成的东西跟以前不一样了,而且也无法实例化使用.百度尝试了n种关键词,终于被我找到解决的方法.在这里记录一下. 1.打开设计器,也就是双击这个 ...