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包中的两个 ...
随机推荐
- linux光盘使用、rpm软件包、yum软件仓库安装使用
转至:https://blog.51cto.com/zpeng/1532520 一.光盘文件使用 1,RHEL5(x86_64)光盘结构 Cluster //集群二进制包 C ...
- 爬虫之Scrapy框架介绍及基础用法
今日内容概要 爬虫框架之Scrapy 利用该框架爬取博客园 并发编程 今日内容详细 爬虫框架Scrapy 1.什么是框架? 框架类似于房子的结构,框架会提前帮你创建好所有的文件和内部环境 你只需要往对 ...
- k8s全方位监控-prometheus-alertmanager部署-配置第一条告警邮件
1.alertmanager告警插件部署 [root@VM_0_48_centos prometheus]# cat alertmanager-pvc.yaml apiVersion: v1 kind ...
- LeetCode-059-螺旋矩阵 II
螺旋矩阵 II 题目描述:给你一个正整数 n ,生成一个包含 1 到 \(n^{2}\) 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix . 示例说明请见LeetCode ...
- EXCEL中多个字符或数值拼接(concatenate)
1.concatenate函数的含义 把多个字符文本或数值连接在一起,实现合并的功能 2.concatenate函数的语法格式 =concatenate(text1, [text2], ...) Te ...
- 矩池云上cifar10使用说明
矩池云将 keras 预训练模型保存目录为 /public/keras_pretrained_model/ 使用方法: 先执行命令,创建目录 mkdir -p ~/.keras/models/ 然后将 ...
- Hadoop原生对象存储Ozone
Hadoop 社区推出了新一代分布式Key-value对象存储系统 Ozone,同时提供对象和文件访问的接口,从构架上解决了长久以来困扰HDFS的小文件问题.本文作为Ozone系列文章的第一篇,抛个砖 ...
- 34 异常机制 异常体系结构 Java把异常当做对象来处理 并定义一个基类java.lang.Throwable作为所有异常的超类 Error Exception
异常体系结构 概念 Java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类. 在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Erro ...
- 【黑马程序员C++ STL】学习记录
黑马程序员 2017 C++ STL 教程(STL 部分已完结) 基于黑马STL课程整理:黑马程序员2017C++STL教程 视频链接 专栏:本STL专栏目录 文章目录 黑马程序员 2017 C++ ...
- 前端知识之html基础
前端知识之html内容 web服务本质 浏览器发送请求-->http协议-->服务端接收请求-->服务端返回响应-->服务端把html文件内容发给浏览器-->浏览器渲染页 ...