Spring
参数校验注解
- Spring框架提供了许多参数校验注解,以下是一些常用的注解及其作用解释:
| 注解 | 可修饰的属性类型 | 属性作用解释 |
|---|---|---|
| @NotNull | 所有类型 | 用于验证对象是否为null |
| @NotEmpty | String, Collection, Map, Object数组等 | 用于验证对象是否为空 |
| @NotBlank | String, CharSequence, Date, Pattern等 | 用于验证对象是否为空或仅包含空白字符 |
| @Min | int, long, float, double, BigDecimal等 | 用于验证数值是否大于等于指定值 |
| @Max | int, long, float, double, BigDecimal等 | 用于验证数值是否小于等于指定值 |
| @Size | String, Collection, Map等 | 用于验证对象的大小(长度、数量等) |
| @DecimalMin | BigDecimal | 用于验证数值是否大于等于指定的最小值 |
| @DecimalMax | BigDecimal | 用于验证数值是否小于等于指定的最大值 |
| @Digits | String, BigDecimal等 | 用于验证数值的位数 |
| @Past | LocalDate | 用于验证日期是否在当前日期之前 |
| @Future | LocalDate | 用于验证日期是否在当前日期之后 |
| @Pattern | String, java.util.regex.Pattern | 用于验证字符串是否符合指定的正则表达式模式 |
| String | 用于验证字符串是否符合电子邮件地址格式 | |
| @Positive | int, long, float, double等 | 用于验证数值是否为正数 |
| @Negative | int, long, float, double等 | 用于验证数值是否为负数 |
| @PastOrPresent | LocalDate | 用于验证日期是否在过去或现在 |
| @FutureOrPresent | LocalDate | 用于验证日期是否在未来或现在 |
| @ElementType | Class | 用于验证集合元素类型 |
| @AssertTrue | boolean | 用于验证布尔值是否为true |
| @AssertFalse | boolean | 用于验证布尔值是否为false |
| @AssertNull | Object | 用于验证对象是否为null |
| @AssertNotEmpty | String, Collection, Map, Object数组等 | 用于验证对象是否为空 |
| @AssertNotBlank | String, CharSequence, Date, Pattern等 | 用于验证对象是否为空或仅包含空白字符 |
| @AssertLessThan | int, long, float, double, BigDecimal等 | 用于验证数值是否小于指定值 |
| @AssertGreaterThan | int, long, float, double, BigDecimal等 | 用于验证数值是否大于指定值 |
| @AssertArrayLength | String, Collection, Map等 | 用于验证集合或数组的长度 |
| @JsonFormat | String, Date, LocalDateTime等 | 用于验证JSON字符串是否符合指定的格式 |
| @ClockDelta | long | 用于验证时间戳之间的巟 |
跨域
SpringBoot 优雅配置跨域多种方式及Spring Security跨域访问配置的坑 - 程序员三时 - 博客园 (cnblogs.com)
拦截器方式
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")//项目中的所有接口都支持跨域
.allowedOriginPatterns("*")//所有地址都可以访问,也可以配置具体地址
.allowCredentials(true)
.allowedMethods("*")//"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"
.maxAge(3600);// 跨域允许时间
}
}
Filter - 1
@Bean
public CorsFilter corsFilter() {
//1.添加CORS配置信息
CorsConfiguration config = new CorsConfiguration();
//放行哪些原始域
config.addAllowedOrigin("*");
//是否发送Cookie信息
config.setAllowCredentials(true);
//放行哪些原始域(请求方式)
config.addAllowedMethod("*");
//放行哪些原始域(头部信息)
config.addAllowedHeader("*");
//暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
config.addExposedHeader("*");
//2.添加映射路径
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
//3.返回新的CorsFilter.
return new CorsFilter(configSource);
}
Filter - 2 Servlet的原始方式
@Slf4j
@Component
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse)servletResponse;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization");
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
filterChain.doFilter(servletRequest,response);
}
}
Spring Security启用CORS支持
如果项目中使用了Spring Security 配置了上面跨越方式还不行,需要单独指定Spring Security跨域,否则跨越不会生效;
Spring Security对CORS提供了非常好的支持,只需在配置器中启用CORS支持,并编写一 个CORS配置源即可
@Override
protected void configure(HttpSecurity http) throws Exception {
// We don't need CSRF for this example
http.cors().and().csrf().disable()
// dont authenticate this particular request
.authorizeRequests().antMatchers("/", "/*.html", "/favicon.ico", "/css/**", "/js/**", "/fonts/**", "/layui/**", "/img/**",
"/v3/api-docs/**", "/swagger-resources/**", "/webjars/**", "/pages/**", "/druid/**",
"/statics/**", "/login", "/register").permitAll().
// all other requests need to be authenticated
anyRequest().authenticated().and().
// make sure we use stateless session; session won't be used to
// store user's state.
//覆盖默认登录
exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
// 基于token,所以不需要session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Add a filter to validate the tokens with every request
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOriginPattern("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
——————————
SpringMVC
Model-View-Controller
应用系统三层架构:
- C/S架构:客户端/服务器架构
- B/S架构:浏览器/服务器架构
Java开发的大多是web应用,是基于B/S架构开发的。JavaEE指定了一套规范,去进行BS结构的处理,这套规范就是Servlet。
B/S架构中,应用系统标准的三层架构为: 表现层、业务层、持久层。
表现层(Web层)
- 负责接收客户端请求,向客户端响应结果,通常客户端使用http协议请求 web,web层需要接收 http请求,完成http响应。
- 表现层包括展示层和控制层:控制层负责接收请求,展示层负责结果的展示。
- 表现层依赖业务层,接收到客户端请求一般会调用业务层进行业务处理,并将处理结果响应给客户端。
- 表现层的设计一般都使用 MVC 模型。 MVC 是表现层的设计模型,和其他层没有关系。
业务层 (Service层)
- 它负责业务逻辑处理,和我们开发项目的需求息息相关。web层依赖业务层,但是业务层不依赖Web层。
- 业务层在业务处理时可能会依赖持久层,如果要对数据持久化需要保证事务一致性。 (事务应该放到业务层来控制)
持久层 (dao 层)
负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进行持久化的载体,数据访问层是业务层和持久层交互的接口;业务层需要通过数据访问层将数据持久化到数据库中。
持久层就是和麵库交互,对麵库表进行曽删改査的。
MVC组件:前端控制器、处理器、视图
三大组件:处理器映射器、处理器适配器、视图解析器
需要开发的组件:处理器、视图(前后端分离后,后端不需要开发)
MVC 设计模式
MVC是模型(model)-视图(view)-控制器(controller)的缩写,是一种用于设计编写Web应用程序表现层的
模式。
MVC设计模式的三大角色:
Model (模型)
模型包含业务模型和数据模型,数据模型用于封装数据,业务模型用于处理业务。
View (视图)
通常指的就是我们的jsp或者html。作用一般就是展示数据的。
通常视图是依据数据模型创建的。
Controller (控制器)
是应用程序中处理用户交互的部分。作用一般就是处理程序逻辑的。
SpringMVC六大组件
MVC组件:前端控制器、处理器、视图
三大组件:处理器映射器、处理器适配器、视图解析器
需要开发的组件:处理器、视图(前后端分离后,后端不需要开发)
常用拦截器、解析器、过滤器等接口
以下是 Spring MVC 中常用的拦截器(Interceptor)、解析器(Resolver)、转换器(Converter)、过滤器(Filter)、监听器(Listener)等接口及其功能的列表。这些接口提供了丰富的扩展点,允许开发者在请求处理的不同阶段进行自定义处理。
| 接口 | 功能 | 主要方法/回调 |
|---|---|---|
| 拦截处理器的执行,可用于权限检查(从请求头获取JWT的token等)、日志记录等 | preHandle、postHandle、afterCompletion | |
| WebRequestInterceptor | 与 HandlerInterceptor 相似,但更加通用,不依赖于 Spring | preHandle、postHandle、afterCompletion |
| 处理器映射,用于确定请求对应的处理器 | getHandler | |
| 处理器适配器,用于调用处理器并处理请求 | handle | |
| 视图解析器,用于根据逻辑视图名解析出真正的视图 | resolveViewName | |
| MultipartResolver | 处理文件上传请求 | resolveMultipart |
| LocaleResolver | 解析请求的区域信息 | resolveLocale |
| ThemeResolver | 解析主题(样式)信息 | resolveThemeName |
| 异常处理器,用于处理控制器中抛出的异常 | resolveException | |
| FlashMapManager | 用于处理重定向时的 Flash Map | saveOutputFlashMap、retrieveAndUpdateFlashMap |
| ContentNegotiationStrategy | 内容协商策略,用于确定请求的响应格式 | resolveMediaTypes |
| ViewNameTranslator | 视图名称翻译器,用于根据请求和响应翻译视图名称 | getViewName |
| RequestToViewNameTranslator | 根据请求翻译为视图名称 | getViewNameForRequest |
| PathMatcher | 路径匹配器,用于确定请求的路径匹配关系 | match |
| UrlPathHelper | URL 路径助手,用于获取和处理 URL 路径 | getLookupPathForRequest、getPathWithinApplication |
| RedirectView | 处理重定向的视图 | renderMergedOutputModel |
| TilesView | 集成 Apache Tiles 的视图 | renderMergedOutputModel |
| FreeMarkerConfigurer | FreeMarker 模板配置 | configure |
| VelocityConfigurer | Velocity 模板配置 | configure |
| ContentNegotiationManager | 内容协商管理器 | resolveMediaTypes |
| DataBinderInitializer | 数据绑定初始化器 | initBinder |
| ServletContextInitializer | Servlet 上下文初始化器 | onStartup |
| ConversionService | 类型转换服务 | convert |
| HttpMessageConverter | HTTP 消息转换器 | read、write |
| FormatterRegistry | 格式化注册器 | addFormatter |
| PathMatcher | 路径匹配器 | match |
| 过滤器 | doFilter、init、destroy | |
| 处理方法参数的解析器 | resolveArgument | |
| 处理方法返回值的处理器 | handleReturnValue | |
| HttpRequestHandler | 处理 HTTP 请求的处理器 | handleRequest |
| HttpMessageReader | HTTP 消息读取器 | read |
| HttpMessageWriter | HTTP 消息写入器 | write |
| MessageCodeResolver | 消息代码解析器 | resolveMessageCodes |
| LocaleContextResolver | 区域上下文解析器 | resolveLocaleContext |
| HttpServletRequestWrapper | HTTP 请求包装器 | getHeader |
| HttpServletResponseWrapper | HTTP 响应包装器 | addHeader |
| FilterRegistrationBean | 过滤器注册 Bean,用于动态注册过滤器 | setFilter |
| ServletContextInitializer | Servlet 上下文初始化器 | onStartup |
| ServletRegistrationBean | Servlet 注册 Bean,用于动态注册 Servlet | setServlet |
| ServletListenerRegistrationBean | Servlet 监听器注册 Bean,用于动态注册监听器 | setListener |
| SimpleMappingExceptionResolver | 简单的异常处理器,用于将异常映射到视图 | resolveException |
| EmbeddedServletContainerCustomizer | 内嵌 Servlet 容器自定义器 | customize |
| DispatcherServletWebRequest | Servlet Web 请求对象封装,实现了 WebRequest 接口 | getRequest |
| HandlerMethodArgumentResolverComposite | 处理方法参数的解析器组合 | resolveArgument |
| RequestToViewNameTranslator | 根据请求翻译为视图名称 | getViewNameForRequest |
| ConfigurableWebBindingInitializer | Web 数据绑定初始化器 | initBinder |
| MessageSource | 消息源,用于国际化消息的获取 | getMessage |
| ApplicationListener | 应用事件监听器 | onApplicationEvent |
| ApplicationContextAware | 实现该接口的 Bean 可以获取 ApplicationContext | setApplicationContext |
| ServletContextAware | 实现该接口的 Bean 可以获取 ServletContext | setServletContext |
请注意,上述表格中只列出了一些常见的接口和功能,Spring MVC 还提供了更多的接口和功能用于满足不同场景下的需求。在实际应用中,根据具体的业务需求,可以选择性地实现这些接口,以实现自定义的功能扩展。
配置接口
以下是 Spring MVC 提供的主要配置接口及其功能,以表格形式展示:
| 接口 | 功能 | 主要方法/回调 |
|---|---|---|
WebMvcConfigurer | Spring MVC 配置的主要接口,用于配置全局性的 MVC 特性 | addInterceptors、configureViewResolvers、addViewControllers、addCorsMappings 等 |
WebMvcConfigurerAdapter | WebMvcConfigurer 接口的适配器实现,可以用于简化配置 | 同 WebMvcConfigurer |
ViewResolverRegistry | 视图解析器注册表,用于配置视图解析器 | viewResolver、defaultView、viewNames 等 |
InterceptorRegistry | 拦截器注册表,用于配置拦截器 | addInterceptor |
DefaultServletHandlerConfigurer | 配置默认的 Servlet 处理器,用于处理静态资源 | enable |
ResourceHandlerRegistry | 静态资源处理器注册表,用于配置静态资源的映射 | addResourceHandler、setCachePeriod 等 |
PathMatchConfigurer | 路径匹配规则配置器,用于配置路径匹配规则 | setUseSuffixPatternMatch、setUseTrailingSlashMatch 等 |
ContentNegotiationConfigurer | 内容协商策略配置器,用于配置内容协商策略 | favorPathExtension、ignoreAcceptHeader 等 |
AsyncSupportConfigurer | 异步请求支持配置器,用于配置异步请求支持 | configureAsyncSupport、setDefaultTimeout 等 |
CorsRegistry | 跨域请求配置器,用于配置跨域请求 | addMapping、allowedMethods 等 |
ViewRegistration | 视图注册器,用于配置视图解析器的视图注册 | setViewName、setViewClass、setContentType 等 |
ViewControllerRegistry | 简单的视图控制器注册表,用于配置简单的视图控制器 | addViewController、setViewName 等 |
这些接口提供了广泛的配置选项,使开发者能够灵活地定制 Spring MVC 应用程序的行为,包括拦截器、视图解析器、静态资源处理、异步请求支持等。在实际应用中,可以根据具体需求实现这些接口或者通过配置方法进行定制。
拦截器接口
以下是 Spring MVC 提供的主要拦截器接口及其功能,以表格形式展示:
| 接口 | 功能 | 主要方法/回调 |
|---|---|---|
HandlerInterceptor | 拦截处理器的执行,可用于权限检查、日志记录等 | preHandle、postHandle、afterCompletion |
WebRequestInterceptor | 与 HandlerInterceptor 相似,但更加通用,不依赖于 Spring | preHandle、postHandle、afterCompletion |
AsyncHandlerInterceptor | 异步处理器拦截器,用于在异步请求的不同阶段进行拦截 | preHandle、postHandle、afterConcurrentHandlingStarted |
LocaleChangeInterceptor | 区域变更拦截器,用于在请求中切换区域 | preHandle |
ThemeChangeInterceptor | 主题变更拦截器,用于在请求中切换主题 | preHandle |
这些拦截器接口提供了灵活的扩展点,允许开发者在请求处理的不同阶段进行自定义处理。在实际应用中,可以通过实现这些接口,注册拦截器并配置相应的拦截规则,以实现对请求的拦截和处理。
过滤器接口
Spring MVC本身并没有提供专门的过滤器接口。过滤器通常是在Servlet规范中定义的,而Spring MVC是基于Servlet的。在Spring MVC中,通常使用Filter接口,该接口在javax.servlet包中定义。
以下是Filter接口及其功能,以表格形式展示:
| 接口 | 功能 | 主要方法/回调 |
|---|---|---|
Filter | 过滤器接口,用于在请求到达Servlet之前或之后进行过滤处理 | doFilter、init、destroy |
在Spring MVC中,过滤器可以通过配置在web.xml文件中,也可以通过FilterRegistrationBean进行Java配置。在配置过滤器时,通常需要指定过滤器的名称、类名以及过滤器的映射路径等信息。过滤器的主要作用是对HTTP请求进行预处理或后处理,例如进行日志记录、字符编码转换、权限检查等操作。
解析器接口
Spring MVC 提供了多个解析器(Resolver)接口,用于处理请求中的不同方面,例如视图解析、主题解析、区域解析等。以下是一些常见的解析器接口及其功能,以表格形式展示:
| 接口 | 功能 | 主要方法/回调 |
|---|---|---|
ViewResolver | 视图解析器,用于将逻辑视图名解析为具体的视图对象 | resolveViewName |
LocaleResolver | 区域解析器,用于解析请求中的区域信息 | resolveLocale |
ThemeResolver | 主题解析器,用于解析请求中的主题信息 | resolveThemeName |
HandlerExceptionResolver | 异常解析器,用于处理控制器中抛出的异常 | resolveException |
FlashMapManager | Flash Map 解析器,用于处理重定向时的 Flash Map | saveOutputFlashMap、retrieveAndUpdateFlashMap |
ContentNegotiationStrategy | 内容协商策略解析器,用于确定请求的响应格式 | resolveMediaTypes |
ViewNameTranslator | 视图名称翻译器,用于根据逻辑视图名翻译为真实的视图名 | getViewName |
RequestToViewNameTranslator | 请求到视图名称的翻译器,根据请求翻译为视图名称 | getViewNameForRequest |
这些解析器接口允许开发者在请求处理的不同阶段进行自定义处理,从而实现对视图、区域、主题等方面的个性化配置。在实际应用中,可以通过实现这些接口,注册解析器并配置相应的解析规则,以实现对请求的定制解析处理。
转换器接口
Spring MVC 提供了多个转换器(Converter)接口,用于处理请求参数、路径变量等的类型转换。以下是一些常见的转换器接口及其功能,以表格形式展示:
| 接口 | 功能 | 主要方法/回调 |
|---|---|---|
Converter | 通用类型转换器接口,用于将一种类型转换为另一种类型 | convert |
GenericConverter | 泛型类型转换器接口,相比通用转换器,提供更灵活的配置 | convert |
ConditionalGenericConverter | 有条件的泛型类型转换器接口,根据条件判断是否进行转换 | matches、convert |
ConverterFactory | 类型转换器工厂接口,用于创建特定源和目标类型的转换器 | getConverter |
ConverterRegistry | 转换器注册表接口,用于注册和管理类型转换器 | addConverter、removeConverter |
Formatter | 格式化器接口,用于将一种类型格式化为字符串 | print、parse |
FormatterRegistrar | 格式化器注册接口,用于注册和配置格式化器 | registerFormatters |
FormatterRegistry | 格式化器注册表接口,用于注册和管理格式化器 | addFormatter、removeFormatter |
GenericConversionService | 通用类型转换服务接口,用于执行类型转换操作 | convert、canConvert |
这些转换器接口提供了灵活的扩展点,允许开发者自定义类型转换的规则。在实际应用中,可以通过实现这些接口,注册转换器并配置相应的转换规则,以实现对请求参数、路径变量等的个性化类型转换。
监听器接口
Spring MVC并没有提供专门的监听器(Listener)接口,通常来说,监听器是在Servlet规范中定义的。在Spring MVC中,常用的监听器包括ServletContextListener和HttpSessionListener等,它们不是Spring MVC自己的接口,而是Servlet规范中的标准接口。
以下是一些常用的Servlet规范中定义的监听器接口及其功能,以表格形式展示:
| 接口 | 功能 | 主要方法/回调 |
|---|---|---|
ServletContextListener | Servlet上下文监听器,用于在ServletContext的生命周期内接收通知 | contextInitialized、contextDestroyed |
ServletContextAttributeListener | Servlet上下文属性监听器,用于监听ServletContext属性的变化 | attributeAdded、attributeRemoved、attributeReplaced |
HttpSessionListener | HttpSession监听器,用于在HttpSession的生命周期内接收通知 | sessionCreated、sessionDestroyed |
HttpSessionAttributeListener | HttpSession属性监听器,用于监听HttpSession属性的变化 | attributeAdded、attributeRemoved、attributeReplaced |
ServletRequestListener | ServletRequest监听器,用于在ServletRequest的生命周期内接收通知 | requestInitialized、requestDestroyed |
这些监听器通常在web.xml中进行配置,或者通过@WebListener注解进行注册。在实际应用中,可以通过实现这些监听器接口,编写相应的逻辑来处理ServletContext、HttpSession等的事件。请注意,这些监听器是与Servlet规范密切相关的标准接口,而不是Spring MVC框架自身定义的。
HandlerMapping:处理器映射器
Spring MVC 提供了多个映射器(HandlerMapping)接口,用于确定请求的处理器(Controller)。以下是一些常见的映射器接口及其功能,以表格形式展示:
| 接口 | 功能 | 主要方法/回调 |
|---|---|---|
HandlerMapping | 处理器映射器接口,用于确定请求的处理器 | getHandler |
BeanNameUrlHandlerMapping | 根据Bean的名称映射URL到处理器 | - |
DefaultAnnotationHandlerMapping | 基于注解的处理器映射器,支持@Controller注解等 | - |
RequestMappingHandlerMapping | 基于@RequestMapping注解的处理器映射器 | - |
SimpleUrlHandlerMapping | 简单的URL处理器映射器,将URL映射到处理器 | - |
ControllerClassNameHandlerMapping | 根据Controller类名映射URL到处理器 | - |
AbstractUrlHandlerMapping | URL处理器映射器的抽象基类,提供通用的逻辑 | registerHandler、unregisterHandler |
AbstractHandlerMethodMapping | 处理器方法映射器的抽象基类,提供通用的逻辑 | detectHandlerMethods |
AbstractHandlerMapping | 处理器映射器的抽象基类,提供通用的逻辑 | getHandler、registerHandler、unregisterHandler |
这些映射器接口允许开发者在请求处理的不同阶段进行自定义处理,根据不同的映射规则找到对应的处理器。在实际应用中,可以通过配置或编码方式选择适合自己需求的映射器,以实现对请求的个性化处理。
HandlerAdapter:处理器适配器
Spring MVC 提供了多个适配器(HandlerAdapter)接口,用于根据请求的处理器的类型调用相应的方法。以下是一些常见的适配器接口及其功能,以表格形式展示:
| 接口 | 功能 | 主要方法/回调 |
|---|---|---|
HandlerAdapter | 处理器适配器接口,用于适配不同类型的处理器 | handle、supports |
HttpRequestHandlerAdapter | 适配HttpRequestHandler类型的处理器,用于处理简单的HTTP请求 | - |
SimpleControllerHandlerAdapter | 适配Controller类型的处理器,支持Controller接口和一些旧的Controller类 | handle |
AnnotationMethodHandlerAdapter | 适配带有@RequestMapping注解的方法的处理器,支持注解风格的控制器 | handle |
RequestMappingHandlerAdapter | 适配带有@RequestMapping注解的方法的处理器,支持注解风格的控制器 | handle |
AbstractHandlerMethodAdapter | 处理器方法适配器的抽象基类,提供通用的逻辑 | supports、handle |
AbstractHandlerAdapter | 处理器适配器的抽象基类,提供通用的逻辑 | supports、handle |
这些适配器接口的主要目的是根据不同的处理器类型调用相应的方法,以确保能够适配各种处理器的执行。在实际应用中,选择合适的适配器可以根据使用的处理器的类型,比如控制器方法、HttpRequestHandler等。这些适配器允许 Spring MVC 适应不同种类的处理器,实现更灵活的处理器调用逻辑。
View Resolver:视图解析器
Spring MVC 提供了多个解析器(HandlerMethodArgumentResolver 和 HandlerMethodReturnValueHandler)接口,用于解析控制器方法的参数和返回值。以下是一些常见的解析器接口及其功能,以表格形式展示:
| 接口 | 功能 | 主要方法/回调 |
|---|---|---|
HandlerMethodArgumentResolver | 控制器方法参数解析器接口,用于解析控制器方法的参数 | supportsParameter、resolveArgument |
HandlerMethodReturnValueHandler | 控制器方法返回值处理器接口,用于处理控制器方法的返回值 | supportsReturnType、handleReturnValue |
ModelAndViewResolver | 解析ModelAndView的接口,用于解析ModelAndView对象 | resolveModelAndView |
View | 视图接口,用于处理控制器方法的返回值为View对象 | render |
ResponseBodyEmitterReturnValueHandler | 处理控制器方法返回值为ResponseBodyEmitter的情况 | supportsReturnType、handleReturnValue |
DeferredResultMethodReturnValueHandler | 处理DeferredResult类型的返回值 | supportsReturnType、handleReturnValue |
CallableMethodReturnValueHandler | 处理Callable类型的返回值 | supportsReturnType、handleReturnValue |
HttpEntityMethodProcessor | 处理控制器方法返回值为HttpEntity类型的情况 | supportsReturnType、handleReturnValue |
ModelAttributeMethodProcessor | 处理控制器方法中使用@ModelAttribute注解的情况 | supportsParameter、resolveArgument |
SessionAttributesHandler | 用于处理@SessionAttributes注解的解析器 | resolveSessionAttributes、isHandlerSessionAttributes |
RedirectAttributesMethodArgumentResolver | 处理RedirectAttributes类型的参数 | supportsParameter、resolveArgument |
ModelMethodProcessor | 处理Model类型的参数 | supportsParameter、resolveArgument |
MapMethodProcessor | 处理Map类型的参数 | supportsParameter、resolveArgument |
这些解析器接口允许 Spring MVC 对控制器方法的参数和返回值进行灵活的解析和处理,使得开发者可以更方便地处理各种类型的输入和输出。在实际应用中,可以通过实现这些接口或使用已有的实现类,满足特定场景下的需求。
AOP
基于动态代理实现,它通常使用 JDK 动态代理或 CGLIB 来生成代理对象。 JDK 动态代理要求目标对象实现一个或多个接口,而 CGLIB 代理则能够代理没有实现接口的目标对象。 Spring AOP 会根据切面的配置自动选择合适的代理方式
AOP(Aspect-Oriented Programming)是一种编程范式,旨在通过横切关注点(Cross-Cutting Concerns)的方式来提高代码的模块性和可维护性。横切关注点是那些不属于某个特定模块或层级的功能,例如日志记录、事务管理、权限控制等。AOP将这些横切关注点从业务逻辑中分离出来,以便在不同的模块中共享和重用。
以下是AOP的一些关键概念:
切面(Aspect): 切面是一个模块化单元,它封装了横切关注点的一部分。切面定义了在何处、何时执行横切逻辑。在AOP中,切面通常包含了通知(Advice)和切点(Pointcut)。
通知(Advice): 通知是切面的一部分,它定义了在横切点(切点)何时执行什么样的逻辑。主要有以下几种类型的通知:
- 前置通知(Before advice): 在目标方法执行之前执行。
- 后置通知(After returning advice): 在目标方法正常执行之后执行。
- 异常通知(After throwing advice): 在目标方法抛出异常后执行。
- 最终通知(After (finally) advice): 无论目标方法如何结束,都会执行。
- 环绕通知(Around advice): 在目标方法前后执行,并有机会干预目标方法的调用。
切点(Pointcut): 切点定义了切面的关注点在何处。切点指定了在哪些连接点(Join Point)上应用通知。连接点是在应用中可以插入切面的点,例如方法调用、异常抛出等。
连接点(Join Point): 连接点是在应用中能够应用通知的点,例如方法的调用、异常的抛出等。
引入(织入)(Introduction): 引入(织入)允许向现有的类添加新的方法或属性。通过引入,可以在不修改类源代码的情况下向类添加新的功能。
目标对象(Target Object): 目标对象是在运行时被切面通知的对象。它是程序中原始的业务逻辑对象。
代理(Proxy): 代理是在运行时生成的对象,它包含了目标对象并可以拦截对目标对象方法的调用。代理将切面的通知织入到目标对象的方法调用中。
AOP的主要目标是提高代码的可维护性、模块性和重用性。通过将横切关注点从业务逻辑中抽离出来,可以更容易地理清业务逻辑和横切关注点之间的关系。这种分离还有助于减少代码的重复,因为横切关注点可以在整个应用中共享和重用。
五大通知执行顺序
①Spring4.0
正常情况:环绕前置=====@Before======目标方法执行=====环绕返回=====环绕最终=====@After=====@AfterReturning
异常情况:环绕前置=====@Before======目标方法执行=====环绕异常=====环绕最终=====@After=====@AfterThrowing
②Spring5.28
正常情况:环绕前置=====@Before=====目标方法执行=====@AfterReturning=====@After=====环绕返回=====环绕最终
异常情况:环绕前置=====@Before=====目标方法执行=====@AfterThrowing=====@After=====环绕异常=====环绕最终
五大通知的写法
Spring中的五种通知(Advice)是在AOP(面向切面编程)中定义的,它们分别是:
- 前置通知(Before advice): 在目标方法执行之前执行。
- 后置通知(After returning advice): 在目标方法正常执行之后执行。
- 异常通知(After throwing advice): 在目标方法抛出异常后执行。
- 最终通知(After (finally) advice): 无论目标方法如何结束,都会在其后执行。
- 环绕通知(Around advice): 在目标方法前后执行,并有机会干预目标方法的调用。
下面是这五种通知的示例:
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
@Aspect
public class MyAspect {
// 前置通知
@Before("execution(* com.example.service.*.*(..))")
public void beforeAdvice(JoinPoint joinPoint) {
System.out.println("Before advice: " + joinPoint.getSignature().toShortString());
}
// 后置通知
@AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result")
public void afterReturningAdvice(JoinPoint joinPoint, Object result) {
System.out.println("After returning advice: " + joinPoint.getSignature().toShortString() + ", result: " + result);
}
// 异常通知
@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "exception")
public void afterThrowingAdvice(JoinPoint joinPoint, Throwable exception) {
System.out.println("After throwing advice: " + joinPoint.getSignature().toShortString() + ", exception: " + exception.getMessage());
}
// 最终通知
@After("execution(* com.example.service.*.*(..))")
public void afterAdvice(JoinPoint joinPoint) {
System.out.println("After (finally) advice: " + joinPoint.getSignature().toShortString());
}
// 环绕通知
@Around("execution(* com.example.service.*.*(..))")
public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("Around advice (before): " + proceedingJoinPoint.getSignature().toShortString());
// 执行目标方法
Object result = proceedingJoinPoint.proceed();
System.out.println("Around advice (after): " + proceedingJoinPoint.getSignature().toShortString() + ", result: " + result);
return result;
}
}
在上述代码中,@Before、@AfterReturning、@AfterThrowing、@After、和@Around分别对应了五种不同类型的通知。这个切面类 MyAspect 将这五种通知应用在com.example.service包下的所有方法上。
请注意,AOP通知的具体执行顺序是:
- 前置通知(Before advice)
- 目标方法执行
- 后置通知(After returning advice)(仅在目标方法正常返回时执行)
- 最终通知(After (finally) advice)(无论目标方法如何结束,都会执行)
- 异常通知(After throwing advice)(仅在目标方法抛出异常时执行)
- 环绕通知(Around advice)(在目标方法前后执行,并有机会干预目标方法的调用)
这些通知可以根据实际业务需求进行组合和使用。
注解
@ControllerAdvice
@ControllerAdvice 是 Spring MVC 提供的一个注解,用于全局处理异常、全局数据绑定和全局数据预处理等。它可以标记一个类,该类中的方法可以用于处理整个应用中所有 @Controller 所抛出的异常。
主要用途包括:
- 全局异常处理:通过
@ExceptionHandler注解处理特定异常类型的处理方法。 - 全局数据绑定:通过
@InitBinder注解定制数据绑定规则。 - 全局数据预处理:通过
@ModelAttribute注解提供全局的模型属性。
Spring
注解
@Configuration
@Configuration 是 Spring 中的一个注解,用于定义配置类。配置类用于替代传统的 XML 配置文件,里面可以包含 @Bean 注解的方法,这些方法用于定义和配置 Spring 容器中的 Bean。
示例:
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
作用:
- 表示该类是一个配置类,类似于 XML 配置文件。
- 包含一个或多个
@Bean注解的方法,这些方法将定义 Spring 容器管理的 Bean。
将yml里的配置读成一个java对象
# shell脚本配置 shell: map: # 测试脚本信息 TEST_ONE: - host: 127.0.0.1 port: 22 username: enlin password: 123456 shellpath: /usr/enlin/sh/shell_test.sh/** * 读取配置文件中的脚本配置 */ @Setter @Getter @Configuration // yml 前缀 shell @ConfigurationProperties(prefix = "shell") public class ShellConfig { // yml shell.map下的配置 依照上面的,格式就是一个TEST_ONE 对应一个List(- 符号后定义被解析微集合) private Map<String, List<HostConfig>> map; }
接口
RequestBodyAdvice
@RequestBodyAdvice 接口是 Spring MVC 提供的一个接口,用于在请求体读取之前和之后对请求数据进行处理。它的实现类可以对请求体的内容进行修改、日志记录、安全控制等操作。
主要用途包括:
- 在请求到达控制器之前,可以修改请求体(@RequestBody)的内容。
- 对请求体进行验证或加密解密操作。
- 记录请求内容、统计数据等。
——————————
SpringBoot
注解
@ConditionalOnProperty
@ConditionalOnProperty 是 Spring Boot 中的一个条件注解,用于根据配置文件中的属性值来决定是否装配 Bean 或者配置类。它允许根据不同的属性条件来控制 Spring Boot 应用的配置。
@ConditionalOnProperty通常与其他注解(如@Configuration、@Bean)结合使用,条件性地启用或禁用某些配置或 Bean。
注解参数解释:
@ConditionalOnProperty 注解有多个参数,用于定义属性条件,以下是常用的参数及其含义:
prefix:属性的前缀。在配置文件(如
application.properties或application.yml)中,属性通常是按照prefix.name的形式组织的。name:属性的名称(即键名),指定要检查的属性的具体名称。
havingValue:属性的期望值。如果指定了
havingValue,则属性必须等于这个值才会匹配条件。默认为空字符串。matchIfMissing:是否在缺少该属性时匹配。默认值为
true,表示如果没有指定该属性或者该属性值为空,则条件也会被视为匹配。
示例和用法:
示例 1:根据属性值决定装配
@Configuration
@ConditionalOnProperty(prefix = "app.feature", name = "enabled", havingValue = "true", matchIfMissing = true)
public class FeatureConfig {
@Bean
public FeatureService featureService() {
return new FeatureServiceImpl();
}
}
在这个例子中,FeatureConfig 类使用 @ConditionalOnProperty 注解,它的含义是:只有当 app.feature.enabled=true,或者如果缺少该属性时(即没有在配置文件中设置该属性),才会装配 FeatureConfig 配置类中定义的 Bean(例如 featureService)。
示例 2:根据多个属性值决定装配
@Configuration
@ConditionalOnProperty(prefix = "app.feature", name = {"enabled", "experimental"}, havingValue = "true")
public class FeatureConfig {
@Bean
public FeatureService featureService() {
return new FeatureServiceImpl();
}
}
在这个例子中,@ConditionalOnProperty 注解指定了多个属性名称(enabled 和 experimental),表示只有当 app.feature.enabled=true 和 app.feature.experimental=true 时,才会装配 FeatureConfig 中定义的 Bean。
使用场景:
- 条件化配置:根据不同的属性值动态地配置 Spring Boot 应用。
- 特性开关:根据配置文件中的特定属性值来启用或禁用特定的功能或模块。
- 环境适应性:根据不同的部署环境(如开发、测试、生产)来配置不同的 Bean 或功能。
通过 @ConditionalOnProperty 注解,可以实现基于属性条件的灵活配置,提高了应用程序的可配置性和适应性,使得应用可以根据不同的部署环境或配置要求进行自动调整和装配。
@EnableConfigurationProperties
@ConfigurationProperties、@EnableConfigurationProperties 和 @Configuration 是 Spring Framework 和 Spring Boot 中用于配置和管理 Bean 的注解,它们在配置类和属性绑定方面有各自的用途和相互关系。以下是它们的详细解释和关系。
@ConfigurationProperties
@ConfigurationProperties 是 Spring Boot 提供的一个注解,用于将外部配置(如 application.properties 或 application.yml 中的配置)绑定到一个 Java Bean 上。通过这个注解,可以将配置文件中的属性映射到 Java 对象的属性上。
示例:
@ConfigurationProperties(prefix = "app.datasource")
public class DataSourceProperties {
private String url;
private String username;
private String password;
// getters and setters
}
在这个示例中,app.datasource.url、app.datasource.username 和 app.datasource.password 会被绑定到 DataSourceProperties 类的相应属性上。
@EnableConfigurationProperties
@EnableConfigurationProperties 是一个组合注解,用于启用 @ConfigurationProperties 注解的支持。它通常与 @Configuration 注解结合使用,指示 Spring Boot 扫描和处理 @ConfigurationProperties 注解的类。
示例:
@Configuration
@EnableConfigurationProperties(DataSourceProperties.class)
public class AppConfig {
// 可以在这个配置类中注入 DataSourceProperties
@Autowired
private DataSourceProperties dataSourceProperties;
@Bean
public DataSource dataSource() {
// 使用 dataSourceProperties 创建和配置 DataSource bean
DataSource dataSource = new DataSource();
dataSource.setUrl(dataSourceProperties.getUrl());
dataSource.setUsername(dataSourceProperties.getUsername());
dataSource.setPassword(dataSourceProperties.getPassword());
return dataSource;
}
}
在这个示例中,@EnableConfigurationProperties(DataSourceProperties.class) 启用了 DataSourceProperties 类的属性绑定支持,并且可以在 AppConfig 配置类中注入 DataSourceProperties。
@Configuration
@Configuration 是 Spring 提供的一个注解,用于定义一个配置类。配置类可以包含一个或多个 @Bean 注解的方法,这些方法用于定义和配置 Spring 容器中的 Bean。
示例:
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
在这个示例中,AppConfig 类被标识为一个配置类,并且定义了一个名为 myService 的 Bean。
三者的关系和组合使用
@Configuration用于标识配置类,其中可以定义 Bean。@ConfigurationProperties用于将外部配置文件中的属性映射到 Java Bean 上。@EnableConfigurationProperties用于启用@ConfigurationProperties支持,并将配置属性绑定类注入到 Spring 容器中。
综合示例:
// 定义一个属性绑定类
@ConfigurationProperties(prefix = "app.datasource")
public class DataSourceProperties {
private String url;
private String username;
private String password;
// getters and setters
}
// 定义一个配置类,启用属性绑定支持
@Configuration
@EnableConfigurationProperties(DataSourceProperties.class)
public class AppConfig {
@Autowired
private DataSourceProperties dataSourceProperties;
@Bean
public DataSource dataSource() {
DataSource dataSource = new DataSource();
dataSource.setUrl(dataSourceProperties.getUrl());
dataSource.setUsername(dataSourceProperties.getUsername());
dataSource.setPassword(dataSourceProperties.getPassword());
return dataSource;
}
}
在这个综合示例中:
DataSourceProperties类通过@ConfigurationProperties注解,将外部配置文件中的属性绑定到 Java 对象上。AppConfig类通过@Configuration注解标识为配置类,并通过@EnableConfigurationProperties注解启用了DataSourceProperties类的属性绑定支持。AppConfig类中注入了DataSourceProperties对象,并使用它来配置和创建一个DataSourceBean。
总结
@ConfigurationProperties:用于将外部配置文件中的属性绑定到 Java Bean 上。@EnableConfigurationProperties:用于启用@ConfigurationProperties支持,通常与@Configuration注解结合使用。@Configuration:用于定义一个配置类,可以包含一个或多个@Bean注解的方法,定义和配置 Spring 容器中的 Bean。
这三个注解可以结合使用,实现基于外部配置文件的属性绑定和 Bean 配置管理。
❗多模块配置
如果项目是多模块,串联依赖关系,相同名称的配置项会按优先级覆盖,优先级规则为:启动模块的配置 > 直接依赖模块的配置 > 间接依赖模块的配置。
@RequestParm & @RequestBody
如果前端使用
application/json来传递参数,请使用@RequestBody注解来接收 JSON 格式的请求体数据。一般来说,后端都需要使用一个封装好的对象来接收前端传来的任何属性,如果前端传来了:
{ "ids": [1001, 1002, 1003] }而后端使用
@RequestBody List<Long> ids是会导致程序异常报错的;
除非前端直接传来是一个json的数组类型数据:[1001, 1002, 1003]
如果前端使用 URL 查询参数(也就是GET格式:
?id=&name=)或表单数据,请使用@RequestParam注解来接收这些参数。如果混用,则参数列表内后定义的获取不到前端传来的参数;
日期
前端传入yyyy-MM-dd HH:mm:ss 格式日期字符串,后端直接接收需要加上 @DateTimeFormat 注解;
@GetMapping("/page")
public Result<Page<SysUser>> page(@RequestParam(defaultValue = "1") Integer current,
@RequestParam(defaultValue = "10") Integer size,
@RequestParam(value = "startTime", required = false)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
@RequestParam(value = "endTime", required = false)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
SysUser param) {
// ...
}
如果使用实体类来接收,实体类字段需要加上 @JsonFormat 注解:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField("c_create_time")
private LocalDateTime createTime;
——————————
SpringCloud
五大组件
注册中心
Eureka/Nacos
Eureka
搭建服务端
配置客户端
Nacos包含
- 下载Nacos配置完毕并启动
- 配置客户端
分布式环境下的服务发现和注册
配置中心:bootstrap.yaml文件的优先级高于application.yaml
Nacos配置中心 (介绍与配置) - 不吃紫菜 - 博客园 (cnblogs.com)
功能差异
模块 Nacos Eureka 说明 注册中心 是 是 服务治理基本功能,负责服务中心化注册 配置中心 是 否Eureka需要配合Config实现配置中心,且不提供管理界面 动态刷新 是 否Eureka需要配合MQ实现配置动态刷新,Nacos采用Netty保持TCP长连接实时推送 可用区AZ 是 是 对服务集群划分不同区域,实现区域隔离,并提供容灾自动切换 分组 是 否Nacos可用根据业务和环境进行分组管理 元数据 是 是 提供服务标签数据,例如环境或服务标识 权重 是 否Nacos默认提供权重设置功能,调整承载流量压力 健康检查 是 是 Nacos支持由客户端或服务端发起的健康检查,Eureka是由客户端发起心跳 负载均衡 是 是 均提供负责均衡策略,Eureka采用Ribion 管理界面 是 否Nacos支持对服务在线管理,Eureka只是预览服务状态 部署安装
模块 Nacos Eureka 说明 MySql 是 否Nacos需要采用MySql进行数据进行持久化 MQ 否是 Eureka需要采用MQ进行配置中心刷新 配置中心 是 否Eureka结合Config或者Consul实现配置中心 配置文件 在线编辑 本地文件或者Git远程文件 Eureka结合Config或者Consul 集群 是 是 Nacos需要配置集群ip再启动 稳定及扩展性
模块 Nacos Eureka 说明 版本 1.0.0 1.9.9 Eureka2.0已停止开发,Nacos处于1.x-2.0开发 厂商 阿里巴巴 Netflix Netflix已长期用于生产,阿里刚起步 生产建议 否是 Nacos0.8以前不可用于生产,建议生产采用Nacos1.0,便于节省配置中心集群和服务管理 未来发展 是 否Nacos 2.0主要关注在统一服务管理、服务共享及服务治理体系的开放的服务平台的建设
服务网关(应用层)
Zuul/Gateway
用户不可能知道每一个功能对应的哪一个微服务,所以就出现了网关。它通过路由、负载均衡、流量控制和安全认证等功能来处理微服务中的复杂性;
网关 & 过滤器:网关相当于小区保安,拦截的是所有到访者;过滤器则是每户人家的门,拦截的是单个人,而且要想到达过滤器必须先经过网关。
Zuul:基于Servlet实现,阻塞式api,不支持长连接
Gateway:Spring官方,基于Spring5,响应式非阻塞式api,支持长连接
网关是整个微服务API请求的入口,负责拦截所有请求,分发到服务上去。可以实现日志拦截、权限控制、解决跨域问题、限流、熔断、负载均衡,隐藏服务端的ip,黑名单与白名单拦截、授权等;
- 过滤器:对单个服务器的请求进行拦截控制
- 网关:对所有的服务器的请求进行拦截控制
客户端 <-> Nginx负载均衡之后将请求分发到网关 <-> (走到这里才到了服务)经过Gateway网关路由转发 <-> 访问到所需的微服务,参看 yudao-cloud 架构图
负载均衡(传输层)
进入网关之前:Nginx
进入网关之后:Ribbon/Spring Cloud LoadBalancer
Nginx 主要用于高性能的请求转发和负载均衡,而 API 网关则提供了更多的业务逻辑支持、服务聚合、认证和监控等功能,特别是在微服务架构中。
服务调用
OpenFeign
使用在注册中心中注册的服务名称
spring.application.name进行调用(内置了Ribbon)
加入依赖
<!--OpenFeign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>修改yml配置文件
eureka: client: # 是否注册进eureka register-with-eureka: true fetchRegistry: true service-url: # 集群版注册中心 defaultZone: http://xxx.com:7000/eureka,http://xxx.com:7001/eureka主启动类上加注解:@EnableFeignClients
@EnableFeignClients @EnableHystrix @RibbonClient(name = "CLOUD-XXX-SERVICE", ocnfiguration = SelfRibbonRule.class) pubic class SpringBootMain(){ public static void main(String[] args){ SpringApplication.run(SpringBootMain.class, args) } }Controller正常写,在调用的service interface 那里加:
@Component @FeignClient(value = "CLOUD-XXX-SERVICE") public interface DemoService(){ @RequestMapping("/demo/test") int getDemo(); }这里的
@FeignClient的value就是要调用的服务在注册中心里的服务名,这样就绑定了Feign为该接口会进行哪个server的远程调用。这里有个很突出的特点,可以在接口里的方法加@RequestMapping,这个就是OpenFeign做的一个升级,通过JDK动态代理的方式对该接口进行增强,产生ProxyDemoService代理实现类,根据服务名称从Eureka提供的注册表单中拿到可用的服务节点,再根据Ribbon配置的负载均衡算法去选定某个服务节点开始建立连接,发起调用,解析响应。若不使用
OpenFeign调用,也可使用RestTemplate:public static final String Circulate_URL = "http://CLOUD-XXX-SERVICE"; @Autowired private RestTemplate restTemplate; @RequestMapping("/test2") public Demo getDemo2(){ return restTemplate.getForObject(Circulate_URL + "/demo/test", Demo.class) }
熔断器
Hystix/Sentinel
流量控制:基于流量控制的策略来管理请求的流量,避免过载。
熔断降级:提供熔断机制,当某个服务不稳定时,自动进行服务降级处理,保护系统的稳定性。
系统自适应保护:根据系统的负载情况,自动调整流控策略。
其他
分布式事务:Seata
- AT 模式(Automatic Transaction):支持自动提交和回滚事务。
- TCC 模式(Try-Confirm-Cancel):支持二阶段提交事务,确保业务操作的最终一致性。
- SAGA 模式:支持长事务的编排和补偿,确保长时间运行事务的最终一致性。
定时任务:xxl-job(分布式任务调度)\ Alibaba SchedulerX
cron表达式
消息队列:RocketMQ
- 异步通信:支持生产者与消费者之间的异步通信,实现高效的消息传递。
- 事务消息:支持分布式事务消息,确保消息传递的一致性。
- 延迟消息:支持消息的定时和延迟发送。
RPC: Dubbo 是一个高性能的 RPC(远程过程调用)框架,用于构建微服务架构中的分布式系统。
- 服务注册与发现:提供基于 Nacos 的服务注册与发现功能。
- 负载均衡:内置多种负载均衡策略,支持集群调用。
- 服务治理:支持服务限流、降级、熔断等服务治理功能。



