曹工说Spring Boot源码(19)-- Spring 带给我们的工具利器,创建代理不用愁(ProxyFactory)

曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享

曹工说Spring Boot源码(2)-- Bean Definition到底是什么,咱们对着接口,逐个方法讲解

曹工说Spring Boot源码(3)-- 手动注册Bean Definition不比游戏好玩吗,我们来试一下

曹工说Spring Boot源码(4)-- 我是怎么自定义ApplicationContext,从json文件读取bean definition的?

曹工说Spring Boot源码(5)-- 怎么从properties文件读取bean

曹工说Spring Boot源码(6)-- Spring怎么从xml文件里解析bean的

曹工说Spring Boot源码(7)-- Spring解析xml文件,到底从中得到了什么(上)

曹工说Spring Boot源码(8)-- Spring解析xml文件,到底从中得到了什么(util命名空间)

曹工说Spring Boot源码(9)-- Spring解析xml文件,到底从中得到了什么(context命名空间上)

曹工说Spring Boot源码(10)-- Spring解析xml文件,到底从中得到了什么(context:annotation-config 解析)

曹工说Spring Boot源码(11)-- context:component-scan,你真的会用吗(这次来说说它的奇技淫巧)

曹工说Spring Boot源码(12)-- Spring解析xml文件,到底从中得到了什么(context:component-scan完整解析)

曹工说Spring Boot源码(13)-- AspectJ的运行时织入(Load-Time-Weaving),基本内容是讲清楚了(附源码)

曹工说Spring Boot源码(14)-- AspectJ的Load-Time-Weaving的两种实现方式细细讲解,以及怎么和Spring Instrumentation集成

曹工说Spring Boot源码(15)-- Spring从xml文件里到底得到了什么(context:load-time-weaver 完整解析)

曹工说Spring Boot源码(16)-- Spring从xml文件里到底得到了什么(aop:config完整解析【上】)

曹工说Spring Boot源码(17)-- Spring从xml文件里到底得到了什么(aop:config完整解析【中】)

曹工说Spring Boot源码(18)-- Spring AOP源码分析三部曲,终于快讲完了 (aop:config完整解析【下】)

工程代码地址 思维导图地址

工程结构图:

曹工说Spring Boot源码(19)-- Spring 带给我们的工具利器,创建代理不用愁(ProxyFactory)

概要

本篇是接着前三篇讲的,但是本篇相对独立,即使不使用spring aop 和spring ioc,我们也可以利用今天要讲的ProxyFactory为我们所用。

曹工说Spring Boot源码(16)-- Spring从xml文件里到底得到了什么(aop:config完整解析【上】)

曹工说Spring Boot源码(17)-- Spring从xml文件里到底得到了什么(aop:config完整解析【中】)

曹工说Spring Boot源码(18)-- Spring AOP源码分析三部曲,终于快讲完了 (aop:config完整解析【下】)

前面几篇说到,spring如何实现aop,即将匹配切点的bean,生成动态代理,并将生成的动态代理放到ioc容器,来替换原先的bean,一系列骚操作,完成"代理换真身"的操作。

jdk动态代理

比较老套的话题,但是,我问大家几个问题,看看大家是否真的足够了解他呢?

在代理对象上,调用不在接口中的方法 package foo; public class Performer implements Perform { @Override public void sing() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("男孩在唱歌"); } public void eat() { System.out.println("男孩在吃饭"); } }

可以看到,我们sing是实现了接口中的方法,而eat不在接口中定义。

那么,如下代码,结果会是啥:

@Test public void createJdkDynamicProxyManual() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { ClassLoader loader = Thread.currentThread().getContextClassLoader(); Object generatedProxy = Proxy.newProxyInstance(loader, new Class[]{Perform.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("proxy:" + proxy.getClass()); return "hahh"; } }); Method eat = Perform.class.getMethod("eat"); eat.setAccessible(true); eat.invoke(generatedProxy,null); }

代码中,我们创建了一个代理对象:generatedProxy;然后,调用了其eat方法,结果会是啥呢?

java.lang.NoSuchMethodException: foo.Perform.eat() at java.lang.Class.getMethod(Class.java:1665) at java.lang.Class.getMethod(Class.java:1665)

为啥会这样呢?因为我们创建代理对象时,是在Perform.class这个接口上创建的。大家可以再仔细看看。

jdk 动态代理(Proxy.newProxyInstance)有哪几个步骤

这个问题,有人思考过吗?简单来说,其实有3个步骤。

生成动态代理类的class,虽然不像其他class文件那样,是编译了就有的,这里,是动态生成的;

加载第一步拿到的字节流,丢给jvm加载该class,拿到Class对象

根据第二步的Class对象,反射生成动态代理对象。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywjjf.html