getHandler(ServerWebExchange exchange) {
String lookupPath = getPath(exchange);
return getHandlerInternal(exchange)
.filter(h -> matchesRoute(lookupPath, h))
.switchIfEmpty(Mono.defer(() -> getBestMatchingHandler(lookupPath, exchange)));
}
映射匹配逻辑
映射匹配逻辑通常涉及以下步骤:
性能优化
RequestMappingHandlerMapping 还实现了一些性能优化措施,例如缓存匹配的 URL 模式,以减少重复的模式匹配操作。
小结一下
HandlerMapping 组件是 Spring WebFlux 请求处理流程中的关键部分,它负责将进入的请求映射到正确的处理器。通过使用不同的 HandlerMapping 实现,Spring WebFlux 支持灵活的请求映射策略,以适应不同的应用场景。
3. HandlerAdapter
HandlerAdapter 接口在 Spring WebFlux 中扮演着至关重要的角色,它的作用是将 DispatcherHandler 找到的处理器(handler)适配到具体的执行逻辑上。HandlerAdapter 使得 DispatcherHandler 无需关心具体的处理器类型,只需要通过 HandlerAdapter 来调用处理器即可。以下是对 HandlerAdapter 组件的源码实现逻辑和步骤的详细分析:
HandlerAdapter 接口定义
HandlerAdapter 接口定义了以下关键方法:
public interface HandlerAdapter {
boolean supports(Object handler);
Mono handle(ServerWebExchange exchange, Object handler, Object... args);
}
主要实现类
Spring WebFlux 提供了几个 HandlerAdapter 的实现类,主要包括:
RequestMappingHandlerAdapter 源码分析
RequestMappingHandlerAdapter 是最常用的 HandlerAdapter 实现之一,下面是它的一些关键实现逻辑:
@Override
public boolean supports(Object handler) {
return (handler instanceof HandlerFunction) ||
(handler instanceof Controller) ||
AnnotationUtils.findAnnotation(handler.getClass(), RequestMapping.class) != null;
}
调用处理器:handle 方法调用处理器,并处理返回值。
@Override
public Mono handle(ServerWebExchange exchange, Object handler) {
// 调用具体的处理器
return ((HandlerFunction) handler).handle(exchange);
}
调用处理器的逻辑
调用处理器的逻辑通常涉及以下步骤:
错误处理
HandlerAdapter 还负责处理调用过程中的异常,将异常转换为合适的响应。
小结一下
HandlerAdapter 组件是 Spring WebFlux 请求处理流程中的关键部分,它解耦了 DispatcherHandler 和具体的处理器实现。通过使用不同的 HandlerAdapter 实现,Spring WebFlux 支持了多种类型的处理器,包括基于注解的控制器、函数式路由以及 HttpHandler 接口的实现。这种设计提高了框架的灵活性和可扩展性。
4. HandlerResultHandler
HandlerResultHandler 组件在 Spring WebFlux 中负责处理由 HandlerAdapter 调用处理器后返回的结果。它将这些结果转换为客户端可以接收的 HTTP 响应。以下是对 HandlerResultHandler 组件的源码实现逻辑和步骤的详细分析:
HandlerResultHandler 接口定义
HandlerResultHandler 接口定义了以下关键方法:
public interface HandlerResultHandler {
boolean supports(HandlerResult result);
Mono handleResult(ServerWebExchange exchange, HandlerResult result);
}
主要实现类
Spring WebFlux 提供了几个 HandlerResultHandler 的实现类,主要包括:
ServerResponseResultHandler 源码分析
ServerResponseResultHandler 是处理 ServerResponse 类型结果的 HandlerResultHandler 实现:
@Override
public boolean supports(HandlerResult result) {
return result.getReturnValue() instanceof ServerResponse;
}
@Override
public Mono handleResult(ServerWebExchange exchange, HandlerResult result) {
ServerResponse response = (ServerResponse) result.getReturnValue();
return response.writeTo(exchange, result.isCommitted());
}
处理结果的逻辑
处理结果的逻辑通常涉及以下步骤:
错误处理
HandlerResultHandler 还负责处理结果处理过程中的异常,将异常转换为合适的响应。
小结一下
HandlerResultHandler 组件是 Spring WebFlux 请求处理流程中的关键部分,它负责将处理器的返回值转换为 HTTP 响应。通过使用不同的 HandlerResultHandler 实现,Spring WebFlux 支持了多种返回值类型,包括 ServerResponse、ResponseEntity 和 ModelAndView。这种设计提高了框架的灵活性和可扩展性,允许开发者以不同的方式处理响应结果。
HandlerResultHandler 的实现通常需要考虑响应的异步特性,确保即使在异步流的情况下也能正确地生成和发送响应。此外,它还需要与 ServerWebExchange 紧密协作,以便访问和操作请求和响应的上下文信息。
5. WebFilter
WebFilter 接口是 Spring WebFlux 中用于拦截和处理 Web 请求和响应的组件。它允许开发者在请求到达具体的处理器之前或之后,对请求或响应进行额外的处理,例如日志记录、安全性检查、跨域处理等。以下是对 WebFilter 组件的源码实现逻辑和步骤的详细分析:
WebFilter 接口定义
WebFilter 接口定义了以下关键方法:
public interface WebFilter {
Mono filter(ServerWebExchange exchange, WebFilterChain chain);
}
过滤器链
在 Spring WebFlux 中,WebFilter 通常会被组织成一个过滤器链,每个 WebFilter 都可以决定是继续过滤请求还是将请求传递给链中的下一个 WebFilter。这种链式调用模式使得过滤器的执行顺序非常重要。
主要实现类
Spring WebFlux 提供了一些内置的 WebFilter 实现类,例如:
过滤器链的构建
过滤器链通常在应用程序的配置中构建,例如使用 WebFilter 接口的实现类:
@Configuration
public class WebFluxConfig {
@Bean
public WebFilter myCustomFilter() {
return (exchange, chain) -> {
// 在这里可以对请求进行预处理
return chain.filter(exchange).subscriberContext(ctx -> ctx.put("customKey", "customValue"));
};
}
}
WebFilter 的实现逻辑
实现 WebFilter 接口的 filter 方法通常涉及以下步骤:
异步处理
由于 filter 方法返回的是 Mono
,WebFilter 的实现需要考虑异步处理。这意味着在过滤过程中,可以返回异步的响应,而不会阻塞整个请求的处理。
小结一下
WebFilter 组件是 Spring WebFlux 中用于拦截和处理 Web 请求和响应的强大工具。通过实现 WebFilter 接口并构建过滤器链,开发者可以灵活地对请求和响应进行预处理和后处理,以及实现各种横切关注点,如安全性、日志记录、CORS 处理等。这种设计提高了应用程序的模块性和可维护性,同时保持了非阻塞和异步的特性。
6. ServerWebExchange
ServerWebExchange 是 Spring WebFlux 中的一个核心组件,它封装了 HTTP 请求和响应的上下文信息,为 Web 服务器和应用程序之间提供了一个交互的接口。以下是对 ServerWebExchange 组件的源码实现逻辑和步骤的详细分析:
ServerWebExchange 接口定义
ServerWebExchange 接口定义了对 HTTP 请求和响应的访问和操作:
public interface ServerWebExchange {
ServerHttpRequest getRequest();
ServerHttpResponse getResponse();
void beforeCommit();
boolean isCommitted();
void setCommitted(boolean committed);
Context getContext();
}
核心属性
ServerWebExchange 通常包含以下核心属性:
request:ServerHttpRequest 对象,封装了 HTTP 请求的详细信息,如头信息、URI、方法等。
response:ServerHttpResponse 对象,用于构造和发送 HTTP 响应。
principal:可能包含当前请求的认证主体(Principal)。
session:可能包含当前请求的会话信息。
attributes:一个 Map,用于存储与请求相关的属性。
请求和响应的处理
ServerWebExchange 在请求和响应的处理中扮演着核心角色:
请求获取:通过 getRequest() 方法获取请求对象,访问请求的各种信息。
响应构造:通过 getResponse() 方法获取响应对象,构造响应的状态码、头信息和响应体。
上下文管理:使用 Context 对象存储和传递请求和响应过程中的附加信息。
提交管理:通过 beforeCommit()、isCommitted() 和 setCommitted() 方法管理响应的提交状态。
过滤器链:在 WebFilter 的实现中,ServerWebExchange 对象在过滤器链中传递,每个过滤器都可以访问和修改请求和响应。
异步处理
由于 WebFlux 是响应式的,ServerWebExchange 支持异步处理:
小结一下
ServerWebExchange 是 Spring WebFlux 中处理 HTTP 请求和响应的核心组件。它提供了一个统一的接口来访问和操作请求和响应数据,同时支持异步非阻塞的处理方式。通过 ServerWebExchange,开发者可以在 Web 服务器和应用程序之间进行高效的数据交换和状态管理,实现高性能的响应式 Web 应用。
ServerWebExchange 的实现通常需要考虑响应式的编程模型,确保在处理请求和构造响应时不会阻塞事件循环,从而充分利用 WebFlux 的性能优势。此外,它还提供了丰富的上下文管理功能,使得在复杂的请求处理流程中,可以方便地存储和传递附加信息。
7. ServerHttpRequest和ServerHttpResponse
ServerHttpRequest 和 ServerHttpResponse 是 Spring WebFlux 中的两个核心接口,它们分别表示服务器接收的 HTTP 请求和发送的 HTTP 响应。以下是对这两个组件的源码实现逻辑和步骤的详细分析:
ServerHttpRequest 接口定义
ServerHttpRequest 接口定义了对 HTTP 请求的访问:
public interface ServerHttpRequest {
URI getURI();
HttpMethod getMethod();
String getHeader(String headerName);
MultiValueMap getHeaders();
DataBufferFactory bufferFactory();
// 省略其他方法...
}
getURI():返回请求的 URI。
getMethod():返回 HTTP 方法(如 GET、POST 等)。
getHeader(String headerName):根据名称获取请求头的值。
getHeaders():返回包含所有请求头的 MultiValueMap。
bufferFactory():返回用于创建数据缓冲区(DataBuffer)的工厂。
ServerHttpResponse 接口定义
ServerHttpResponse 接口定义了对 HTTP 响应的构造和发送:
public interface ServerHttpResponse {
HttpStatusSeriesStatus.Series getStatusSeries();
void setStatusCode(HttpStatus statusCode);
String getHeader(String headerName);
MultiValueMap getHeaders();
void setComplete();
DataBufferFactory bufferFactory();
Mono writeWith(Publisher body);
// 省略其他方法...
}
getStatusSeries():返回响应的状态码系列(如 2xx、3xx 等)。
setStatusCode(HttpStatus statusCode):设置 HTTP 状态码。
getHeader(String headerName):根据名称获取响应头的值。
getHeaders():返回包含所有响应头的 MultiValueMap。
setComplete():标记响应为完成。
writeWith(Publisher body)
:发送响应体。
请求和响应的处理
ServerHttpRequest 和 ServerHttpResponse 在处理 HTTP 请求和响应中扮演着核心角色:
请求信息获取:通过 ServerHttpRequest 的方法获取请求的 URI、方法、头信息等。
响应构造:使用 ServerHttpResponse 的方法设置状态码、头信息,并构造响应体。
数据缓冲区:通过 bufferFactory() 方法获取 DataBufferFactory,用于创建和管理数据缓冲区。
异步发送:ServerHttpResponse 的 writeWith(Publisher body)
方法支持异步发送响应体。
流式处理:支持以流式的方式读取请求体和写入响应体。
异步非阻塞
由于 WebFlux 是基于响应式编程模型的,ServerHttpRequest 和 ServerHttpResponse 支持异步非阻塞的操作:
小结一下
ServerHttpRequest 和 ServerHttpResponse 是 Spring WebFlux 中处理 HTTP 请求和响应的接口。它们提供了丰富的方法来访问请求信息、构造响应,并支持异步非阻塞的操作。通过这两个接口,开发者可以构建高性能、响应式的 Web 应用,充分利用现代硬件和软件架构的优势。
在实际应用中,开发者通常不需要直接实现这些接口,而是通过框架提供的实现类来操作请求和响应。这些实现类通常会与特定的运行时环境(如 Netty)集成,以提供高效的 I/O 操作。
8. WebSession
WebSession 组件在 Spring WebFlux 中用于表示和管理 Web 会话(session)。它提供了一种机制来存储和检索与特定用户会话相关的数据。以下是对 WebSession 组件的源码实现逻辑和步骤的详细分析:
WebSession 接口定义
WebSession 接口定义了 Web 会话的基本操作:
public interface WebSession {
String getId();
Mono save();
void invalidate();
Map getAttributes();
T getAttribute(String name);
void setAttribute(String name, T value);
default Mono getAttributeOrDefault(String name, Supplier defaultValue);
// 省略其他方法...
}
getId():获取会话的唯一标识符。
save():保存会话的更改。
invalidate():使会话无效,相当于会话过期。
getAttributes():获取会话的所有属性。
getAttribute(String name):根据名称获取会话属性。
setAttribute(String name, T value):设置会话属性。
WebSession 的实现逻辑
会话创建:WebSession 可以在请求处理过程中创建,通常与 ServerWebExchange 关联。
属性管理:会话属性存储在 getAttributes() 返回的 Map 中,允许存储和检索用户特定的信息。
异步保存:save() 方法异步保存会话更改,这可能涉及将更改写入底层存储。
会话失效:invalidate() 方法用于使会话无效,确保会话数据不再可用。
会话 ID 管理:每个 WebSession 实例都有一个唯一的 id,用于标识特定的用户会话。
默认值获取:getAttributeOrDefault() 方法提供了一种便捷的方式来获取属性值,如果属性不存在,则返回默认值。
会话的存储和检索
WebSession 的实现通常需要考虑以下方面:
存储机制:会话数据可以存储在不同的介质中,例如内存、数据库或分布式缓存。
并发处理:在多线程或异步环境中,需要确保会话数据的一致性。
会话超时:实现会话超时逻辑,自动使过期的会话无效。
会话的创建和绑定
在请求处理过程中,WebSession 可以被创建和绑定到 ServerWebExchange:
ServerWebExchange exchange = ...;
Mono sessionMono = exchange.getSession();
sessionMono.flatMap(session -> {
// 使用会话
return session.save();
});
小结一下
WebSession 组件是 Spring WebFlux 中用于管理 Web 会话的接口。它提供了一种灵活的方式来存储和检索与用户会话相关的数据,同时支持异步操作和多种存储选项。通过 WebSession,开发者可以轻松实现用户会话跟踪和管理,构建具有个性化用户体验的 Web 应用。
在实际应用中,开发者可以根据需要选择不同的会话存储实现,例如使用 Spring Session 项目提供的多种存储解决方案,包括 Redis、Hazelcast、JDBC 等。这些实现通常会处理会话的创建、保存、失效等逻辑,并与 WebSession 接口进行集成。
9. Reactive Streams
Reactive Streams 是一个规范,它定义了异步流处理的接口和行为,以便在不同的库和框架之间实现互操作性。Spring WebFlux 作为响应式编程的一部分,遵循 Reactive Streams 规范。以下是对 Reactive Streams 组件的源码实现逻辑和步骤的详细分析:
Reactive Streams 核心接口
Reactive Streams 规范定义了以下几个核心接口:
Publisher
:发布者,表示可以产生数据的源头。
Subscriber
:订阅者,表示接收并处理数据的消费者。
Subscription
:订阅关系,用于管理数据的请求和发送。
Processor
:处理器,是 Publisher 和 Subscriber 的结合体。
Publisher 接口
Publisher 接口是 Reactive Streams 的核心,它定义了如何将数据推送给 Subscriber:
public interface Publisher {void subscribe(Subscriber s);}
subscribe(`Subscriber s`):允许 Subscriber 订阅 Publisher。
Subscriber 接口
Subscriber 接口定义了如何处理从 Publisher 接收到的数据:
public interface Subscriber {
void onSubscribe(Subscription s);
void onNext(T t);
void onError(Throwable t);
void onComplete();
}
Subscription 接口
Subscription 接口用于管理 Subscriber 和 Publisher 之间的数据流:
public interface Subscription {
void request(long n);
void cancel();
}
Processor 接口
Processor 是 Publisher 和 Subscriber 的结合体,可以接收数据并产生新的数据流:
public interface Processor extends Subscriber, Publisher {
// 继承自 Subscriber 和 Publisher 的方法
}
源码实现逻辑
数据流创建:使用 Publisher 创建数据流。
订阅机制:Subscriber 通过调用 Publisher 的 subscribe 方法订阅数据流。
数据请求:Subscriber 使用 Subscription 的 request 方法控制数据的接收速率。
数据推送:Publisher 根据 Subscriber 的请求发送数据项给 Subscriber。
错误和完成处理:Publisher 在发生错误或数据流结束时,分别调用 Subscriber 的 onError 或 onComplete 方法。
取消订阅:Subscriber 可以通过调用 Subscription 的 cancel 方法取消订阅。
步骤
初始化:创建 Publisher 和 Subscriber 对象。
订阅:Subscriber 调用 Publisher 的 subscribe 方法。
处理订阅:Publisher 调用 Subscriber 的 onSubscribe 方法,传入 Subscription 对象。
请求数据:Subscriber 使用 Subscription 请求数据。
发送数据:Publisher 根据请求发送数据给 Subscriber。
完成或错误:Publisher 在数据发送完毕后调用 onComplete,或在发生错误时调用 onError。
小结一下
Reactive Streams 规范提供了一种异步、非阻塞的数据处理模型,Spring WebFlux 通过实现这些接口,支持响应式编程。这种模型允许系统更有效地处理并发数据流,提高性能和可伸缩性。开发者可以利用 Reactive Streams 规范提供的接口和机制,构建高效、弹性的响应式应用程序。
10. Reactor 库
Reactor 是一个基于 Reactive Streams 规范的库,用于构建异步、非阻塞的响应式应用程序。它是 Spring WebFlux 的反应式编程基础。以下是对 Reactor 库组件的源码实现逻辑和步骤的详细分析:
Reactor 核心组件
Reactor 提供了以下核心组件:
Flux:代表一个包含 0 到 N 个元素的响应式序列。
Mono:代表一个包含 0 到 1 个元素的响应式序列。
Scheduler:用于控制并发和执行异步操作的调度器。
Flux 和 Mono 的实现逻辑
数据流创建:通过静态方法(如 Flux.just(), Mono.just())或构造函数创建 Flux 或 Mono 实例。
操作符:Reactor 提供了丰富的操作符来处理数据流,例如 map、flatMap、filter 等。
订阅机制:通过 subscribe() 方法订阅数据流,并提供 Subscriber 来接收数据。
数据请求:使用 request() 方法控制数据的请求数量。
数据推送:数据通过 onNext() 方法推送给订阅者。
错误和完成处理:通过 onError() 和 onComplete() 方法处理数据流的错误和完成事件。
Scheduler 的实现逻辑
调度器创建:创建 Scheduler 实例,例如使用 Schedulers.parallel() 创建并行调度器。
任务调度:使用 schedule() 方法调度任务,返回 Mono 或 Flux。
并发控制:Scheduler 可以控制任务的并发执行,例如限制并发数量。
异步执行:任务在非阻塞的线程池中异步执行。
源码实现步骤
定义数据源:创建 Flux 或 Mono 实例作为数据源。
应用操作符:使用操作符对数据流进行转换、过滤或组合。
错误处理:使用 onErrorResume() 或 doOnError() 等操作符处理错误。
背压管理:使用 onBackpressureBuffer() 或 onBackpressureDrop() 等操作符处理背压。
订阅和消费:调用 subscribe() 方法订阅数据流,并提供 Subscriber 来消费数据。
调度任务:使用 Scheduler 调度异步任务。
资源清理:使用 dispose() 方法在不再需要时释放资源。
小结一下
Reactor 库通过 Flux、Mono 和 Scheduler 等组件,提供了一种强大的方式来构建响应式应用程序。它遵循 Reactive Streams 规范,支持异步非阻塞的数据流处理。Reactor 的操作符丰富,可以轻松实现复杂的数据处理逻辑。同时,它还提供了灵活的并发控制和调度机制,以适应不同的应用场景。
Reactor 的设计哲学是提供声明式的数据处理能力,让开发者能够以一种直观和灵活的方式构建响应式系统。通过 Reactor,开发者可以充分利用现代硬件的多核特性,提高应用程序的性能和可伸缩性。
11. WebClient
WebClient 是 Spring WebFlux 中用于发起 HTTP 请求的非阻塞响应式客户端。它允许你以声明式的方式构建请求并处理响应。以下是对 WebClient 组件的源码实现逻辑和步骤的详细分析:
WebClient 接口定义
WebClient 提供了发起请求的方法:
public interface WebClient {
default URI uri() {
return URI.create(this.baseUrl);
}
Mono getForObject(String url, Class responseType, Object... uriVariables);
Flux getForFlux(String url, Class elementType, Object... uriVariables);
// 其他 HTTP 方法的重载,例如 postForObject, putForObject 等
}
uri():返回基础 URI。
getForObject(String url, ...):发起 GET 请求并期望获取对象响应。
getForFlux(String url, ...):发起 GET 请求并期望获取元素流响应。
WebClient.Builder 构建器
WebClient 的实例是通过 WebClient.Builder 构建的:
public final class WebClient.Builder {
private final String baseUrl;
public Builder(String baseUrl) {
this.baseUrl = baseUrl;
}
public WebClient build() {
return new ExchangeStrategiesDefaultWebClient(this);
}
// 其他配置选项,例如设置 ExchangeStrategies, ClientHttpRequestFactory 等
}
请求构建和发送
创建 WebClient 实例:使用 WebClient.Builder 创建并配置 WebClient 实例。
构建请求:使用 WebClient 的方法来添加请求头、查询参数、请求体等。
发起请求:调用 HTTP 方法对应的方法(如 getForObject、postForObject)来发起请求。
处理响应:响应以 Mono 或 Flux 的形式返回,可以进一步处理。
源码实现步骤
WebClient webClient = WebClient.builder().baseUrl("http://example.com").build();
构建请求:使用 WebClient 的方法链式构建请求。
Mono personMono = webClient.get()
.uri("/person/{id}", id)
.retrieve()
.bodyToMono(Person.class);
发起请求并获取响应:调用 retrieve() 方法并指定响应体转换的方式。
响应体转换:使用 bodyToMono 或 bodyToFlux 等方法将响应体转换为指定类型。
错误处理:使用 onErrorResume 或 onErrorMap 等操作符处理可能发生的错误。
订阅和消费:订阅响应体 Mono 或 Flux 并消费数据。
并发和异步处理
WebClient 支持并发和异步处理,允许以非阻塞的方式发起多个请求:
使用 Flux 可以处理多个响应。
可以使用 Scheduler 来控制并发级别。
小结一下
WebClient 是 Spring WebFlux 中一个强大且灵活的组件,用于构建非阻塞的响应式 HTTP 客户端。它允许以声明式的方式构建请求,并通过 Reactive Streams 规范支持异步数据处理。WebClient 的设计使得它非常适合在响应式应用程序中使用,可以充分利用现代异步编程的优势,提高应用程序的性能和可伸缩性。
开发者可以轻松地使用 WebClient 与外部服务进行通信,获取数据,并以响应式的方式处理这些数据。通过 WebClient,Spring WebFlux 应用程序可以无缝地集成到更大的响应式系统中。
12. Spring Data Reactive
Spring Data Reactive 是 Spring Data 项目的一部分,它提供了一组用于访问响应式数据存储的抽象。它允许以声明式和响应式的方式进行数据访问和操作,支持如 MongoDB、Redis、R2DBC(Reactive Relational Database Connectivity)等响应式数据库。以下是对 Spring Data Reactive 组件的源码实现逻辑和步骤的详细分析:
Spring Data Reactive 核心概念
Reactive Repository:扩展了 Reactive Streams 规范,提供了异步的 CRUD 操作。
ReactiveCrudRepository:基础接口,提供基本的 CRUD 操作。
ReactiveMongoRepository、ReactiveRedisRepository 等:特定数据库的实现。
Reactive Repository 接口定义
public interface ReactiveCrudRepository extends ReactiveRepository {
Mono save(T entity);
Flux findAll();
Mono findById(ID id);
Mono deleteById(ID id);
// 其他方法...
}
响应式数据访问步骤
public interface MyEntityRepository extends ReactiveCrudRepository {
// 可以添加自定义查询方法
}
配置数据源:配置响应式数据源和客户端,例如配置 MongoDB 的 ReactiveMongoDatabase。
使用仓库:在服务层注入并使用仓库接口进行数据操作。
构建查询:使用仓库接口提供的方法或自定义查询方法构建查询。
异步处理:处理查询结果,使用 Mono 或 Flux 的异步特性。
源码实现逻辑
实体和仓库定义:定义数据实体和仓库接口。
Spring 应用上下文:Spring 应用上下文扫描仓库接口并创建代理实现。
执行查询:当调用仓库接口的方法时,代理将方法调用转换为数据库操作。
结果封装:查询结果封装在 Mono 或 Flux 中返回。
错误处理:处理可能发生的异常,将它们转换为合适的响应。
响应式流控制:使用 Reactive Streams 规范控制数据流。
响应式数据库操作示例
@Service
public class MyEntityService {
private final MyEntityRepository repository;
@Autowired
public MyEntityService(MyEntityRepository repository) {
this.repository = repository;
}
public Mono addMyEntity(MyEntity entity) {
return repository.save(entity);
}
public Flux getAllMyEntities() {
return repository.findAll();
}
}
小结一下
Spring Data Reactive 通过提供响应式仓库接口,简化了响应式数据访问的实现。它利用了 Reactive Streams 规范,允许以非阻塞的方式进行数据库操作,提高了应用程序的性能和可伸缩性。开发者可以轻松地定义仓库接口,并使用 Spring 提供的 CRUD 方法或自定义查询方法进行数据操作。
Spring Data Reactive 组件的设计允许它与现代响应式编程模型和框架(如 WebFlux)无缝集成,为构建响应式应用程序提供了强大的数据访问能力。通过使用 Spring Data Reactive,开发者可以构建高效、弹性的应用程序,同时保持代码的简洁性和可维护性。
13. Spring Security Reactive
Spring Security Reactive 是 Spring Security 的响应式扩展,它为响应式应用程序提供了安全和认证支持。以下是对 Spring Security Reactive 组件的源码实现逻辑和步骤的详细分析:
Spring Security Reactive 核心概念
ServerSecurityContextRepository:用于在请求中存储和检索 SecurityContext。
ReactiveSecurityContextHolder:管理 SecurityContext 的持有者。
ServerSecurityConfigurer:用于配置安全上下文。
ServerHttpSecurity:定义了响应式 HTTP 安全策略。
ReactiveAuthenticationManager 和 ReactiveUserDetailsService:用于用户认证和用户详情服务。
ServerSecurityContextRepository 接口定义
public interface ServerSecurityContextRepository {
Mono save(ServerSecurityContext context);
Mono load();
void invalidate();
}
save:保存 ServerSecurityContext。
load:加载 ServerSecurityContext。
invalidate:使 ServerSecurityContext 无效。
ServerHttpSecurity 配置
public class ServerHttpSecurity {
public ServerHttpSecurity(ReactiveAuthenticationManager authentication) {
// ...
}
public SecurityWebFilterChain build() {
// ...
}
public ServerHttpSecurity authorizeExchange(Consumer configurer) {
// ...
}
// 其他配置方法,例如 cors, csrf, formLogin, httpBasic 等
}
响应式认证和授权步骤
配置认证管理器:创建并配置 ReactiveAuthenticationManager。
配置用户服务:创建并配置 ReactiveUserDetailsService。
构建 ServerHttpSecurity:使用 ServerHttpSecurity 构建安全策略。
配置安全上下文存储:配置 ServerSecurityContextRepository。
注册 WebFilter:将 SecurityWebFilterChain 注册到 Web 过滤器链中。
处理认证和授权:在请求处理过程中,Spring Security Reactive 拦截请求并处理认证和授权。
源码实现逻辑
初始化:在应用程序启动时,Spring Security Reactive 初始化安全配置。
请求拦截:SecurityWebFilterChain 拦截请求并根据配置的安全策略进行处理。
认证:使用 ReactiveAuthenticationManager 进行用户认证。
授权:根据 ServerHttpSecurity 配置的授权规则,使用 ReactiveAccessDecisionManager 进行访问控制。
安全上下文:使用 ServerSecurityContextRepository 管理每个请求的安全上下文。
异常处理:处理安全相关的异常,如认证失败或访问拒绝。
响应:根据认证和授权的结果,构建响应并返回给客户端。
小结一下
Spring Security Reactive 为响应式应用程序提供了全面的安全支持。它基于 Spring Security 的核心概念,并通过响应式编程模型提供了异步、非阻塞的安全处理能力。通过 ServerHttpSecurity 的配置,开发者可以灵活地定义认证和授权策略,以满足不同应用程序的安全需求。
Spring Security Reactive 的设计允许它与 Spring WebFlux 无缝集成,为响应式 Web 应用程序提供强大的安全保障。通过使用 Spring Security Reactive,开发者可以构建安全、可靠且易于维护的响应式应用程序。
14. HttpHandler
HttpHandler 组件在 Spring WebFlux 中是一个用于处理 HTTP 请求的接口,它是响应式编程模型中最低层次的 HTTP 请求处理契约。HttpHandler 作为一个共同的接口,允许不同的运行时环境通过不同的实现来处理 HTTP 请求。以下是对 HttpHandler 组件的源码实现逻辑和步骤的详细分析:
HttpHandler 接口定义
HttpHandler 接口定义了一个 handle 方法,用于处理传入的 HTTP 请求并返回一个响应:
public interface HttpHandler {
Mono handle(ServerHttpRequest request, ServerHttpResponse response);
}
handle(ServerHttpRequest request, ServerHttpResponse response):处理给定的请求并构造响应。
核心职责
HttpHandler 的核心职责包括:
接收请求:接收 ServerHttpRequest 对象,该对象封装了 HTTP 请求的详细信息。
构造响应:根据请求信息构造 ServerHttpResponse 对象,设置状态码、响应头等。
返回结果:返回一个 Mono
对象,表示异步的响应处理过程。
实现步骤
创建 HttpHandler 实例:实现 HttpHandler 接口或使用现有的实现。
处理请求:在 handle 方法中编写逻辑以处理请求,例如路由、认证、业务处理等。
构造响应:根据请求的处理结果构造响应,设置状态码、响应头和响应体。
返回 Mono
:返回一个 Mono
,表示响应已经发送或将被发送。
错误处理:在 handle 方法中处理可能发生的异常,确保它们被适当地转换为响应。
示例实现
以下是一个简单的 HttpHandler 实现示例,它返回一个固定的响应:
public class SimpleHttpHandler implements HttpHandler {
@Override
public Mono handle(ServerHttpRequest request, ServerHttpResponse response) {
String body = "Hello, World!";
response.getHeaders().add("Content-Type", "text/plain");
return response.writeWith(Flux.just(DataBufferUtils.wrap(body)));
}
}
小结一下
HttpHandler 组件是 Spring WebFlux 中用于处理 HTTP 请求的基础接口。它提供了一个简单而灵活的方式来处理 HTTP 请求和构造响应。通过实现 HttpHandler 接口,开发者可以控制整个请求处理流程,包括请求解析、业务逻辑处理和响应构建。
HttpHandler 的实现可以与其他 Spring WebFlux 组件(如 DispatcherHandler、HandlerMapping、HandlerAdapter 等)结合使用,以构建一个完整的响应式 Web 应用程序。这种低层次的接口为需要高度定制的 Web 应用程序提供了强大的灵活性。
15. ContextPathCompositeHandler
ContextPathCompositeHandler 是 Spring WebFlux 中的一个组件,它允许在同一服务器上将多个应用程序映射到不同的上下文路径(context paths)。这类似于在传统的 Servlet 容器中为每个 Web 应用程序配置不同的 URL 路径。
以下是对 ContextPathCompositeHandler 组件的源码实现逻辑和步骤的详细分析:
ContextPathCompositeHandler 接口定义
ContextPathCompositeHandler 实际上不是一个接口,而是 HandlerMapping 接口的一个实现,它组合了多个 Handler 对象,每个对象都关联一个上下文路径。
主要属性
上下文路径映射
ContextPathCompositeHandler 维护了一个映射,将每个上下文路径映射到一个 Handler:
private final Map contextPaths = new ConcurrentHashMap<>();
添加应用程序
应用程序可以在初始化时通过 ContextPathCompositeHandler 的 addHandler 方法添加到映射中:
public void addHandler(String contextPath, HttpHandler handler) {
this.contextPaths.put(contextPath, handler);
// 更新正则表达式模式以匹配所有注册的上下文路径
updatePattern();
}
处理请求
ContextPathCompositeHandler 通过 getHandler 方法来确定请求应该由哪个 Handler 处理:
@Override
public Mono getHandler(ServerWebExchange exchange) {
String path = extractContextPath(exchange);
return Mono.justOrEmpty(contextPaths.get(path))
.map(HandlerAdapter::new)
.defaultIfEmpty(Mono.defer(() -> createNotFoundError(exchange)));
}
正则表达式模式
ContextPathCompositeHandler 使用正则表达式来匹配请求路径:
private void updatePattern() {
// 构建匹配所有注册上下文路径的正则表达式
String regex = contextPaths.keySet().stream()
.map(this::toRegex)
.collect(Collectors.joining("|", "^(", ")$"));
this.compiledPattern = Pattern.compile(regex);
}
错误处理
如果没有找到匹配的上下文路径,ContextPathCompositeHandler 会创建一个表示 "Not Found" 的错误处理器:
private Mono createNotFoundError(ServerWebExchange exchange) {
return Mono.just(new HandlerAdapter() {
@Override
public boolean supports(Object handler) {
return true;
}
@Override
public Mono handle(ServerWebExchange exchange, Object handler) {
return ServerResponse.notFound().build().writeTo(exchange);
}
});
}
小结一下
ContextPathCompositeHandler 组件是 Spring WebFlux 中用于将多个应用程序映射到不同上下文路径的 HandlerMapping 实现。它通过维护一个上下文路径到 HttpHandler 的映射,允许每个应用程序处理其自己的请求路径。通过正则表达式匹配请求路径,并使用 HandlerAdapter 来适配和调用相应的处理器。
这种设计模式使得在单个服务器实例中部署和管理多个 WebFlux 应用程序变得简单和高效,每个应用程序都可以有自己的上下文路径,而 ContextPathCompositeHandler 负责将请求路由到正确的应用程序处理器。
最后
以上是Spring WebFlux 框架核心组件的全部介绍了,希望可以帮助你全面深入的理解 WebFlux的原理。
文章转载自: 威哥爱编程
原文链接: https://www.cnblogs.com/wgjava/p/18282994
体验地址: 引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构
你可能感兴趣的:(java,spring)
Java实习生常规技术面试题每日十题Java基础(五)
用户昵称23
面试 阿里巴巴 java 开发语言 jvm html golang
目录1.启动一个线程是用run()还是start()?.?2.线程的基本状态以及状态之间的关系。3.Set和List的区别,List和Map的区别?4.同步方法、同步代码块区别?5.描述Java锁机制。6.Comparable和Comparator接口是干什么的?列出它们的区别7.Java集合类框架的最佳实践有哪些?8.HashMap和Hashtable的区别。
Redis数据类型有哪些
头孢头孢
零散面试相关的总结 redis 哈希算法 数据库
Redis底层数据类型及其实现原理详细解析Redis提供了多种底层数据类型,每种类型都基于不同的数据结构实现,适用于不同的应用场景。理解这些底层实现和它们的使用方式对于优化Redis性能至关重要。以下是Redis中常用的底层数据类型的详细介绍,包括底层实现原理以及一些常用的Java代码示例。1.字符串(String)1.1数据类型描述Redis中的字符串(String)是最基本的数据类型,它可以存
Java 初学者如何学习 Java?(分享自身学习经历)
爱学习Java的靓女
因为我一开始也是通过知乎学习的,所以和同学们分享下我自学java成功的经历。首先我从我自己的学习经历说起,然后谈一下自己对学习java的看法和建议。这对于初学者来说才是有帮助的,希望大家可以吸取一些对自己有用的东西。1本科的脚踏实地高考之后填志愿,那时候其实我也不懂,就觉得电子信息工程好像还不错,于是就填了。在大学四年,除了学校学了C语言之外,我没有学习任何第二门编程语言,而且C语言也只是初级的水
SpringBoot中集成SaToken
boy快快长大
解决问题合集 spring boot 后端 java
SpringBoot中集成SaToken1.写一个拦截器2.对拦截器的说明&解释2.拦截器1.写一个拦截器importcn.dev33.satoken.exception.NotLoginException;importcn.dev33.satoken.stp.StpUtil;importorg.springframework.beans.factory.annotation.Value;impo
Spring中的IOC详解
m0_74824687
面试 学习路线 阿里巴巴 spring java 后端
文章目录IOCIOC容器的工作原理Bean的生命周期Bean的自动装配@Autowired@Resource@Inject使用Spring底层组件IOCSpring的核心之一是IOC,IOC全称为InversionofControl,中文译为控制反转,是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。IOC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是
分享一些处理复杂HTML结构的经验
数据小爬虫@
html 前端
在处理复杂HTML结构时,尤其是使用Java爬虫和Jsoup进行数据抓取时,以下是一些实用的经验和技巧,可以帮助你更高效地解析和提取数据:1.缩小解析范围对于复杂的HTML结构,尽量缩小解析范围,只解析所需的元素。使用CSS选择器来定位所需的元素,而不是对整个文档进行解析。2.使用Jsoup的选择器功能Jsoup提供了强大的选择器功能,可以用来处理嵌套的DOM元素。例如,你可以使用select方法
人工智障的软件开发-自动流水线CI/CD篇-docker+jenkins部署之道
Yuanymoon
人工智障2077系列 devops jenkins ci/cd docker jenkins ai
指令接收:「需要自动构建系统」系统检测:目标开发一个软件已完成代码仓库-轻盈的gitea,开始添加自动流水线启动应急冷却协议:准备承受Java系应用的资源冲击核心组件锁定:构建老将军Jenkins(虽然年迈但依然能战)需求分析:论碳基生物的认知进化人类需求翻译矩阵表层需求:“写一个软件”实际需求:“写代码并自动完成测试/打包/部署的流水线,最后自动部署一个系统哟”隐藏需求:“想要偷懒又不想承认的自
Java基于Java的酒店管理系统的设计与实现(开题+源码)
笔文程序设计
java 开发语言
本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景:随着科技的发展和信息化的加速,酒店管理系统已经成为酒店运营不可或缺的一部分。过去,酒店通常采用传统的手动方式来管理客户信息、客房预订和入住登记等,这种方式不仅效率低下,而且容易出错。为了提高酒店的运营效率和服务质量,我们需要设计并实现一个基于Java的酒店管理系统。意义:通过
【Redis系列】Redis安装与使用
m0_74825409
面试 学习路线 阿里巴巴 redis 数据库 缓存
???欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。推荐:kwan的首页,持续学习,不断总结,共同进步,活到老学到老导航檀越剑指大厂系列:全面总结java核心技术点,如集合,jvm,并发编程redis,kafka,Spring,微服务,Netty等常用开发工具系列:罗列常用的开发工具,如IDE
《On Java进阶卷》阅读笔记(二)
m0_74823317
面试 学习路线 阿里巴巴 java 笔记 python
第3章集合主题List的行为:List是除数组之外最基本的对象存储和检索方式,基本操作如下:add()用于插入元素get()用于随机访问元素,这个操作在特定的List的实现成本不同iterator()用于返回该序列上的iteratorstream()用于生成序列中元素的StreamSet的行为:Set的意义在于测试成员身份,也可以用于删除重复元素。HashSet的输出是没有明显的顺序TreeSet
SpringBoot中websocket拦截器获取cookie中的token信息
小的~~
spring boot websocket java
@Getter@Slf4j@ComponentpublicclassWebSocketSecurityTokenInterceptorimplementsHandshakeInterceptor{privateTokenAcquireHandlertokenAcquireHandler;privateTokenAnalysisHandlertokenAnalysisHandler;{tokenAc
Springboot中添加原生websocket支持
小的~~
spring boot websocket java
1、添加配置@Configuration@EnableWebSocketpublicclassWebSocketConfigimplementsWebSocketConfigurer{@OverridepublicvoidregisterWebSocketHandlers(WebSocketHandlerRegistryregistry){//注册WebSocket处理器,并允许所有来源的连接(在
Aerospike
小的~~
nosql Aerospike
文章来源:拉勾教育Java高薪训练营第3期Aerospike介绍Aerospike(简称AS)是一个分布式,可扩展的键值存储的NoSQL数据库。T级别大数据高并发的结构化数据存储读写操作达微妙级,99%的响应可在1毫秒内实现采用混合架构,索引存储在内存中,而数据可存储在机械硬盘(HDD)或固态硬盘(SSD)上(也可存储在内存)AS内部在访问SSD屏蔽了文件系统层级,直接访问地址,保证了数据的读取速
前端面试题常考汇总1
RayFars
前端
JS部分1.解释JavaScript中的闭包,并举例说明其应用场景闭包是指函数能够记住并访问它的词法作用域,即使这个函数在词法作用域之外执行。应用场景:数据隐藏:通过闭包,可以创建私有变量,只通过特定的函数来访问和修改这些变量。回调函数和事件处理:闭包常用于设置回调函数,因为回调函数需要访问其外部函数的变量。functioncreateCounter(){letcount=0;returnfunc
JavaSE基础及面试
浩哲Zhe
Java知识体系构建 java
JavaSE整理总结结构:问题(问题关键字)回答问题关键字可以取消,以后目录和题目结构要认真组织。Java的知识体系包含哪些内容?拓展拓展如何打开远程桌面连接?通过“运行”对话框打开:按下Windows键+R,打开“运行”对话框。输入“mstsc”并按回车,这将打开远程桌面连接窗口。VisualStudio中的多行注释快捷键是什么?ctrl+shift+/二进制-1的原码、补码、反码分别是什么?-
RPC框架Dubbo深入分析
radcb55226
程序员 rpc dubbo 网络协议
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!依赖于Zookeeper的稳定性Redis支持基于客户端双写的集群方式,性能高要求服务器时间同步,用于检查心跳过期脏数据Multicast去中心化,不需要安装注册中心依赖于网络拓普和路由,跨机房有风险SimpleDogfooding,注册中心本身也是一个标准的RPC服务没有集群支持,可能单点故障cl
08-两数之和(四种解法)
最遥远的瞬间
算法合集 算法 数据结构
两数之和1:给定一个整数数组num,从数组中找出两个数满足相加之和等于目标数target。假设每个输入只对应唯一的答案,而且不可以重塑使用相同的元素。返回两数的下标值,以数组形式返回。importjava.util.Arrays;importjava.util.HashMap;importjava.util.Map;importjava.util.Scanner;publicclassdemo01
红 - 黑树和 B+树?
百态老人
笔记
红黑树是一种自平衡二叉查找树,由RudolfBayer发明,在1978年被LeoJ.Guibas和RobertSedgewick改称为“红黑树”。它的特点包括每个节点非红即黑;根节点是黑色;每个叶子节点都是黑色的空节点;如果一个节点是红色的,那么它的两个子节点都是黑色;从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。在Java集合框架中,很多部分如HashMap、TreeMap、Tree
MySQL底层原理学习
jiqiren1994
# mysql mysql 数据库 database
一、MySQL体系架构MySQLServer架构自顶向下大致可以分网络连接层、服务层、存储引擎层和系统文件层。1.网络连接层客户端连接器(ClientConnectors):提供与MySQL服务器建立的支持。目前几乎支持所有主流的服务端编程技术,例如常见的Java、C、Python、.NET等,它们通过各自API技术与MySQL建立连接。2.服务层(MySQLServer)服务层是MySQLSer
Web组件适配网页中iframe
场景描述:当使用web组件加载带有iframe的页面时,由于H5的iframe标签的几个限制条件,可能会出现以下问题:1.由于iframe也要遵守浏览器同源策略,也有对应的白名单限制,所以也会出现跨域或者无法加载的问题,大多出现在本地或沙箱中的H5资源内联iframe时,并且cookie有时候也设置不上2.在应用侧调用runJavascript方法调用不到iframe里面,且主frame和ifra
Spring Cloud构建微服务架构:分布式服务跟踪
yueerba126
Spring Cloud 架构 spring cloud 微服务
准备工作启动SpringCloud构建微服务架构:服务注册与发现(Eureka、Consul)中的服务注册中心d-eureka-server。1.服务注册中心d-eureka-server:描述:服务注册与发现中心。选项:你可以使用已有的构建或选择公益eureka注册中心。2.微服务应用d-trace-1:描述:微服务应用1。功能:实现REST接口/trace-1,调用此接口会触发对trace-2
深入解析Spring Cloud五大组件:构建微服务架构的核心利器
一位卑微的码农
架构 spring cloud 微服务
引言在当今的互联网时代,微服务架构已经成为构建复杂应用的主流方式。SpringCloud作为微服务架构的佼佼者,提供了一系列强大的工具和组件,帮助开发者快速构建和部署微服务应用。本文将深入解析SpringCloud的五大核心组件,帮助你全面掌握SpringCloud的核心技术。1.SpringCloudNetflixEureka:服务注册与发现1.1什么是Eureka?Eureka是Netflix
出现Field ‘id‘ doesn‘t have a default value; nested exception is java.sql.SQLException的解决方法
码农研究僧
BUG java 开发语言 后端
出现这个指示错误org.springframework.dao.DataIntegrityViolationException:###Errorupdatingdatabase.Cause:java.sql
阿里云EMAS:2月产品动态
阿里云移动应用开发测试推送
一、内容摘要上线EMAS定制版套餐,适合有多种移动研发工具诉求的中型企业Windvane小程序容器新增列表搜索功能云构建发布新的android镜像java-11-base,适应gradle7.0+移动测试上线一键重跑功能,支持失败的用例一键重跑移动推送支持Flutter插件,开源更易用二、产品动态
JavaScript设计模式 -- 状态模式
鎈卟誃筅甡
javascript 设计模式 状态模式
在软件开发中,很多对象的行为会随着其内部状态的变化而改变。如果将所有状态逻辑写在一个类中,代码不仅臃肿而且难以维护。**状态模式(StatePattern)**正是为了解决这个问题而设计的。通过将对象的状态封装成独立的状态类,并将状态相关的行为转移到这些状态类中,状态模式让对象在内部状态发生变化时自动切换行为,达到了将状态转换与行为实现分离的目的。本文将详细介绍状态模式的核心思想、基本结构与优缺点
AQS 核心原理与高频面试题详解
java
前言AQS(AbstractQueuedSynchronizer)是Java并发包(java.util.concurrent)中的核心基础类,它提供了一个框架来实现阻塞锁和相关的同步器(如信号量、CountDownLatch等)。AQS内部使用了一个FIFO的双向队列来管理线程,这个队列存储的是等待获取同步状态的线程节点。一、AQS的核心原理1.AQS的作用是什么?AQS是一个用于构建锁和同步器的
什么是MVC?什么是SpringMVC?什么是三层架构?
m0_74824802
面试 学习路线 阿里巴巴 mvc 架构
文章目录应用分层什么是MVC?什么是SpringMVC?三层架构三层架构和MVC的关系应用分层在讲解什么是MVC之前,先来理解一下什么是应用分层。应用分层是一种软件开发设计思想,将应用程序划分成N个层次,每个层次都分别负责自己的职责,多个层次之间来协同提供完整的功能,根据项目的复杂度,将项目分成三层或四层等。举个例子:比如,一个公司创始初期,创始人要身兼数职,既要做财务,又要做人事,又要做行政,但
解决Mybatis-plus与springboot3.0+、spring6.0+的兼容性问题
lian潋湄
mybatis
根据mybatis-plus学习框架时,一直都会报错如下信息:当时并不知道这几个工具之间存在版本兼容性问题,就一直苦于找不到合适的解决方法,于是便上网开始了疯狂的搜索,发现改了好多地方还是不行。偶然间了解到了工具之间版本是存在兼容性问题的,一开始问ChatGPT也并没有给出正确的回答,于是我去了最最权威的官网查看,终于发现了问题所在:mybatis-plus官网给出的mybatis-plus插件依
数据库字段类型和Java的对应关系
m0_67265654
java java 后端
1、CHAR、VARCHAR、LONGVARCHAR可映射为String或char[],但String更适合于一般用法2、BINARY、VARBINARY和LONGVARBINARY都可用同一byte数组来表示。3、BITBIT类型的Java映射的推荐类型是Java布尔型4、SMALLINTSMALLINT类型的Java映射的推荐类型是16位的Javashort类型5、INTEGERINTEGER
Java 大视界 -- Java 大数据在智能体育中的应用与赛事分析(80)
青云交
大数据新视界 Java 大视界 java 大数据 智能体育 数据采集 运动员训练 赛事分析 赛事预测
亲爱的朋友们,热烈欢迎来到青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而我的博客正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也期待你毫无保留地分享独特见解,愿我们于此携手成长,共赴新程!一、欢迎加入【福利社群】点击快速加入:青云交灵犀技韵交响盛汇福利社群点击快速加入2:2024CSDN博客之星创作交流营(NEW)二、本博客的精华专栏:大数据新视
书其实只有三类
西蜀石兰
类
一个人一辈子其实只读三种书,知识类、技能类、修心类。
知识类的书可以让我们活得更明白。类似十万个为什么这种书籍,我一直不太乐意去读,因为单纯的知识是没法做事的,就像知道地球转速是多少一样(我肯定不知道),这种所谓的知识,除非用到,普通人掌握了完全是一种负担,维基百科能找到的东西,为什么去记忆?
知识类的书,每个方面都涉及些,让自己显得不那么没文化,仅此而已。社会认为的学识渊博,肯定不是站在
《TCP/IP 详解,卷1:协议》学习笔记、吐槽及其他
bylijinnan
tcp
《TCP/IP 详解,卷1:协议》是经典,但不适合初学者。它更像是一本字典,适合学过网络的人温习和查阅一些记不清的概念。
这本书,我看的版本是机械工业出版社、范建华等译的。这本书在我看来,翻译得一般,甚至有明显的错误。如果英文熟练,看原版更好:
http://pcvr.nl/tcpip/
下面是我的一些笔记,包括我看书时有疑问的地方,也有对该书的吐槽,有不对的地方请指正:
1.
Linux—— 静态IP跟动态IP设置
eksliang
linux IP
一.在终端输入
vi /etc/sysconfig/network-scripts/ifcfg-eth0
静态ip模板如下:
DEVICE="eth0" #网卡名称
BOOTPROTO="static" #静态IP(必须)
HWADDR="00:0C:29:B5:65:CA" #网卡mac地址
IPV6INIT=&q
Informatica update strategy transformation
18289753290
更新策略组件: 标记你的数据进入target里面做什么操作,一般会和lookup配合使用,有时候用0,1,1代表 forward rejected rows被选中,rejected row是输出在错误文件里,不想看到reject输出,将错误输出到文件,因为有时候数据库原因导致某些column不能update,reject就会output到错误文件里面供查看,在workflow的
使用Scrapy时出现虽然队列里有很多Request但是却不下载,造成假死状态
酷的飞上天空
request
现象就是:
程序运行一段时间,可能是几十分钟或者几个小时,然后后台日志里面就不出现下载页面的信息,一直显示上一分钟抓取了0个网页的信息。
刚开始已经猜到是某些下载线程没有正常执行回调方法引起程序一直以为线程还未下载完成,但是水平有限研究源码未果。
经过不停的google终于发现一个有价值的信息,是给twisted提出的一个bugfix
连接地址如下http://twistedmatrix.
利用预测分析技术来进行辅助医疗
蓝儿唯美
医疗
2014年,克利夫兰诊所(Cleveland Clinic)想要更有效地控制其手术中心做膝关节置换手术的费用。整个系统每年大约进行2600例此类手术,所以,即使降低很少一部分成本,都可以为诊 所和病人节约大量的资金。为了找到适合的解决方案,供应商将视野投向了预测分析技术和工具,但其分析团队还必须花时间向医生解释基于数据的治疗方案意味着 什么。
克利夫兰诊所负责企业信息管理和分析的医疗
java 线程(一):基础篇
DavidIsOK
java 多线程 线程
&nbs
Tomcat服务器框架之Servlet开发分析
aijuans
servlet
最近使用Tomcat做web服务器,使用Servlet技术做开发时,对Tomcat的框架的简易分析:
疑问: 为什么我们在继承HttpServlet类之后,覆盖doGet(HttpServletRequest req, HttpServetResponse rep)方法后,该方法会自动被Tomcat服务器调用,doGet方法的参数有谁传递过来?怎样传递?
分析之我见: doGet方法的
揭秘玖富的粉丝营销之谜 与小米粉丝社区类似
aoyouzi
揭秘玖富的粉丝营销之谜
玖富旗下悟空理财凭借着一个微信公众号上线当天成交量即破百万,第七天成交量单日破了1000万;第23天时,累计成交量超1个亿……至今成立不到10个月,粉丝已经超过500万,月交易额突破10亿,而玖富平台目前的总用户数也已经超过了1800万,位居P2P平台第一位。很多互联网金融创业者慕名前来学习效仿,但是却鲜有成功者,玖富的粉丝营销对外至今仍然是个谜。
近日,一直坚持微信粉丝营销
Java web的会话跟踪技术
百合不是茶
url会话 Cookie会话 Seession会话 Java Web 隐藏域会话
会话跟踪主要是用在用户页面点击不同的页面时,需要用到的技术点
会话:多次请求与响应的过程
1,url地址传递参数,实现页面跟踪技术
格式:传一个参数的
url?名=值
传两个参数的
url?名=值 &名=值
关键代码
web.xml之Servlet配置
bijian1013
java web.xml Servlet配置
定义:
<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>com.myapp.controller.MyFirstServlet</servlet-class>
<init-param>
<param-name>
利用svnsync实现SVN同步备份
sunjing
SVN 同步 E000022 svnsync 镜像
1. 在备份SVN服务器上建立版本库
svnadmin create test
2. 创建pre-revprop-change文件
cd test/hooks/
cp pre-revprop-change.tmpl pre-revprop-change
3. 修改pre-revprop-
【分布式数据一致性三】MongoDB读写一致性
bit1129
mongodb
本系列文章结合MongoDB,探讨分布式数据库的数据一致性,这个系列文章包括:
数据一致性概述与CAP
最终一致性(Eventually Consistency)
网络分裂(Network Partition)问题
多数据中心(Multi Data Center)
多个写者(Multi Writer)最终一致性
一致性图表(Consistency Chart)
数据
Anychart图表组件-Flash图转IMG普通图的方法
白糖_
Flash
问题背景:项目使用的是Anychart图表组件,渲染出来的图是Flash的,往往一个页面有时候会有多个flash图,而需求是让我们做一个打印预览和打印功能,让多个Flash图在一个页面上打印出来。
那么我们打印预览的思路是获取页面的body元素,然后在打印预览界面通过$("body").append(html)的形式显示预览效果,结果让人大跌眼镜:Flash是
Window 80端口被占用 WHY?
bozch
端口占用 window
平时在启动一些可能使用80端口软件的时候,会提示80端口已经被其他软件占用,那一般又会有那些软件占用这些端口呢?
下面坐下总结:
1、web服务器是最经常见的占用80端口的,例如:tomcat , apache , IIS , Php等等;
2
编程之美-数组的最大值和最小值-分治法(两种形式)
bylijinnan
编程之美
import java.util.Arrays;
public class MinMaxInArray {
/**
* 编程之美 数组的最大值和最小值 分治法
* 两种形式
*/
public static void main(String[] args) {
int[] t={11,23,34,4,6,7,8,1,2,23};
int[]
Perl正则表达式
chenbowen00
正则表达式 perl
首先我们应该知道 Perl 程序中,正则表达式有三种存在形式,他们分别是:
匹配:m/<regexp>;/ (还可以简写为 /<regexp>;/ ,略去 m)
替换:s/<pattern>;/<replacement>;/
转化:tr/<pattern>;/<replacemnt>;
[宇宙与天文]行星议会是否具有本行星大气层以外的权力呢?
comsci
举个例子: 地球,地球上由200多个国家选举出一个代表地球联合体的议会,那么现在地球联合体遇到一个问题,地球这颗星球上面的矿产资源快要采掘完了....那么地球议会全体投票,一致通过一项带有法律性质的议案,既批准地球上的国家用各种技术手段在地球以外开采矿产资源和其它资源........
&
Oracle Profile 使用详解
daizj
oracle profile 资源限制
Oracle Profile 使用详解 转
一、目的:
Oracle系统中的profile可以用来对用户所能使用的数据库资源进行限制,使用Create Profile命令创建一个Profile,用它来实现对数据库资源的限制使用,如果把该profile分配给用户,则该用户所能使用的数据库资源都在该profile的限制之内。
二、条件:
创建profile必须要有CREATE PROFIL
How HipChat Stores And Indexes Billions Of Messages Using ElasticSearch & Redis
dengkane
elasticsearch Lucene
This article is from an interview with Zuhaib Siddique, a production engineer at HipChat, makers of group chat and IM for teams.
HipChat started in an unusual space, one you might not
循环小示例,菲波拉契序列,循环解一元二次方程以及switch示例程序
dcj3sjt126com
c 算法
# include <stdio.h>
int main(void)
{
int n;
int i;
int f1, f2, f3;
f1 = 1;
f2 = 1;
printf("请输入您需要求的想的序列:");
scanf("%d", &n);
for (i=3; i<n; i
macbook的lamp环境
dcj3sjt126com
lamp
sudo vim /etc/apache2/httpd.conf
/Library/WebServer/Documents
是默认的网站根目录
重启Mac上的Apache服务
这个命令很早以前就查过了,但是每次使用的时候还是要在网上查:
停止服务:sudo /usr/sbin/apachectl stop
开启服务:s
java ArrayList源码 下
shuizhaosi888
ArrayList源码
版本 jdk-7u71-windows-x64
JavaSE7 ArrayList源码上:http://flyouwith.iteye.com/blog/2166890
/**
* 从这个列表中移除所有c中包含元素
*/
public boolean removeAll(Collection<?> c) {
Spring Security(08)——intercept-url配置
234390216
Spring Security intercept-url 访问权限 访问协议 请求方法
intercept-url配置
目录
1.1 指定拦截的url
1.2 指定访问权限
1.3 指定访问协议
1.4 指定请求方法
1.1 &n
Linux环境下的oracle安装
jayung
oracle
linux系统下的oracle安装
本文档是Linux(redhat6.x、centos6.x、redhat7.x) 64位操作系统安装Oracle 11g(Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production),本文基于各种网络资料精心整理而成,共享给有需要的朋友。如有问题可联系:QQ:52-7
hotspot虚拟机
leichenlei
java HotSpot jvm 虚拟机 文档
JVM参数
http://docs.oracle.com/javase/6/docs/technotes/guides/vm/index.html
JVM工具
http://docs.oracle.com/javase/6/docs/technotes/tools/index.html
JVM垃圾回收
http://www.oracle.com
读《Node.js项目实践:构建可扩展的Web应用》 ——引编程慢慢变成系统化的“砌砖活”
noaighost
Web node.js
读《Node.js项目实践:构建可扩展的Web应用》
——引编程慢慢变成系统化的“砌砖活”
眼里的Node.JS
初初接触node是一年前的事,那时候年少不更事。还在纠结什么语言可以编写出牛逼的程序,想必每个码农都会经历这个月经性的问题:微信用什么语言写的?facebook为什么推荐系统这么智能,用什么语言写的?dota2的外挂这么牛逼,用什么语言写的?……用什么语言写这句话,困扰人也是阻碍
快速开发Android应用
rensanning
android
Android应用开发过程中,经常会遇到很多常见的类似问题,解决这些问题需要花时间,其实很多问题已经有了成熟的解决方案,比如很多第三方的开源lib,参考
Android Libraries 和
Android UI/UX Libraries。
编码越少,Bug越少,效率自然会高。
但可能由于 根本没听说过、听说过但没用过、特殊原因不能用、自己已经有了解决方案等等原因,这些成熟的解决
理解Java中的弱引用
tomcat_oracle
java 工作 面试
不久之前,我
面试了一些求职Java高级开发工程师的应聘者。我常常会面试他们说,“你能给我介绍一些Java中得弱引用吗?”,如果面试者这样说,“嗯,是不是垃圾回收有关的?”,我就会基本满意了,我并不期待回答是一篇诘究本末的论文描述。 然而事与愿违,我很吃惊的发现,在将近20多个有着平均5年开发经验和高学历背景的应聘者中,居然只有两个人知道弱引用的存在,但是在这两个人之中只有一个人真正了
标签输出html标签" target="_blank">关于标签输出html标签
xshdch
jsp
http://back-888888.iteye.com/blog/1181202
关于<c:out value=""/>标签的使用,其中有一个属性是escapeXml默认是true(将html标签当做转移字符,直接显示不在浏览器上面进行解析),当设置escapeXml属性值为false的时候就是不过滤xml,这样就能在浏览器上解析html标签,
&nb