【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 ...
随机推荐
- 【KMP】洛谷P2375 [NOI2014]动物园 题解
一开始的方向应该对了,但是没有想到合理的优化还是没写出来…… 题目描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己 ...
- 补档 Codeblocks下的文件标题栏(标签)显示方法
可能在以下链接也能看到这篇文档 我知道很多人都不知道这个到底叫啥,还不如直接一点: 文件标题栏 就是如下的效果. 解决办法: 在左上角第三个view下,打开后取消Hide editor tabs 选项 ...
- BZOJ - 1003 DP+最短路
这道题被马老板毒瘤了一下,TLE到怀疑人生 //然而BZOJ上妥妥地过了(5500ms+ -> 400ms+) 要么SPFA太玄学要么是初始化block被卡到O(n^4) 不管了,不改了 另外D ...
- git——合并分支
A将自己的本地代码提交到远程A分支,此时master主干上有B新提交的代码,如果此时A把自己的代码merge到主干,会有冲突,那怎么办? 1.A将自己的代码提交到自己的A分支 2.git fetch ...
- Hsl PLC
https://github.com/dathlin/HslCommunication 地址
- TOJ 3176 Challenge from XOR
Description Mr. AngelClover just learnt XOR on his Computer Class. XOR is a bit arithmetic operator ...
- git clone时的各种报错汇总
npm ERR! path E:\aawork\1work\2019.2\package.json 没有在项目路径下 npm ERR! missing script: dev 需要 vue init ...
- SQL Server Profiler(转载)
SQL Server Profiler工具 一.SQL Profiler工具简介 SQL Profiler是一个图形界面和一组系统存储过程,其作用如下: 图形化监视SQL Server查询: 在后台收 ...
- python学习(七)--豆瓣爬取电影名,评分以及演员
import requestsimport re #爬取豆瓣电影排名pageNum = int(input("要查看第几页电影分数:"))#已知豆瓣默认每页展示20条#url= & ...
- spring cloud Eureka 服务注册发现与调用
记录一下用spring cloud Eureka搭建服务注册与发现框架的过程. 为了创建spring项目方便,使用了STS. 一.Eureka注册中心 1.新建项目-Spring Starter Pr ...