Spring学习之@CompnentScan

注解说明 @ComponentScan 注解是Spring 提供的对组件进行扫描的注解指令,通常与 @Configuration 注解一起使用,支持在类上重复标注 注解能做什么? 此注解支持以下重要特性: 自定义扫描的包范围 配置包含扫描组件的过滤器 配置排除组件的过滤器 是否使用默认过滤器 是否配置懒加载 源码分析 由于此注解通常与 @Configuration 注解一起使用,其解析的主要逻辑都是在 refresh 阶段的 invokeBeanFactoryPostProcessors 方法中,最终会定位到 ConfigurationClassParser#doProcessConfigurationClass() 方法中,在方法中可以看到对 ComponentScan 注解的操作逻辑了 对注解属性的解析 所有对属性的解析都在 ComponentScanAnnotationParser#parse() 方法中进行,此方法中会创建一个 ClassPathBeanDefinitionScanner 实例scanner,此实例初始化过程中会对默认的Filter进行加载 处理默认Filter主要是 JSR-250 与 JSR-330 API 增加的注解 然后会把配置的 includeFilter 和 excludeFilter 设置到 scanner 中,接着会对 basePackage 扫描包属性进行解析配置,如果配置了就添加,没有配置,默认就使用 @ComponentScan 注解标注类所在的包路径。解析完注解属性后,就开始了真正的扫描操作 扫描操作 扫描操作由 ClassPathBeanDefinitionScanner#doScan() 方法进行处理,此方法会调用 findCandidateComponents() 方法在给定的包下查找符合条件的组件,查找的任务由 scanCandidateComponents() 进行,该方法调用 isCandidateComponent() 方法,根据解析的includeFilter和excludeFilter 来选择满足条件的组件 这样扫描到所有满足条件的Bean后,会接着对这些Bean进行parse操作,直到注解再无其它依赖 注册Bean 扫描完所有Bean后,会调用 checkCandidate() 方法进行检查,检查当前要注册的Bean是否与已经注册过的Bean的定义是否兼容,如果冲突会报 ConflictingBeanDefinitionException 。检查没问题后,会调用 registerBeanDefinition() 方法对Bean进行注册,这个过程就涉及到Spring其它的生命周期了(这个后续专门学习总结),对于@ComponentScan 组件来说已经完成了它的使命 总结 最后以注解解析过程中的涉及的核心类做一下总结 常见问题 调整包结构后一些@Bean配置扫描不到了 调用启动类的包路径为最外层,这样可以扫描当前包及子包的配置 默认只扫描当前标注注解的包,可以通过配置 basePackage 属性指定扫描路径,配置后默认的扫描路径就不生效了 如何将未配置Spring相关组件注解的Bean纳入Spring管理? 可以通过配置 ComponentScan的includeFilter 来实现 ...

2025-05-15 · 1 min · 99 words · tomyli

Spring学习之@Configuration

@Configuration是什么? @Configuration 是 Spring提供的一个用于配置与声明Bean与相应Bean之间依赖的注解,根据文档描述,此注解通常由 AnnotationConfigApplicationContext 上下文进行启动加载 @Configuration能做什么? 先看一下此注解的声明,在此注解上标识了 @Component ,则证明此注解是一个 Component,拥有 @Component 注解的基础能力(可以被Spring容器自动扫描与加载) 上图标识了注解常用的配置方式,分类为以下几种 属性资源导入 引入其它配置类的配置 Value注入 Spring容器组件注入 支持Profile配置 注解属性 在Spring5.x版本中,只支持两个属性配置 value 配置注解的名称 proxyBeanMethods 是否代理增强(基于CGLIB)标识 @Bean 的方法,默认为true,保证声明的bean是单例共享的,而不是每一次通过方法调用都生成一个新的 此属性的两个值被定义为两种模式 full 模式(值为true) lite 模式(值为false) 源码分析 @Configuration 注解的解析类为 ConfigurationClassPostProcessor ,本次主要关注从 AnnotationConfigApplicationContext 启动后的整个处理过程, AnnotationConfigApplicationContext 启动分为三个阶段 先上一张三个阶段的涉及的主要类与调用关系图 初始化 初始化reader 此过程会实例化 AnnotatedBeanDefinitionReader 类,此类在实例化时会调用 AnnotationConfigUtils.registerAnnotationConfigProcessors 来注册解析配置的Processor,如果registry中没有包含 ConfigurationClassPostProcessor 类的定义,则会新new一个 ConfigurationClassPostProcessor 的Bean定义类 整体调用链路如下: 初始化scanner 此过程会实例化Bean定义扫描器 ClassPathBeanDefinitionScanner , 在此过程中主要会设置 Environment 和 ResourceLoader 相关信息 注册 注册阶段主要是对标注了 @Configuration 类(MyConfig)进行注册,以便Spring可以正常识别,主要逻辑在 AnnotatedBeanDefinitionReader#doRegisterBean 中,此方法会调用 BeanDefinitionReaderUtils.registerBeanDefinition 对此Bean进行注册 至此, @Configuration 类信息就注册到了 Spring 容器中 ...

2025-05-09 · 1 min · 202 words · tomyli

众乐乐-weekly 第16期

Read 📖 CLion Is Now Free for Non-Commercial Use | The CLion Blog C编辑器CLion对非商业使用免费了 voideditor/void 开源的Cursor编辑器,基于VSCode开发 BrokkAi/brokk: Brokk brings code intelligence to AI 号称理解代码语法,对于大型项目支持更好的AI工具 奇客Solidot | 食用超加工食品或有害健康 目前超加工食品越来越多,我们被困在了里面 BHznJNs/MotionEaseTune: A simple application that can prevent you from motion sickness via 100Hz sound. 播放100Hz声音来预防晕车的Android应用 Ebrizzzz/Youtube-playlist-to-formatted-text: A desktop application that extracts YouTube playlist transcripts and enhances them using Google’s Gemini AI models. The output is a book in any language you want. 将Youtube列表通过AI转成电子书 ...

2025-05-08 ·  (🌟Updated: 2025-05-16) · 1 min · 125 words · tomyli

Windows相关软件或工具

背景 平常只使用MAC,但是架不Windows的占用率,有一些感兴趣的东西想要记录一下 Win11-23H2-22631.3155_办公版-装机版_【2024.02.28】 – TWM000

2025-04-27 · 1 min · 5 words · tomyli

SpringMVC实践之集成Sentinel限流功能

背景 近期收到线上报警,发现个别新接口在同1s内被请求了接近上百次,对系统的稳定造成了一些影响,近期调研了一下通用的限流框架,打算将Sentinel的限流功能集成进新服务 Sentinel前置知识 Sentinel 限流主要涉及以下几方面 Resource 限流的资源,资源支持动态加载,核心类为: AbstractDataSource ,Sentinel 默认提供了市面常见的资源管理服务的实现,也可以自定义实现 Rule 对定义的 Resouce 应用的限流规则,基于QPS、响应时间与系统负载。Sentinel 是通过一系列的功能Slot来实现不同的统计/控制功能,对于限流功能对应的就是 FlowSlot FlowSlot 的功能实现需要依赖前面的 NodeSelectorSlot 和 ClusterBuilderSlot 等统计Slot,有了统计信息才可以针对配置进行限流操作,这里面借用一张官方的实现图 各Slot默认的顺序也可以在代码中找到 核心处理逻辑 核心逻辑是在执行调用chain的捕获Blockexcption然后执行后续操作 集成步骤 借助SpringMVC中提供的 HandlerInterceptor 拦截器功能 与 Sentinel 提供的SpringMVC框架集成类库可以方便快速的实现限流功能 引入Sentinel SpringMVC Adapter <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-spring-webmvc-adapter</artifactId> <version>1.8.8</version> </dependency> 配置SentinelWebInterceptor Sentinel SpringMVC Adapter中提供了 SentinelWebInterceptor 来实现限流功能,这个 Interceptor 支持一些自定义的行为,主要通过 SentinelWebMvcConfig 来实现 SentinelWebMvcConfig 常用配置说明 SentinelWebMvcConfig 支持以下配置能力 urlCleaner 自定义对请求url的处理,比如厂商此次需要通过请求的设备id维度进行限流,对于其它的请求参数都进行忽略,最终可定义效果为: /api/v1/test/ping?did=6308103f1026acf274bbcc1b10001291551xxX httpMethodSpecify 是否指定特定的Http请求方法,此设置是对资源的请求方法进行了细粒度的配置,默认为false不开启,配置为true后,会在设定好的资源名前加上请求的方法,类似效果: GET: /api/v1/test/ping?did=6308103f1026acf274bbcc1b10001291551xxX blockExceptionHandler 被Block的请求异常处理器,对Block的请求进行自定义处理,可以设置返回的值,如果未配置则需要服务自己捕获 BlockException,可以通过配置 ExceptionHandler 进行统一处理 originParser 请求来源处理器,针对请求的来源进行处理,在配置资源的规则的可以使用此解析的origin细粒度控制,例如可以解析ip、用户做为请求 origin ...

2025-04-25 · 1 min · 131 words · tomyli

众乐乐-weekly 第15期

Read 📖 Cherry Studio 网络搜索与知识库最佳实践 奇客Solidot | YouTube 用户上传了 20 万亿则视频 20年,20万亿的视频,惊到了 如何避免在 AI 时代技能退化 | 宝玉的分享 把AI当做协作者,而不是拐杖,做了一个完整独立的人 Tools 🧰 the-via/app 改键神器,如果使用中老是卡在查找设备的页面,可以在设置中改成3D模式 Image 🖼️ Speech 💬 天不生人上之人,也不生人下之人 规则就像汽车上的安全带:一开始可能会有点不舒服,但一段时间后,使用规则就会成为习惯,不使用规则就变得不可想象。 Idea 💡

2025-04-22 ·  (🌟Updated: 2025-05-06) · 1 min · 30 words · tomyli

SpringMVC学习之HandlerMapping

起因 新服务在处理不存在的url请求时,上报日志报错,具体错误信息: 根据报错信息找到相关代码 代码处做了对参数hanler的强制转换,但是真正传入的参数类型为 ResourceHttpRequestHandler 导致转换失败而报错,梳理一下,handler是在 自定义的日志Interceptor 的afterCompletion方法中由框架传入的 ResourceHttpRequestHandler 是什么? 查阅类文档,ResourceHttpRequestHandler是SpringMVC提供的处理静态资源的Handler,比如常见的js或者css文件。在当前前后端分离的分工下,对于REST服务开发,不会再使用这种方式提供对静态资源的访问,为什么请求了一个不存在的url,会使用静态资源的Hanlder来处理? SpringMVC提供了哪些HandlerMapping? SpringMVC提供的HanlderMapping位于 org.springframework.web.servlet.handler 包下,主要包含 Mapping Desc RequestMappingHandlerMapping 处理@RequestMapping 注解映射关系 SimpleUrlHandlerMapping 使用URL模式匹配映射关系 BeanNameUrlHandlerMapping 基于Bean名匹配映射关系 SpringMVC 路径映射流程回顾 回顾一下SpringMVC的路径映射流程,通常的url请求的编码方式为: @RequestMapping("/ping") public Response<String> ping() { return Response.success("pong"); } 标识了 @RequestMapping 注解的方法会被 SpringMVC 框架的 RequestMappingHandlerMapping 类在启动时进行扫描并根据映射信息来创建 RequestMappingInfo(RequestMappingInfo 类维护请求的映射信息),扫描后的所有Mapping信息在 MappingRegistry(AbstractHandlerMethodMapping内部类) 类进行维护 SpringMVC如何处理request与HandlerMethod的映射关系 AbstractHandlerMethodMapping的getHandler 方法用来通过给定的request来找到一个合适的handler进行处理 getHandler会先调用抽象方法 getHandlerInternal 由子类实现查找逻辑,如果找不到,则查找默认配置的Hanlder,默认Hanlder找不到则返回null SpringMVC默认使用了哪些HandlerMapping 如何查询Handler是在 DispacherServlet的getHandler方法操作的,它会在所有的handlerMappings(有序handlerMapping)中查找出一个可用的handler进行request的处理 如图可知会在7个handlerMapping中依次进行查询,这些handlerMapping是在 DispatcherServlet#initHandlerMappings() 设置的 定位到问题原因 跟踪请求代码发现对于不存在的url会在 SimpleUrlHanlderMapping中找到可用的handler,因为最终请求url匹配上了 /**,而 /** 模式对应的handler就是 ResourceHttpRequestHandler,此时getHandler的结果就是ResourceHttpRequestHandler 了,但是在上报时使用的是 HandlerMethod,执行到此时报了转换异常 WebMvcAutoConfiguration中的SourceHandler在哪注册的? 在启用MVC功能时,会增加注解 @EnableWebMvc,而对应的MVC配置类为 WebMvcConfigurationSupport,在这个类中进行SourceHandler的注册。跟踪代码发现两个ResourceHandler是在 WebMvcAutoConfigurationAdapter中添加的 ...

2025-04-18 · 1 min · 72 words · tomyli

众乐乐-weekly 第14期

Read 📖 中国民航局颁发首批飞行出租车运营合格证 看了一下宣传片,有机会要体验一下,空间上感觉坐两个人有些拥挤 JetBrains IDEs Go AI: Coding Agent, Smarter Assistance, Free Tier | The JetBrains Blog JetBrains在最新的版本提供了可以免费使用的AI,目前看只有一个模型:Qwen Max Tools 🧰 Vivaldi Browser | Powerful, Personal and Private web browser 由于近期的 FireFox 事件,要多装几个注重隐私的浏览器 Windsurf Editor | Windsurf (formerly Codeium) AI编辑器,大量使用价格具有性价比 pypa/pipx: Install and Run Python Applications in Isolated Environments 更方便的在隔离环境运行Python应用 nomic-ai/gpt4all: GPT4All: Run Local LLMs on Any Device. Open-source and available for commercial use. 在命令行运行本地大模型,跨平台支持 ProNotes 对Mac 的Notebook进行样式增强的APP,Pro版本带AI功能 Image 🖼️ Speech 💬 任何时候,都不要放弃自己的思考 ...

2025-04-14 ·  (🌟Updated: 2025-04-30) · 1 min · 76 words · tomyli

SpringMVC学习之Exception处理

背景 开发过程中,会出现很多异常情况,比如RPC调用异常、请求参数异常,SpringMVC是如何处理异常信息的? Spring处理异常的方式 Spring采用了全局的异常捕获统一处理的方式,虽然JAVA的异常机制一直有争议,但是Spring还是选择基于实际开发需要使用抛异常后捕获统一处理的方式 HandlerExceptionResolver登场 HandlerExceptionResolver 是SpringMVC提供的解析Handler调用过程抛出异常的解析器,只提供了一个解析异常的方法 resovleException Spring提供了哪些ExceptionResolver? 经典的Interface-Abstract方式的实现类 Resolver Desc SimpleMappingExceptionResolver 提供exception class name到view的映射 DefaultHandlerExceptionResolver 默认Resolver实现,用于解析标准的SpringMVC异常并转换成对应的Http状态码 ResponseStatusExceptionResolver 基于 @ResponseStatus 注解来映射异常与Http状态码 ExceptionHandlerExceptionResolver 基于 @ExceptionHalder 注解来解析处理异常信息 直接实现HandlerExceptionResolver的类 Resolver Desc DefaultErrorAttributes 默认错误属性实现 HandlerExceptionResolverComposite 代理其它Resolver集合的ExceptionResolver HandlerExceptionResolverComposite 中包含了一个解析列表,可以判断是会排序后顺序调用,以找到第一个可以处理的Resolver 具体异常处理流程 异常处理的核心逻辑都在 processHandlerException 方法中,Spring处理完请求后,如果有异常抛出,则会把异常信息传给 processHandlerException 方法, processHandlerException 遍历持有的 handlerExceptionResolvers 进行对异常的解析,如果解析成功则直接返回对应的 ModelAndView(此返回与正常的handler处理返回保持了一致) handlerExceptionResolvers 有哪些? 在 SpringMVC启动时会调用 initHandlerExceptionResolvers 方法来查找所有可用的 handlerExceptionResolver 并保存到 handlerExceptionResolvers 变量中。SpringMVC配置了两个 resolver 来提供异常解析 errorAttributes 此Resolver是在 ErrorMvcAutoConfiguration 进行实例化的 此实现的 resolverExcption 方法逻辑简单,直接返回了null,不是关注重点 handlerExceptionResolver 此Resolver真正的实现类为 HandlerExceptionResolverComposite ,也就是持有多个ExceptionResolver列表的 Resolver,它是在 WebMvcConfigurationSupport 实例化的 ...

2025-04-14 ·  (🌟Updated: 2025-04-18) · 1 min · 139 words · tomyli

SpringMVC统一配置接口WebMvcConfigurer功能

接口说明 WebMvcConfigurer是Spring提供的统一配置接口,用于自定义Spring MVC的配置,全局更改服务的行为,提供的可配置项: 方法名称 参数 用途 addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) List<HandlerMethodArgumentResolver> argumentResolvers 添加自定义的 HandlerMethodArgumentResolver 用于解析方法参数。 addCorsMappings(CorsRegistry registry) CorsRegistry registry 配置跨域资源共享 (CORS) addFormatters(FormatterRegistry registry) FormatterRegistry registry 添加自定义的格式化程序和转换器 addInterceptors(InterceptorRegistry registry) InterceptorRegistry registry 添加自定义的拦截器 addRequestMappings(RequestMappingInfo customization, Class<Controller> controllerClass) RequestMappingInfo customization, Class<Controller> controllerClass 关联自定义请求映射到具控制器类 addResourceHandlers(ResourceHandlerRegistry registry) ResourceHandlerRegistry registry 配置资源处理,如静态资源路径 addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) List<HandlerMethodReturnValueHandler> returnValueHandlers 添加自定义的 HandlerMethodReturnValueHandler 用于处理方法返回值 addViewControllers(ViewControllerRegistry registry) ViewControllerRegistry registry 注册视图控制器 configureAsyncSupport(AsyncSupportConfigurer configurer) AsyncSupportConfigurer configurer 配置异步支持 configureContentNegotiation(ContentNegotiationConfigurer configurer) ContentNegotiationConfigurer configurer 配置内容协商策略 configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) DefaultServletHandlerConfigurer configurer 启用默认 Servlet 处理 configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) List<HandlerExceptionResolver> exceptionResolvers 配置异常处理程序 configureMessageConverters(List<HttpMessageConverter<?>> converters) List<HttpMessageConverter<?>> converters 配置自定义的 HttpMessageConverter configurePathMatch(PathMatchConfigurer configurer) PathMatchConfigurer configurer 配置路径匹配规则 configureViewResolvers(ViewResolverRegistry registry) ViewResolverRegistry registry 配置视图解析器 extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) List<HandlerExceptionResolver> exceptionResolvers 扩展异常处理程序 extendMessageConverters(List<HttpMessageConverter<?>> converters) List<HttpMessageConverter<?>> converters 扩展自定义的 HttpMessageConverter extendInterceptors(List<HandlerInterceptor> interceptors) List<HandlerInterceptor> interceptors 扩展拦截器 extendArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) List<HandlerMethodArgumentResolver> argumentResolvers 扩展自定义的 HandlerMethodArgumentResolver 用于解析方法参数。 extendReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) List<HandlerMethodReturnValueHandler> returnValueHandlers 扩展自定义的 HandlerMethodReturnValueHandler 用于处理方法返回值。 extendViewResolvers(List<ViewResolver> viewResolvers) List<ViewResolver> viewResolvers 扩展视图解析器 关联类 WebMvcConfigurationSupport EnableWebMvc 接口常用方法 接口提供了将近20个方法对Spring的配置进行调整,本次只针对常用的Rest接口开发相关内容进行展开学习研究 ...

2025-03-28 · 3 min · 461 words · tomyli