最近做一个数据库分离的功能,其中用到了spring aop,主要思路就是在service层的方法执行前根据注解(当然也可以根据方法名称,如果方法名称写的比较统一的话)来判断具体使用哪个库。所以想着再回头来看看aop的详细用法。

  因为spring aop的话原理涉及到动态代理,了解动态代理的可以查看我的另一篇博客:java动态代理
  这里主要学习讨论spring aop的用法和注意事项。
  AOP(Aspect Oriented Programming),即面向切面编程。我们知道在学习java的时候有一个OOP(Object Oriented Programming,面向对象编程),其中还涉及到它的一些特性:封装,继承,多态。这些其实就是定义了类本身以及类和类之间的关系。这里不再赘述。那么AOP是用在什么场合呢?
  下面的例子可以大致说明面向切面编程的一个场景,代码如下:
 public class User {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
这里User就是一个普通的pojo类,现在假设有个需求说如果user对象为空,则进行判空处理,否则还是正常处理。这个时候有两种解决思路:一种是在每个方法里面判断,代码如下:
 public class User {
private int age;
private String name;
private User user;
public int getAge() {
if(user == null){
return 0;
}
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
if(user == null){
return "user is null";
}
return name;
}
public void setName(String name) {
this.name = name;
}
}
  如果方法很多个,那么就要在每个方法里面判断user是否为空,这个比较麻烦,而且容易出错。另一种方式是面向切面。就是在执行User类方法的前面先判断,这样的话判断条件就比较集中。具体怎么判断呢?先来看一下aop的具体知识点。
  AOP它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
  使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

AOP核心概念

1、横切关注点

  对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点

2、切面(aspect)

  类是对物体特征的抽象,切面就是对横切关注点的抽象,所以切面一般对应一个类

3、连接点(joinpoint)

  被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器

4、切入点(pointcut)

  对连接点进行拦截的定义

5、通知(advice)

  所谓通知指的就是拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类

6、目标对象

  代理的目标对象

7、织入(weave)

  将切面应用到目标对象并导致代理对象创建的过程

8、引入(introduction)

  在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段
  单纯的记忆这些概念不好记,下面会根据具体实例来一一对号。

Spring对AOP的支持

  Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。Spring创建代理的规则为:
  1. 默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了
  2. 当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB
AOP编程其实是很简单的事情,纵观AOP编程,程序员只需要参与三个部分:
  1. 定义普通业务组件
  2. 定义切入点,一个切入点可能横切多个业务组件
  3. 定义增强处理,增强处理就是在AOP框架为普通业务组件织入的处理动作
  所以进行AOP编程的关键就是定义切入点和定义增强处理,一旦定义了合适的切入点和增强处理,AOP框架将自动生成AOP代理,即:代理对象的方法=增强处理+被代理对象的方法。
使用Spring AOP,要成功运行起代码,只用Spring提供给开发者的jar包是不够的,请额外上网下载两个jar包:
  1. aopalliance.jar
  2. aspectjweaver.jar

这里举一个简单的例子,首先定义一个接口Output:

 public interface Output {
void out();
}
定义接口的实现类Subject:
 public class Subject implements Output{
@Override
public void out(){
System.out.println("被代理对象的输出");
}
}
接着定义一个切面AopAspect,切面可以看做是切入点,通知等的抽象集合。
 public class AopAspect {
public void before() {
System.out.println("方法执行前");
}
public void after() {
System.out.println("方法执行后");
}
}
然后在xml中配置如下:
 <bean id="subject" class="aop.Subject"></bean>
<bean id="aopAspect" class="aop.AopAspect"></bean>
<aop:config>
<aop:aspect id="aopAspect" ref="aopAspect">
<aop:pointcut id="allMethod" expression="execution(* aop.Subject.*(..))"/>
<aop:before method="before" pointcut-ref="allMethod"></aop:before>
<aop:after method="after" pointcut-ref="allMethod"></aop:after>
</aop:aspect>
</aop:config>
其实在xml中能够更清晰的对应相应的概念:
  横切关注点:这里就是对Subject类的out()方法进行拦截,在out()方法前面执行before(),之后执行after(),这些成为横切关注点
  切面(aspect):很明显,就是AopAspect
  连接点(joinpoint):被拦截到的点,这里是一个方法,也就是out()方法
  切入点(pointcut):在哪里进行拦截,这里定义的是Sub   ject类下面的所有方法。这里有一个expression表达式来描述拦截的地方:常用的就是execution,这里的表达式的含义如下:
    
  通知(advie):拦截到连接点之后要执行的代码,这里就是before()和after()了
  目标对象:就是Subject
  织入:切面应用到目标对象,就是把切面AopAspect织入到Subject中

使用Spring AOP的其他细节

1、如果在加入一个切面,那么这两个切面的执行顺序是怎样的?
  1. 默认以aspect的定义顺序作为织入顺序
  2. aspect里面有一个order属性,order属性的数字就是横切关注点的顺序
2、强制使用CGLIB生成代理
  Spring使用动态代理或是CGLIB生成代理是有规则的,高版本的Spring会自动选择是使用动态代理还是CGLIB生成代理内容,当然我们也可以强制使用CGLIB生成代理,那就是<aop:config>里面有一个"proxy-target-class"属性,这个属性值如果被设置为true,那么基于类的代理将起作用,如果proxy-target-class被设置为false或者这个属性被省略,那么基于接口的代理将起作用。
 

spring aop使用的更多相关文章

  1. 学习AOP之深入一点Spring Aop

    上一篇<学习AOP之认识一下SpringAOP>中大体的了解了代理.动态代理及SpringAop的知识.因为写的篇幅长了点所以还是再写一篇吧.接下来开始深入一点Spring aop的一些实 ...

  2. 学习AOP之认识一下Spring AOP

    心碎之事 要说知道AOP这个词倒是很久很久以前了,但是直到今天我也不敢说非常的理解它,其中的各种概念即抽象又太拗口. 在几次面试中都被问及AOP,但是真的没有答上来,或者都在面上,这给面试官的感觉就是 ...

  3. spring aop

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将 ...

  4. spring aop注解方式与xml方式配置

    注解方式 applicationContext.xml 加入下面配置 <!--Spring Aop 启用自动代理注解 --> <aop:aspectj-autoproxy proxy ...

  5. 基于Spring AOP的JDK动态代理和CGLIB代理

    一.AOP的概念  在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的 ...

  6. Spring AOP详解

    一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnbl ...

  7. Spring AOP实例——异常处理和记录程序执行时间

    实例简介: 这个实例主要用于在一个系统的所有方法执行过程中出线异常时,把异常信息都记录下来,另外记录每个方法的执行时间. 用两个业务逻辑来说明上述功能,这两个业务逻辑首先使用Spring AOP的自动 ...

  8. 从零开始学 Java - Spring AOP 实现用户权限验证

    每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...

  9. 从零开始学 Java - Spring AOP 实现主从读写分离

    深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...

  10. 从零开始学 Java - Spring AOP 拦截器的基本实现

    一个程序猿在梦中解决的 Bug 没有人是不做梦的,在所有梦的排行中,白日梦最令人伤感.不知道身为程序猿的大家,有没有睡了一觉,然后在梦中把睡之前代码中怎么也搞不定的 Bug 给解决的经历?反正我是有过 ...

随机推荐

  1. 索引节点inode详解

    Inode(index node),索引节点.Linux系统中,分区要进行格式化,创建文件系统.在每个Linux存储设备或存储设备的分区(可以是硬盘,软盘,U盘等)被格式化为ext3文件系统后,一般分 ...

  2. [解读REST] 5.Web的需求 & 推导REST

    衔接上文[解读REST] 4.基于网络应用的架构风格,上文总结了一些适用于基于网络应用的架构风格,以及其评估结果.在前文的基础上,本文介绍一下Web架构的需求,以及在对Web的关键协议进行设计和改进的 ...

  3. git学习整理(1)git clone 理解

    1.git clone 的理解 git clone默认会把远程仓库整个给clone下来 ,只能clone远程库的master分支并在本地默认创建一个master分支 ,无法clone所有分支,若想要其 ...

  4. MySQL索引语法+使用场景

    MySQL索引语法 建表时添加索引 建表同时建立单索引 CREATE TABLE t_user1(id INT , userName VARCHAR(20), PASSWORD VARCHAR(20) ...

  5. 数据结构与算法--从平衡二叉树(AVL)到红黑树

    数据结构与算法--从平衡二叉树(AVL)到红黑树 上节学习了二叉查找树.算法的性能取决于树的形状,而树的形状取决于插入键的顺序.在最好的情况下,n个结点的树是完全平衡的,如下图"最好情况&q ...

  6. Java随机数和UUID

    Java随机数和UUID Java随机数 在Java项目中通常是通过Math.random方法和Random类来获得随机数,前者通过生成一个Random类的实例来实现. 此类产生的是一组伪随机数流,通 ...

  7. JS的简单用法

    JS的简单用法 参考:http://www.w3school.com.cn/js/js_switch.asp JavaScript 是网络的脚本语言 JavaScript 是可插入 HTML 页面的编 ...

  8. Nginx监控-Nginx+Telegraf+Influxb+Grafana

    搭建了Nginx集群后,需要继续深入研究的就是日常Nginx监控. Nginx如何监控?相信百度就可以找到:nginx-status 通过Nginx-status,实时获取到Nginx监控数据后,如何 ...

  9. LeetCode 243. Shortest Word Distance (最短单词距离)$

    Given a list of words and two words word1 and word2, return the shortest distance between these two ...

  10. css中居中方法小结

    ---恢复内容开始--- 1.文字垂直居中 .header_nav-item{ height:38px; line-height:38px; } 即文字所在模块的高度和行高设置成一样的! 2.块元素垂 ...