1.Ribbon负载均衡分析
2.Nacos 1.4.1源码解析之服务注册--AP
3.SpringBoot源码学习——SpringBoot自动装配源码解析+Spring如何处理配置类的自动装配自动装配
4.@autowired注解有什么用?
Ribbon负载均衡分析
Ribbon使用介绍
Ribbon的使用非常简单,只需要在配置类中添加相应的源码源码配置即可。调用时,设置通过服务名在Eureka中注册的自动装配自动装配服务进行调用,Ribbon则自动进行负载均衡。源码源码以zhao-service-resume项目为例,设置甲壳虫源码开启多个服务实例并打印请求信息,自动装配自动装配即能观察到负载均衡的源码源码效果。Ribbon默认采用随机负载均衡策略(RandomRule),设置该策略全局生效,自动装配自动装配但可根据需求为不同服务设置不同的源码源码负载均衡策略。
Ribbon源码解析
自动装配类是设置配置加载的入口,例如LoadBalancerAutoConfiguration类。自动装配自动装配通过配置,源码源码LoadBalancerAutoConfiguration会自动注入带有@LoadBalanced注解的设置RestTemplate对象,并注入定制器RestTemplateCustomizer。在定制器代码中,添加了ClientHttpRequestInterceptor拦截器,该拦截器根据请求路径和地址执行负载均衡逻辑。最终,执行负载均衡策略选择服务端进行请求,实现负载均衡。服务列表的获取与更新在RibbonAutoConfigration中的SpringClientFactory和RibbonClientConfiguration类中实现,通过定时任务在ZoneAwareLoadBalancer的父类DynamicServerListLoadBalancer中重新赋值与更新服务列表。
Nacos 1.4.1源码解析之服务注册--AP
nacos的使用方法在zhuanlan.zhihu.com/p/...有详细介绍。 在启动nacos Client时,首先开启自动装配功能,接着初始化discovery配置参数。bugcheck源码紧接着,注册NacosServiceRegistry,然后注册服务自动注册bean NacosAutoServiceRegistration。在Spring容器启动完成时,启动发布监听事件。此过程中,NacosAutoServiceRegistration实现ApplicationListener,监听springBoot web容器启动事件,于Spring容器启动的finishRefresh阶段启动web容器后发布。接收到消息后执行onApplicationEvent,设置服务端口。 服务元数据初始化通过NacosRegistration,用户可以通过配置文件配置,或使用API进行服务注册。服务注册通过rest请求至/nacos/v1/ns/instance实现,官方文档提供详细指导。 nacos server端的API服务主要由com.alibaba.nacos.naming.controllers.InstanceController入口控制。它采用缓存结构,第一层为namespace,第二层为group分组。在service中,clusterMap按照集群分组,集群内才是实例列表。在添加、修改实例或基于集群纬度修改实例时,使用copyOnWrite方式替换。流程图展示基本操作流程。Vuestore源码SpringBoot源码学习——SpringBoot自动装配源码解析+Spring如何处理配置类的
SpringBoot通过SPI机制,借助外部引用jar包中的META-INF/spring.factories文件,实现引入starter即可激活功能,简化手动配置bean,实现即开即用。
启动SpringBoot服务,通常使用Main方法启动,其中@SpringBootApplication注解包含@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan,自动装配的核心。
深入分析@SpringBootApplication,其实质是执行了@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三个注解的功能,简化了配置过程,强调了约定大于配置的思想。
SpringBoot的自动装配原理着重于研究如何初始化ApplicationContext,Spring依赖于ApplicationContext实现其功能,SpringApplication#run方法为初始化ApplicationContext的入口。
分析SpringApplication构造方法,SpringApplication.run(启动类.class, args) 实际调用的是该方法,其关键在于根据项目类型反射生成合适的ApplicationContext。
选择AnnotationConfigServletWebServerApplicationContext,此上下文具备启动Servlet服务器和注册Servlet或过滤器类型bean的能力。
准备刷新ApplicationContext,SpringBoot将主类注册到Spring容器中,telnetlib源码以便@ConfigurationClassPostProcessor解析主类注解,发挥@Import、@ComponentScan的作用。
刷新ApplicationContext过程包括一系列前置准备,如将主类信息封装成AnnotatedGenericBeanDefinition,解析注解并调用BeanDefinitionCustomizer自定义处理。
解析配置类中的注解,通过BeanDefinitionRegistryPostProcessor和ConfigurationClassParser实现,筛选、排序候选者,并解析@Import注解实现自动装配。
增强配置类,ConfigurationClassPostProcessor对full模式的配置进行增强,确保@Import正确处理,CGLIB用于增强原配置类,确保生命周期完整,避免真正执行@Bean方法逻辑。
深入解析AutoConfigurationImportSelector实现自动装配,通过spring.boot.enableautoconfiguration设置开启状态,读取spring-autoconfigure-metadata.properties和META-INF/spring.factories文件,筛选并加载自动配置类。
@autowired注解有什么用?
最近在审查代码时,注意到一些@Autowired注解的非典型用法,觉得颇为有趣,于是花时间深入研究,发现了不少有价值的信息,现在与大家分享。getclientrect源码 @Autowired可能比你想象的更为强大。1. 默认装配方式
我们知道,在Spring中,@Autowired注解主要用于自动装配对象。通常,我们在项目中这样使用: 是的,这样做确实能够实现装配,因为默认情况下,Spring会按照类型进行装配,即byType方式。 另外,@Autowired注解的required参数默认设为true,表示开启自动装配,若不希望使用自动装配功能,可通过将其设为false来实现。2. 相同类型的对象不止一个时
byType方式主要针对对象类型唯一的情况,当对象类型不唯一时,会出现问题。 例如,在项目的test目录下创建了一个名为TestService1的类。重启项目时,会报错,提示类名冲突,导致项目无法启动。 需要注意的是,这种情况与在@Autowired时出现两个相同类型的对象无关,容易引起混淆。问题是由于Spring的@Service方法不允许出现相同类名,而类名首字母转换为小写作为bean名称,如testService1,且默认情况下bean名称必须唯一。3. 使用@Qualifier和@Primary
显然,按照默认的byType装配方式,无法解决上述问题,此时可改用byName装配方式。 只需在代码中添加@Qualifier注解即可解决。 只需进行这样的调整,项目就能正常启动。 @Qualifier意味着“合格者”,通常与@Autowired结合使用,通过指定bean名称来找到需要装配的bean。 除了使用@Qualifier注解外,还可以使用@Primary注解解决相同类型bean的问题。在User1上加上@Primary注解,移除UserService上的@Qualifier注解。 重新启动项目,同样能正常运行。 当使用自动配置方式装配Bean时,若有多个候选者,其中一个带有@Primary注解,该候选者会被选中作为自动配置的值。4. @Autowired的使用范围
在成员变量上使用@Autowired注解是常见的用法。除此之外,它还能应用于其他场景。 下面总结一下@Autowired注解的使用方式:4.1 成员变量
在成员变量上使用@Autowired注解是常见用法。4.2 构造器
在构造器上使用@Autowired注解,实际上还是使用了@Autowired装配方式,而非构造器装配。4.3 方法
在普通方法上添加@Autowired注解,spring会在项目启动时调用一次该方法,我们可在该方法中执行初始化工作。 同样可以在setter方法上使用@Autowired注解。4.4 参数
构造器的入参上可使用@Autowired注解,非静态方法的入参上也可使用。4.5 注解
使用@Autowired注解的注解实例相对较少,因此这里不再过多介绍。5. @Autowired的高级玩法
虽然上面的例子都是自动装配单个实例,但事实上,它也能自动装配多个实例。让我们看看是怎么实现的。 调整UserService方法,使用List集合接收IUser类型的参数。 增加一个controller,调用该接口。 通过观察结果,可以发现userList、userSet和userMap都打印出了两个元素,说明@Autowired会自动收集相同类型的IUser对象到集合中。 这种功能令人惊讶,令人惊喜!6. @Autowired装配是否一定成功?
前面介绍了@Autowired注解的强大功能,但有些情况下,即使使用了@Autowired仍然装配失败,这是为什么呢?6.1 没有加@Service注解
在类上忘记添加@Controller、@Service、@Component、@Repository等注解,Spring将无法完成自动装配功能,例如: 这种错误是最常见的,不会因为你长得帅,就避免犯这种低级错误。6.2 注入Filter或Listener
Web应用启动顺序为:listener->filter->servlet。 接下来我们看看这个案例: 程序启动会报错,提示tomcat无法正常启动。 原因是什么? 众所周知,springmvc的启动在DisptachServlet中完成,而它是在listener和filter之后执行。如果在listener和filter中使用@Autowired注入某个bean,肯定不行,因为filter初始化时,此时bean尚未初始化,无法自动装配。 如果在工作中真的需要这样做,该如何解决呢? 答案是使用WebApplicationContextUtils.getWebApplicationContext获取当前的ApplicationContext,再通过它获取bean实例。6.3 注解未被@ComponentScan扫描
通常情况下,@Controller、@Service、@Component、@Repository、@Configuration等注解需要通过@ComponentScan注解进行扫描,收集元数据。 但如果没有添加@ComponentScan注解,或其扫描路径错误或范围过小,可能导致注解收集不全,进而无法使用@Autowired完成自动装配。 好消息是,在springboot项目中,使用了@SpringBootApplication注解内置了@ComponentScan的功能。6.4 循环依赖问题
如果A依赖于B,B依赖于C,C又依赖于A,形成死循环。 Spring的bean默认是单例的,大多数情况下,能解决循环依赖问题。 但若bean是多例的,会引发循环依赖问题,导致自动装配失败。 还有些情况下,即使创建了代理对象,即使bean是单例的,也可能出现循环依赖问题。 如果你对循环依赖问题感兴趣,可以参考我的另一篇专题《》,其中详细介绍了相关内容。7. @Autowired与@Resource的区别
@Autowired功能强大,但也存在一些不足,比如它与Spring强耦合,换用其他框架功能失效。而@Resource是JSR-提供的,是Java标准,大部分框架都支持。 除此之外,在某些场景下,使用@Autowired无法满足需求,而使用@Resource则能解决问题。接下来,我们来看看@Autowired与@Resource的区别。 另外,它们的装配顺序不同。 @Autowired的装配顺序如下: @Resource的装配顺序如下:后记
原本计划接着分析@Autowired的原理和源码解读,但由于篇幅过长,不适合合并在一起,我打算另开一个专题。如果你对这个话题感兴趣,请持续关注我后续的文章,相信你一定能从中有所收获。