认识Spring AOP
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的更多相关文章
- 学习AOP之深入一点Spring Aop
上一篇<学习AOP之认识一下SpringAOP>中大体的了解了代理.动态代理及SpringAop的知识.因为写的篇幅长了点所以还是再写一篇吧.接下来开始深入一点Spring aop的一些实 ...
- 学习AOP之认识一下Spring AOP
心碎之事 要说知道AOP这个词倒是很久很久以前了,但是直到今天我也不敢说非常的理解它,其中的各种概念即抽象又太拗口. 在几次面试中都被问及AOP,但是真的没有答上来,或者都在面上,这给面试官的感觉就是 ...
- spring aop
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将 ...
- spring aop注解方式与xml方式配置
注解方式 applicationContext.xml 加入下面配置 <!--Spring Aop 启用自动代理注解 --> <aop:aspectj-autoproxy proxy ...
- 基于Spring AOP的JDK动态代理和CGLIB代理
一.AOP的概念 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的 ...
- Spring AOP详解
一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnbl ...
- Spring AOP实例——异常处理和记录程序执行时间
实例简介: 这个实例主要用于在一个系统的所有方法执行过程中出线异常时,把异常信息都记录下来,另外记录每个方法的执行时间. 用两个业务逻辑来说明上述功能,这两个业务逻辑首先使用Spring AOP的自动 ...
- 从零开始学 Java - Spring AOP 实现用户权限验证
每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...
- 从零开始学 Java - Spring AOP 实现主从读写分离
深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...
- 从零开始学 Java - Spring AOP 拦截器的基本实现
一个程序猿在梦中解决的 Bug 没有人是不做梦的,在所有梦的排行中,白日梦最令人伤感.不知道身为程序猿的大家,有没有睡了一觉,然后在梦中把睡之前代码中怎么也搞不定的 Bug 给解决的经历?反正我是有过 ...
随机推荐
- phpstudy 部署php项目
网站根目录
- VS2010 由于缺少调试目标"xx.exe"
有两种可能会造成这种现像.A.配制属性出了问题. 一种方法:右击“解决方案”->“属性”,在弹出的“属性页”框中,选择左边的“配置属性”,在右边,将应用程序的生成那个框框勾上,二可能是这里的属性 ...
- 安装jdk1.8,编写环境变量
好记性不如烂笔头!!!(我这是把jdk放在的/usr/local下,且命令为jdk1.8...复制的时候别搞错位置了) JAVA_HOME=/usr/local/jdk1./ JAVA_BIN=/us ...
- 【转】IntelliJ IDEA下自动生成Hibernate映射文件以及实体类
1.构建项目并添加项目结构配置以及配置初始参数 1.1.如图将基本的架子搭建好 1.2.点击File,弹出的菜单中点击Project Structure: 1.3.点击左侧的Modul ...
- 【转】intellij idea使用指南—— 导入Eclipse的Web项目
通常一个团队中可能有人用eclipse,有人用intelliJ,那么经常会出现需要导入别人用eclipse建好的web项目.而IntelliJ提供了多种项目类型的导入方式,其中就有eclipse. 在 ...
- abp架构添加实体并使用迁移功能生成表
参考: https://aspnetboilerplate.com/Pages/Articles/Introduction-With-AspNet-Core-And-Entity-Framework- ...
- C#.net地址传参汉字乱码解决方案
C#.net地址传参汉字乱码解决方案 web.config文件: <system.web> <globalization requestEncoding="GB2312 ...
- POJ 3258:River Hopscotch (最大化最小值)
[题意] 牛要到河对岸,在与河岸垂直的一条线上,河中有N块石头,给定河岸宽度L,以及每一块石头离牛所在河岸的距离, 现在去掉M块石头,要求去掉M块石头后,剩下的石头之间以及石头与河岸的最小距离的最大值 ...
- C# 一些请求的基类(待补充)
using System.Runtime.Serialization; /// <summary> /// 通用分页请求类 /// </summary> [DataContra ...
- CentOS-pam认证机制简介
前言 linux下PAM模块全称是Pluggable Authentication Module for linux(可插入式授权管理模块),该由Sun公司提供,在Linux中,PAM是可动态配置的, ...