
关于Feign的启动原理分析,参照另一篇 Spring Cloud Feign 源码分析 - feign启动原理
书接上文,上篇最后提到所有带@FeignClient注解的interface都被封装成FeignClientFactoryBean的BeanDefinition。从名字上可以得知这个类是一个FactoryBean。关于FactoryBean的介绍参考
因此直接找getObject()。
getTarget方法首先获取FeignContext的对象,基于这个context对当前feign的配置信息存放到Builder中。
首先实例化bean:FeignContext
FeignContext的定义在FeignAutoConfiguration
第一次除了创建新的FeignContext对象之外,还设置了一组configurations,
这组configurations是FeignClientSpecification类型,通过autowired注入。
在扫描EnableFeignClients和各个FeignClient时,将configuration对应的class封装成了FeignClientSpecification的BeanDefinition,这里从容器中取出来创建对象注入到configurations
通过断点可以看到这里有15个FeignClientSpecification的对象
一个是default开头的在启动类里配置的configuration,剩下的都是FeignClient的configuration。
FeignContext继承了NamedContextFactory,对应的范型就是FeignClientSpecification,看下NamedContextFactory构造方法
这里设置了默认的defaultConfigType,feign里用的是FeignClientsConfiguration,定义了一系列的默认值。
在获取到FeignContext之后,开始封装FeignBuilder。
首先通过context实例化FeignLoggerFactory的对象,因为context是NamedContextFactory的子类,会给每个contextId创建一个独立的AnnotationConfigApplicationContext上下文,每一个k-v会存储在FeignContext的全局context中,key就是contextId
这三个方法的实现完全体现了NamedContextFactory的作用:
给每个name创建一个单独的ApplicationContext子上下文对象,后续凡是这个name的ioc *** 作,都由独立的ApplicationContext来完成,name之间的context相互隔离。所有的子上下文保存在了Map<String, AnnotationConfigApplicationContext> contexts中。
在创建Context时,补充了configuration的设置:
首先(1的位置),从全局的configurations查找是否定义了只对当前name生效的configuration,也就是判断在当前name所属的FeignClient注解上是否定义了configuration。如果定义过,将这个configuration的Class封装成BeanDefinition注册到本name的子上下文中。
接着(2的位置),从全局的configurations查找是否定义了全局配置,也就是@EnableFeignClients的defaultConfiguration的值,这里固定前缀是default。
如果也存在,就也将这个defaultConfiguration的Class封装成BeanDefinition注册到本name的子上下文中。
第一次调用完毕get方法后,给每个FeignClient创建的FeignContext就完成了configuration初始化的动作,后面的所有 *** 作,如配置encoder、decoder都是给当前的子上下文内注册BeanDefinition。最后将所有配置封装成Builder返回。
在getTarget()构造完成builder属性之后,开始了整个请求调度过程。
先看第一段:
如果没有url属性,就用name来处理,把>
SpringAOP是利用代理模式,在运行时生成一个目标对象的代理,并且使用代理代替目标对象,整个过程对使用者透明,使用者无法像使用目标对象一样使用代理对象,代理对象类型是目标对象所属类的子类或者接口实现,沙河IT培训认为这个子类也是在运行时动态生成,这个生成子类的过程使用 *** 作字节码技术,Spring框架中使用两种字节码技术:JDK动态代理和CGLIB,当目标类实现了接口时使用JDK动态代理,否则使用CGLIB代理。
AOP的实现包含下面几个步骤:
根据配置或注解解析切面。
生成AOP代理对象,给目标对象生成一个代理类以及代理类实例,根据解析出的切面,生成通知链设置到代理对象,在代理的回调中会执行通知链。
把AOP代理对象注册到容器中代替目标对象,当使用者向容器请求目标bean时,容器会返回代理对象。
下面对这几个步骤逐一的分析。
切面解析
在分析切面解析过程之前,首先先了解一下几个关键的接口,看下面的类图。
PointCut:描述切点,在进行切点匹配时,使用ClassFilter进行类匹配,MethodMatcher进行执行方法匹配。
Advice:通知,AfterAdvice后通知,BeforeAdvice前通知,DynamicIntroductionAdvice引用通知,环绕通知通过Interceptor实现。
Advisor:通知器,也就是切面,PointcutAdvisor切点通知器,IntroductionAdvisor引用通知器。
在创建AOP代理之前需要把相关的切面配置解析成上面类图中的接口子类的对象,对于ProxyFactoryBean来说,没有这个过程,因为这种方式下不能使用切点。
切面解析完成之后,把解析出的通知添加通知链中,AOP代理对象引用该通知链执行切面通知逻辑。对于aop标签方式和注解方式添加通知链这个动作的代码是类似的,解析切面这个过程有些差异。
以上就是关于Spring是怎么用的全部的内容,包括:Spring是怎么用的、设计模式-Spring中常用的设计模式、Spring MVC 面试总结等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)