spring源码解读-aop
aop是指面向切面编程,ProxyFactoryBean是spring aop的底层实现与源头,为什么这么说呢?首先我们看一段配置:
1、target是目标对象,需要对其进行切面增强
2、proxyInterfaces是指代理对象所实现的接口
3、interceptorNames:是指通知器(Advisor)列表,通知器中包含了通知advice与切点pointcut
概括一下,ProxyFactoryBean的作用是:
针对目标对象来创建代理对象,将对目标对象方法的调用转到对相应代理对象方法的调用,并且可以在代理对象方法调用前后执行与之匹配的各个通知器中定义好的方法
spring通过两种方式来创建目标代理对象:
1、JDK动态代理
2、CGLIB
在spring中这两种代理方式都实现了AopProxy接口去,如下图所示:
spring中AopProxyFactory是一个接口,接口中只有一个方法createAopProxy,这个接口是有一个实现类DefaultAopProxyFactory,用来创建AopProxy对象,如下图所示:
下面我们比较并实现以下两种代理方式:
首先明确以下我们常用的代理模式有什么问题,在我们经常使用的代理模式中,真实对象必须是事先存在的,并将其作为代理对象的内部属性,在使用时,一个真实角色必须对应一个dialing角色,如果大量使用会导致类的急剧膨胀,java的动态代理类就可以解决这个问题。
JDK动态代理
java动态代理类位于java.lang.reflect包下,一般主要涉及到两个类:
1、Interface InvocationHandler:该接口中只定义了一个方法
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
第一个参数proxy是指代理类,method是被代理的方法,args为该方法的参数数组
2、Proxy:该类为动态代理类,其主要方法如下
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
该方法返回代理类的一个实例,返回后的代理类可以被当作代理类使用
JDK动态代理实现步骤:
1、创建一个实现接口InvocationHandler的类(DynamicSubject),它必须实现invoke方法
public class DynamicSubject implements InvocationHandler { private Object sub; public DynamicSubject(Object sub) {
this.sub = sub;
} public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before calling:" + method);
method.invoke(sub, args);
System.out.println(args == null);
System.out.println("after calling:" + method);
return null;
}
}
2、创建被代理的类(RealSubject)以及接口(Subject)
public interface Subject {
public void request();
}
public class RealSubject implements Subject { public void request() {
System.out.println("from real subject");
}
}
3、通过Proxy的静态方法newProxyInstance创建一个代理
public class Client { public static void main(String[] args) { RealSubject realSubject = new RealSubject();
InvocationHandler handler = new DynamicSubject(realSubject);
Class<?> classType = handler.getClass();
Subject subject = (Subject) Proxy.newProxyInstance(classType.getClassLoader(), realSubject.getClass().getInterfaces(), handler);
subject.request();
System.out.println(subject.getClass());
}
}
如果目标类并未实现接口,那么Spring就会使用CGLIB库为其创建代理,如下demo运用了CGLIB实现代理
1、创建被代理类Person
public class Person { public void study() {
System.out.println("study");
}
}
2、创建CglibProxy实现代理
public class CglibProxy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); public Object getProxy(Class<?> clazz) {
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
Object object = enhancer.create();
return object;
} public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println(o.getClass().getName() + "." + method.getName()); //执行父类对应方法
final Object result = methodProxy.invokeSuper(o, objects); System.out.println("执行结束"); return result;
} public static void main(String[] args) { CglibProxy proxy = new CglibProxy();
Person person = (Person) proxy.getProxy(Person.class);
System.out.println(person.getClass().getName());
person.study(); }
}
下面我们来比较一下,两种代理方法的区别
1、JDK动态代理只能对实现了接口的类生成代理,而不能针对类
2、CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
3、在spring中如果bean实现了接口spring用JDK动态代理,如果bean没有实现接口,spring使用CGLIB实现代理
4、CGLIb不能对声明为final的方法进行dialing,因为CGLib原理是动态生成被代理类的子类
5、JDK动态代理通过反射的newInstance方法产生代理类的对象
spring源码解读-aop的更多相关文章
- Spring 源码学习——Aop
Spring 源码学习--Aop 什么是 AOP 以下是百度百科的解释:AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程通过预编译的方式和运行期动态代理实 ...
- Spring源码之AOP的使用
Spring往期精彩文章 Spring源码搭建 Spring源码阅读一 前言 我们都知道Java是一门面向对象(OOP)的语言,所谓万物皆对象.但是它也存在着一些个弊端:当你需要给多个不具有继承关系的 ...
- Spring源码解读之BeanFactoryPostProcessor的处理
前言 前段时间旁听了某课堂两节Spring源码解析课,刚好最近自己又在重新学习中,便在这里记录一下学习所得.我之前写过一篇博文,是介绍BeanFactoryPostProcessor跟BeanPost ...
- Spring源码解读--(一)源码下载
走在Java程序员这条路上,网上Java各种工具满天飞,写个简单的CRUD,相信是个开发都能写出来,于是在思考如何可以在同行业中更有竞争力(其实就是如何赚更多钱).那么,老大给我推荐了Spring源码 ...
- 【Spring源码解读】bean标签中的属性
说明 今天在阅读Spring源码的时候,发现在加载xml中的bean时,解析了很多标签,其中有常用的如:scope.autowire.lazy-init.init-method.destroy-met ...
- Spring源码解读:核心类DefaultListableBeanFactory的继承体系
1 简介 我们常用的ClassPathXmlApplicationContext是AbstractRefreshableApplicationContext的子类,而DefaultListableBe ...
- Spring源码解读(二):Spring AOP
一.AOP介绍 面向方面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP).OOP中模块化的关键单元是类,而在AOP中,模块化单元是方面.方面实现了诸如跨越多种类型和对象的事务 ...
- 专治不会看源码的毛病--spring源码解析AOP篇
昨天有个大牛说我啰嗦,眼光比较细碎,看不到重点.太他爷爷的有道理了!要说看人品,还是女孩子强一些.原来记得看到一个男孩子的抱怨,说怎么两人刚刚开始在一起,女孩子在心里就已经和他过完了一辈子.哥哥们,不 ...
- Spring源码解读Spring IOC原理
一.什么是Ioc/DI? IoC 容器:最主要是完成了完成对象的创建和依赖的管理注入等等. 先从我们自己设计这样一个视角来考虑: 所谓控制反转,就是把原先我们代码里面需要实现的对象创建.依赖的代码,反 ...
随机推荐
- mybatis随记
JDBC问题:1.数据库配置信息硬编码 2.频繁创建,释放数据库连接 3.sql,设置参数,获取结果集硬编码,不通用 解决方案:1.配置文件 2.采用连接池 3.使用反射和内省 自定义持久层框 ...
- drf 生命周期
1) 根据应用中urls.py,走as_view方法,但是视图类没有该方法,所以请求走的是APIView的as_view方法 2) 在APIView的as_view调用父类(django原生View) ...
- 201771010128王玉兰《面向对象程序设计(Java)》第十二周学习总结
第一部分:理论知识 1.AWT与Swing简介 (1)Swing用户界面库是非基于对等体的GUI工具箱. Swing具有更丰富并且更方便的用户界面元素集合. Swing对底层平台的依赖很少,因此与 ...
- (二)vue的生命周期及相关的运行流程
@ 目录 1. vue的生命周期 经过一系列的初始化过程 需要设置数据监听 编译模板 将实例花在到DOM 并在数据变化时更新DOM 等 这是相应的生命周期函数 在用的时候直接写上, 其实很多人都这样, ...
- [JavaWeb基础] 027.JAVA中使用Axis搭建webservice-示例实现(二)
在上面的一个文章中,我们介绍了如何搭建Axis2的环境,也就是在MyEclipse中加入Axis的开发插件,那么,准备工作做好了之后,下面我们就用上一章的工具去搭建一个WebService的简单例子. ...
- NIO 的非阻塞式网络通信
1.阻塞与非阻塞 ① 传统的 IO 流都是阻塞式的.也就是说,当一个线程调用 read() 或 write()时, 该线程被阻塞,直到有一些数据被读取或写入,该线程在此期间不能执行其他任务. 因 ...
- 性能测试之Docker监控
微服务.大中台盛行的当下,容器化已经被广泛使用.在性能测试过程中,对容器的监控模型构建也是必不可少的. 我们性能测试监控模型的构建一直是围绕着Prometheus和Grafana来展开的.她们可以快速 ...
- 串口助手下载-带时间戳的串口助手-极简串口助手-V1.1 自动保存配置参数 能显示收发时间方便调试
1.串口助手下载 2.带时间戳的串口助手,每次收发指令带上了时间戳,方便调试 3.极简串口助手 4.简单易用 高速稳定 5.每次修改的参数都能自动保存,免去了重复配置的工作 下载地址:http://w ...
- python常见面试题讲解(十三)字串的连接最长路径查找
输入描述: 输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母. 输出描述: 数据输出n行,输出结果为按照字典序排列的字符串. 示例1 ...
- SpringMVC(二)返回值设置、数据在域中的保存与SpringMVC案例
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.返回值的设置 1.返回 String [1]返回 String 默认情况 @RequestMappi ...