Spring AOP

AOP是Aspect/'æspekt/ Oriented/ɔːrɪentɪd/ Programming的缩写,意为:面向切面编程。

是什么

通过预编译方式和运行期动态代理实现程序功能的一种技术。

作用
Spring AOP是Spring框架中的一个重要内容,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

使用场景
Java是一个面向对象(OOP)的语言,但它有一些弊端,比如当我们需要为多个不具有继承关系的对象引入一个公共行为,例如日志、权限验证、事务等功能时,只能在在每个对象里引用公共行为。这样做不便于维护,而且有大量重复代码。AOP的出现弥补了OOP的这点不足。

举个栗子1

package test.staticProxy;

// 接口
public interface IUserDao {
void save();
} //目标对象
class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("模拟:保存用户!");
}
} /**
* 静态代理
* 特点:
* 2. 目标对象必须要实现接口
* 2. 代理对象,要实现与目标对象一样的接口
*/
class UserDaoProxy implements IUserDao{ // 代理对象,需要维护一个目标对象
private IUserDao target = new UserDao(); @Override
public void save() {
System.out.println("代理操作: 开启事务...");
target.save(); // 执行目标对象的方法
System.out.println("代理操作:提交事务...");
}
}
测试:
public static void main(String args[]){
IUserDao proxy = new UserDaoProxy();
proxy.save();
}
测试结果:
代理操作: 开启事务...
模拟:保存用户!
代理操作:提交事务...

以上是静态代理的例子,其中一个代理类只能服务一个对象,如果有大量需要被代理的对象,那么需要编写大量的代理类,并且被代理的对象增加方法则除了实现了增加之外代理类也要实现此方法,这样就增加了代码的维护成本。

举个栗子2

package test.dynamicProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; // 接口
public interface IUserDao {
void save();
} //目标对象
class UserDao implements IUserDao{ @Override
public void save() {
System.out.println("模拟: 保存用户!");
}
} /**
* 动态代理:
* 代理工厂,给多个目标对象生成代理对象!
*
*/
class ProxyFactory { // 接收一个目标对象
private Object target; public ProxyFactory(Object target) {
this.target = target;
} // 返回对目标对象(target)代理后的对象(proxy)
public Object getProxyInstance() {
Object proxy = Proxy.newProxyInstance(
target.getClass().getClassLoader(), // 目标对象使用的类加载器
target.getClass().getInterfaces(), // 目标对象实现的所有接口
new InvocationHandler() { // 执行代理对象方法时候触发 @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable { // 获取当前执行的方法的方法名
String methodName = method.getName();
// 方法返回值
Object result = null;
if ("save".equals(methodName)) {
System.out.println("开启事务...");
// 执行目标对象方法
result = method.invoke(target, args);
System.out.println("提交事务...");
}
return result;
}
}
);
return proxy;
}
}
测试:
public static void main(String[] args){
  //创建目标对象
  IUserDao target = new UserDao();
  System.out.println("目标对象"+target.getClass());
  //代理对象
  IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
  System.out.println("代理对象"+proxy.getClass());
  //执行代理对象方法
  proxy.save();
}
测试结果:
目标对象:class test.dynamicProxy.UserDao
代理对象:class com.sun.proxy.$Proxy0
开启事务...
模拟:保存用户!
提交事务...

以上代码是基于JDK动态代理实现的,前提是目标类必须有实现的接口。

如果一个类没有实现接口,就不能使用JDK动态代理。而CGLIB代理可以弥补这个问题。

举个栗子3

CGLIB 是以动态生成的子类继承目标的方式实现,在运行期动态的在内存中构建一个子类,如下:

public class UserDao{}

// CGLIB 是以动态生成的子类继承目标的方式实现,程序执行时,隐藏了下面的过程
public class $Cglib_Proxy_class extends UserDao{}

前提是目标类不能是final修饰,因为final修改的类不能被继承。

总结:

面向切面编程的核心原理是使用动态代理模式在方法执行的前后或出现异常时加入相关逻辑。

关键词 动态代理 方法级 动态关注点 切面关注点代码类

优秀的 Spring 框架把JDK 代理和 CGLIB 代理两种动态代理方式在底层都集成了进去,我们无需担心自己去实现动态生成代理。

通过查看 Spring 源码,我们在 DefaultAopProxyFactory 类中,找到这样一段话。

简单的从字面意思看出:如果有接口,则使用 JDK 代理,反之使用 CGLIB ,这刚好印证了前文所阐述的内容。Spring AOP 综合两种代理方式的使用前提有会如下结论:如果目标类没有实现接口,且 class 为 final 修饰的,则不能进行 Spring AOP 编程!

认识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. 文件参数化-utp框架之根据yaml文件自动生成python文件+utp运行用例

    根据yaml文件自动生成python文件 utp框架: bin目录:存放执行文件(run.py) cases目录:存放生成的用例的python文件(该目录下的文件为根据data目录下的测试用例生成的p ...

  2. 【bzoj3998】弦论 后缀自动机

    Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...

  3. ArcGIS10.4破解

    arcgis 10.4破解方法 *注意!Desktop,Engine,Server必须为同一版本* Engine10.4破解失败,SDE10.4未进行破解 1.先安装License10.4 2.再安装 ...

  4. [SDOi2012]Longge的问题 BZOJ2705 数学

    题目背景 SDOi2012 题目描述 Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题.现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N). ...

  5. 加载 xib 文件 UIView

    记在 UIView 的 xib 文件方式有一下几种: 一 .直接加载 xib 文件, 没有.h.m 文件 1. NSBundle 方式 NSArray *objs = [[NSBundle mainB ...

  6. 用IDM下载博客图片

    前言 写博客的人一定都会有一个图床,将图片存在那里.发现自己以前没有注意图片来源问题,随手就贴在博客上面了.现在有不少图片都挂了,换句话来说有可能自己目前用的图床不提供服务了,那所有的图片都有可能丢失 ...

  7. python之文件读写(1)

    1. 从文件读取数据 关于对文件的操作,使用open(filename, mode),打开文件.与之对应的,close()用来关闭文件.对文件操作完毕切记要关闭. open函数参数: mode 参数有 ...

  8. DEM反应不收敛问题

    之前算DEM反应一直不收敛,后来把计算规模减少到两个固定颗粒,也就是仿照reactive-chemistry和evaperation这两个算例. 目前reactive-chemistry这个算例,把各 ...

  9. debug启动项目很慢

    用debug启动项目比正常启动慢,从网上找到的是这样说的.删除所有的断点就可以了. 这个问题可能是由于eclipse和tomcat的交互而产生的,在以debug模式启动tomcat时,发生了读取文件错 ...

  10. JSTL的核心标签

    JSTL的核心标签: .if: 语法:<c:if test="" var="" scope=""></c:if> 当 ...