前言:

前面介绍了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. docker~环境变量到底怎么用

    docker已经用了两年多了,从开始的简单应用到现在的自动化部署,已经越来越感觉到它的威力,今天把Hitchhiker部署完成后,看到了它与.net core项目有个类似的地方,就是对于多环境部署的时 ...

  2. adb调试安卓

    http://blog.csdn.net/liushida00/article/details/49797239

  3. VS2010中VC++目录和C/C++之间的区别。VC++ Directories和C/C++的区别。

    首先,这是个历史遗留问题,说起来比较复杂.其次,这个问题在微软的MSDN博客上已经专门被说起过了,英文好的请直接移步到原文:<VC++ Directories>.另外,stack over ...

  4. CentOS 下 安装 nginx

    1.准备 安装 nginx 之前,需要确认是否安装了 GCC,PCRE, zlib, OpenSSL 等. 如未安装,则先安装这些插件 # yum install -y gcc # yum insta ...

  5. Linux VFS机制简析(二)

    Linux VFS机制简析(二) 接上一篇Linux VFS机制简析(一),本篇继续介绍有关Address space和address operations.file和file operations. ...

  6. 一个不错的架构图:基于SpringCloud的微服务项目

    https://github.com/hanlin5566/HJ-MicroService

  7. [转]C# - JSON详解

    本文转自:http://www.cnblogs.com/QLJ1314/p/3862583.html 最近在做微信开发时用到了一些json的问题,就是把微信返回回来的一些json数据做一些处理,但是之 ...

  8. jeecg308 <t:authFilter />标签失效的问题

    <%--该标签放到body末尾会无效,估计是js冲突,放到body前好用--%><t:authFilter /> <body></body>

  9. 通过学生-课程关系表,熟悉hive语句

    通过学生-课程关系表,熟悉hive语句 1.在hive中创建以下三个表. create table  student(Sno int,Sname string,Sex string,Sage int, ...

  10. HDU 5215 Cycle(dfs判环)

    题意 题目链接 \(T\)组数据,给出\(n\)个点\(m\)条边的无向图,问是否存在一个奇环/偶环 Sol 奇环比较好判断吧,直接判是否是二分图就行了.. 偶环看起来很显然就是如果dfs到一个和他颜 ...