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. 题解 CF500D 【New Year Santa Network】

    题目链接 这道题首先是要看看该如何化简,先把三元组化成二元组. 之后统计经过某条边的 次数$*$权值  的和. 最后除以总基数 $tot$ 其中,每条边被计算的次数为 子树的点数$*$非子树的点数 ( ...

  2. JDBC_ResultSet结果集用法_游标原理_关闭连接问题

    依次关闭使用对象及连接 ResultSet---Statement--Connectionimport java.sql.Connection;import java.sql.DriverManage ...

  3. Reviewing notes 1.1 of Advanced algebra

    ♦Linear map Definition Linear map A linear map from vector space V to W over a field F is a function ...

  4. (转)win7英文目录和中文目录,文件夹的别名

    win7英文目录和中文目录,文件夹的别名 在使用win7的很多目录例如我的文档.我的音乐等目录,你会发现文件夹是中文名的,路径也是中文的.但这个不是真的路径.点击一下地址栏,就可以看到真实路径了. 这 ...

  5. 【转】org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be res

    如图所示: 看网上的解决方案,有的说是jstl的版本问题,1.0版本引入使用的时候加的uri不带有jsp路径的,1.2的带有/jsp路径,还有的说是依赖冲突的问题,最后尝试了都不行,只有一招能够行的通 ...

  6. php Apache No input file

    RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] 变为 RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]

  7. php 编码和解码的函数

    URL: urlencode(); //编码 urldecode(); //解码 URL与数组互转: parse_url () http_build_query() base64: base64_en ...

  8. asp.net 同时执行js事件和代码事件 导出 excel

     onclick="return bnQuery_onclick()" onserverclick="bnQuery_ServerClick"   public ...

  9. SGU - 275 线性基 初步

    题意:求给出的数任意异或的最大值 目前对线性基的理解过于肤浅,有空总结一下 #include<iostream> #include<algorithm> #include< ...

  10. [转] Tomcat 禁用URL中的JSESSIONID

    [From] http://stackoverflow.com/questions/962729/is-it-possible-to-disable-jsessionid-in-tomcat-serv ...