SpringAop实现原理及代理模式
Spring Aop的原理
Spring的AOP就是通过动态代理实现的。当为某个Bean或者某些Bean配置切面时,Spring会为其创建代理对象,当调用该对象的某个方法时,实际是调用生成的代理类的对象方法。Spring的Aop主要是使用了两个动态代理,分别是JDK的动态代理和CGLIB动态代理。
1. JDK动态代理
如果代理类实现了接口,Spring默认会使用JDK动态代理。JDK的动态代理是基于反射实现。JDK通过反射,生成一个代理类,这个代理类实现了原来那个类的全部接口,并对接口中定义的所有方法进行了代理。当我们通过代理对象执行原来那个类的方法时,代理类底层会通过反射机制,调用我们实现的InvocationHandler接口的invoke方法。
点击查看代码
/*
* 接口类
*/
public interface Person {
void say();
}
/*
* 接口实现类
*/
public class Man implements Person {
private String word;
public Man(String word){
this.word = word;
}
public Man(){
}
public void say(){
System.out.println("Man Can Say " + word);
}
}
public class ManJDKProxy implements InvocationHandler {
/**
* 需要的代理对象
*/
private Object o;
public Object bind(Object o){
this.o = o;
return Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK Proxy Design");
return method.invoke(o, args);
}
}
/**
* JDK动态代理
*/
public class ProxyDesign_2 {
public static void main(String[] args) {
Man man = new Man("Hello");
Person p = (Person)new ManJDKProxy().bind(man);
p.say();
}
}
* JDK动态代理的优缺点
优点:
1. JDK动态代理是JDK原生的,不需要任何依赖即可使用
2. 通过反射机制生成代理类的速度要比CGLib操作字节码生成代理类的速度更快
缺点:
1. 如果要使用JDK动态代理,被代理的类必须实现了接口,否则无法代理(InvocationHandler)
2. JDK动态代理无法为没有在接口中定义的方法实现代理
3. JDK动态代理执行代理方法时,需要通过反射机制进行回调,此时方法执行的效率比较低
2. CGLIB动态代理
若需要代理的类没有实现接口,JDK的动态代理就无法使用,Spring会使用CGLiB动态代理来生成代理对象。CGLiB直接操作字节码,生成类的子类,重写类的方法完成代理。
点击查看代码
/*
* 接口类
*/
public interface Person {
void say();
}
/*
* 接口实现类
*/
public class Man implements Person {
private String word;
public Man(String word){
this.word = word;
}
public Man(){
}
public void say(){
System.out.println("Man Can Say " + word);
}
}
public class ManCGLIBProxy {
public Object bind(Object target){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("CGLIB Proxy Design");
return method.invoke(target, objects);
}
});
return enhancer.create();
}
}
/**
* CGLIB动态代理
*/
public class ProxyDesign_3 {
public static void main(String[] args) {
Man man = new Man("Hello");
Person p = (Person)new ManCGLIBProxy().bind(man);
p.say();
}
}
* CGLiB动态代理的优缺点
优点:
1. 使用CGLiB代理的类,不需要实现接口,因为CGLib生成的代理类是直接继承自需要被代理的类
2. 因为CGLiB实现方式是重写父类的方法,所以对final方法,或者private方法是没有办法代理的
3. CGLiB是通过修改字节码生成的代理类,所以CGLib执行代理方法的效率要高于JDK的动态代理
缺点:
1. 因为CGLiB实现方式是重写父类的方法,所以对final方法,或者private方法是没有办法代理的
2. 因为CGLiB生成代理类的方式是通过操作字节码(asm工具包),这种生成的代理类的方式比JDK通过反射生成代理类的方式的效率低
3. Spring项目中如何强制使用CGLIB代理方式
* xml方式
<!-- aop:config用来在xml中配置切面,指定proxy-target-class="true" -->
<aop:config proxy-target-class="true">
<!-- AOP相关配置 -->
</aop:config>
* @Aspect注解方式
<!-- 将proxy-target-class配置设置为true -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
* 配置类注解方式
添加@EnableAspectJAutoProxy(proxyTargetClass = true)
SpringAop实现原理及代理模式的更多相关文章
- 大话设计模式C++实现-文章7章-代理模式
一个.UML画画 二.概念 代理模式:为其它对象提供一种代理以控制对这个对象的訪问. 三.应用场景 (1)远程代理.也就是为一个对象在不同的地址空间提供局部代表.这样能够隐藏一个对象存在于不同地址空间 ...
- 代理模式(静态代理、JDK动态代理原理分析、CGLIB动态代理)
代理模式 代理模式是设计模式之一,为一个对象提供一个替身或者占位符以控制对这个对象的访问,它给目标对象提供一个代理对象,由代理对象控制对目标对象的访问. 那么为什么要使用代理模式呢? 1.隔离,客户端 ...
- AOP 技术原理——代理模式全面总结
前言 非常重要的一个设计模式,也很常见,很多框架都有它的影子.定义就不多说了.两点: 1.为其它对象提供一个代理服务,间接控制对这个对象的访问,联想 Spring 事务机制,在合适的方法上加个 tra ...
- springAOP之代理模式
springAOP指的是在spring中的AOP,什么是AOP,相对于java中的面向对象(oop),在面向对象中一些公共的行为,像日志记录,权限验证等如果都使用面向对象来做,会在每个业务方法中都写上 ...
- 带你入门代理模式/SpringAop的运行机制
SpringAop 是spring框架中最重要的一项功能之一,同时也是企业级开发记录事物日志等不可或缺的一部分,如果说你的系统需要记录用户访问接口的操作,那SpringAop是很完美的了,当然,拦截器 ...
- Java设计模式——代理模式实现及原理
简介 Java编程的目标是实现现实不能完成的,优化现实能够完成的,是一种虚拟技术.生活中的方方面面都可以虚拟到代码中.代理模式所讲的就是现实生活中的这么一个概念:中介. 代理模式的定义:给某一个对象提 ...
- 重学 Java 设计模式:实战代理模式「模拟mybatis-spring中定义DAO接口,使用代理类方式操作数据库原理实现场景」
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 难以跨越的瓶颈期,把你拿捏滴死死的! 编程开发学习过程中遇到的瓶颈期,往往是由于看不 ...
- 从代理模式 到 SpringAOP
前言 Spring AOP 就是通过代理模式来实现切面编程的.代理模式用来为其他对象提供一种代理,以控制对这个对象的访问. 代理对象在客户端和目标对象之间起到中介的作用.通过控制对这个对象的访问,可以 ...
- JAVA动态代理模式(从现实生活角度理解代码原理)
所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...
随机推荐
- petite-vue源码剖析-从静态视图开始
代码库结构介绍 examples 各种使用示例 scripts 打包发布脚本 tests 测试用例 src directives v-if等内置指令的实现 app.ts createApp函数 blo ...
- TCP三次握手中SYN,ACK,seq ack的含义
转至:https://www.cnblogs.com/muyi23333/articles/13841268.html 1.TCP 为什么三次握手而不是两次握手 1.防止已失效的连接请求又传送到服务器 ...
- Python:Scrap爬虫过程中遇到的各种错误
1.KeyError: 'Spider not found: BDS' 原因:settings.py中缺少了几项与spider名字配置相关的项: BOT_NAME = 'BDS' SPIDER_MOD ...
- boostrap的select2自动换行的问题解决
最近在使用boostrap的select2控件实现多选效果时发现一个问题正常效果:但是当选择了两个长一些的option时,发现select2莫名其妙的换了一行空白行:经过F12调试发现是因为selec ...
- 在矩池云上复现 CVPR 2018 LearningToCompare_FSL 环境
这是 CVPR 2018 的一篇少样本学习论文:Learning to Compare: Relation Network for Few-Shot Learning 源码地址:https://git ...
- think php 删除
表单页面 <a href="/examtest/test/edit/id/{$v['id']}">修改</a> <a href="/exam ...
- linux php 环境word转pdf、excel转pdf、office转pdf
最近项目中遇到一个需求,将word.excel文件转换成pdf,并且打上水印,我利用的是libreoffice,这个需要Java 的jdk环境.废话不多说,开撸 1.在linux上搭建jdk环境 文章 ...
- Django基础四之测试环境和ORM查询
Django基础四之测试环境和ORM查询 目录 Django基础四之测试环境和ORM查询 1. 搭建测试环境 1.1 测试环境搭建方法: 1.2 使用测试环境对数据库进行CURD 1.3 返回Quer ...
- VTK数据拓扑结构、几何结构和属性数据
读取到VTK数据后,将数据组织起来并添加属性值. 示例: #include <vtkSmartPointer.h> #include <vtkPoints.h> #includ ...
- CentOS8安装Geant4笔记(三):Geant4介绍、编译、安装支持Qt5界面并运行exampleB1例程显示Qt界面
前言 上一篇,安装了Qt5环境. 本篇在服务器CentOs8.2上安装geant4软件,geant4使用Qt5来显示. GEANT4 介绍 Geant4 是一个用于模拟粒子穿过物质的工具 ...