【Spring开发】—— AOP之方法级拦截
前言:
前面介绍了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之方法级拦截的更多相关文章
- Spring2.5那些事之基于AOP的方法级注解式日志配置
在日常开发中经常需要在代码中加入一些记录用户操作日志的log语句,比如谁在什么时间做了什么操作,等等. 把这些对于开发人员开说无关痛痒的代码写死在业务方法中实在不是一件很舒服的事情,于是AOP应运而生 ...
- Spring的AOP,Struts2的拦截器(Interceptor),以及springMVC的(interceptor)
参考外链:http://www.ibm.com/developerworks/cn/java/j-lo-springaopfilter/ 1.首先,spring的AOP作用范围很广,可以使用Aspec ...
- Spring Security 之方法级的安全管控
默认情况下, Spring Security 并不启用方法级的安全管控. 启用方法级的管控后, 可以针对不同的方法通过注解设置不同的访问条件. Spring Security 支持三种方法级注解, 分 ...
- 使用Spring实现AOP(XML+注解)
一.Spring对AOP的支持 AOP并不是Spring框架特有的,Spring只是支持AOP编程的框架之一,每一个框架对AOP的支持各有特点,有些AOP能够对方法的参数进行拦截,有些AOP对方法进行 ...
- Spring的AOP开发的相关术语
转载自 https://www.cnblogs.com/ltfxy/p/9873618.html SpringAOP简介: AOP思想最早是由AOP联盟组织提出的.Spring使用这种思想最好的框架. ...
- spring cglib实现嵌套方法拦截
使用spring 的拦截器对方法进行拦截,不管是动态代理,还是cglib, 只能拦截到被代理对象的调用方法,对于被调用方法里再调用同一对象里的其他方法就无法拦截到,就是我们说的嵌套拦截,之前文章里提及 ...
- 十一 Spring的AOP开发的相关术语
SpringAOP简介: AOP思想最早是由AOP联盟组织提出的.Spring使用这种思想最好的框架. Spring的AOP有自己实现的方式,但是非常繁琐.AspectJ是一个AOP框架,Spring ...
- Spring3系列10- Spring AOP——Pointcut,Advisor拦截指定方法
Spring3系列10- Spring AOP——Pointcut,Advisor 上一篇的Spring AOP Advice例子中,Class(CustomerService)中的全部method都 ...
- Spring的AOP基于AspectJ的注解方式开发3
上上偏博客介绍了@Aspect,@Before 上篇博客介绍了spring的AOP开发的注解通知类型:@Before,@AfterThrowing,@After,@AfterReturning,@Ar ...
随机推荐
- Python-删除列表中重复元素的方法
1.set()方法 x = [1,2,3,4,5,1] y = list(set(x)) print(y) ``` [1, 2, 3, 4, 5] ``` 2. x = ['b','c','d','b ...
- 从source安装python3.5和pip
按顺序来,先装上python3.5,source安装,命令是 ./configure --prefix="你想要的路径" make make install 然后是安装pip,但是 ...
- 【Python】ACL限制结果检测
最近帮客户做ACL的限制检测,也就是客户对一些站点做了acl限制,只有省内或内网可以访问,然后让我 去验证acl做的是否正确,简单写了个粗略的脚本,分享下,不足之处日后改进(如多线程等),脚本如下: ...
- PIE SDK SFIM融合
1.算法功能简介 SFIM 融合方法全称为基于平滑滤波的亮度变换.基本原理是将高分辨率影像通过低通滤波抑制其高频空间信息保留低频信息,再将原高分辨率影像与通过低通滤波的高分辨率影像进行比值运算,以抵消 ...
- IE9以下程序开发不兼容项目罗列
1. 提前关闭iframe,脚本将不再执行 IE下的js不是缓存在站点系统中,而是缓存在每个单独页面系统中的,当关闭页面,对应引入的脚本将不再执行. 可能出现两种情况: iframe引入的html页面 ...
- PMP 变更的流程
变更的流程: 内部变更: (团队成员提出)团队成员提出的变更,原则上拒绝,如果对客户和自己方都有好处不能拒绝1.内部变更 先分析影响 >> 2. 再提出变更请求 >> 3.变更 ...
- 网页引用Font Awesome图标
问题:最近在IIS上部署web项目的时候,发现浏览器总是报找不到woff.woff2字体的错误.导致浏览器加载字体报404错误,白白消耗了100-200毫秒的加载时间. 原因:因为服务器IIS不认SV ...
- 一些Andoid studio常用的快捷键
常用快捷键 Android Studio是基于IntelliJ IDEA的,我们都知道,IDEA是一个很方便很好用的IDE,其中有许多快捷键,但是太多快捷键我们也记不住. 其实,我们可以记住几个 ...
- innosetup区分正常状态和静默安装状态(通过传递的参数)
命令行运行程序,如: myprogram.exe /abc /bcd 如果我们想获取其中的参数,“/abc”.“/bcd” 1. 直接使用innosetup自带的方法, GetCmdTail() ...
- HDU 1754——I Hate It——————【线段树单点替换、区间求最大值】
I Hate It Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit St ...