@Bean
    @ConditionalOnProperty(value = "shenyu.netty.http.web-server-factory-enabled", havingValue = "true", matchIfMissing = true)
    public NettyReactiveWebServerFactory nettyReactiveWebServerFactory(final ObjectProvider<NettyHttpProperties> properties,
                                                                       final ObjectProvider<ShenyuSniAsyncMapping> shenyuSniAsyncMappingProvider,
                                                                       final ObjectProvider<TcpSslContextSpec> tcpSslContextSpecs) {
        NettyReactiveWebServerFactory webServerFactory = new NettyReactiveWebServerFactory();
        NettyHttpProperties nettyHttpProperties = Optional.ofNullable(properties.getIfAvailable()).orElse(new NettyHttpProperties());
        webServerFactory.addServerCustomizers(new EventLoopNettyCustomizer(nettyHttpProperties, httpServer -> {
            HttpServer server = httpServer;
            // Configure sni certificates
            NettyHttpProperties.SniProperties sniProperties = nettyHttpProperties.getSni();
            if (sniProperties.getEnabled()) {
                ShenyuSniAsyncMapping shenyuSniAsyncMapping = shenyuSniAsyncMappingProvider.getIfAvailable();
                if (Objects.isNull(shenyuSniAsyncMapping)) {
                    throw new ShenyuException("Can not find shenyuSniAsyncMapping bean");
                }
                if ("manual".equals(sniProperties.getMod())) {
                    List<SslCrtAndKeyFile> sslCrtAndKeyFiles = sniProperties.getCertificates();
                    if (CollectionUtils.isEmpty(sslCrtAndKeyFiles)) {
                        throw new ShenyuException("At least one certificate is required");
                    }

                    // Use the first certificate as the default certificate (this default certificate will not actually be used)
                    List<SslCrtAndKeyFile> certificates = sslCrtAndKeyFiles;
                    for (SslCrtAndKeyFile certificate : certificates) {
                        try {
                            shenyuSniAsyncMapping.addSslCertificate(certificate);
                        } catch (IOException e) {
                            LOG.error("add certificate error", e);
                        }
                    }

                    SslCrtAndKeyFile defaultCert = certificates.get(0);
                    TcpSslContextSpec defaultSpec = TcpSslContextSpec.forServer(new File(defaultCert.getKeyCertChainFile()),
                            new File(defaultCert.getKeyFile()));
                    
                    server = server.secure(spec -> spec.sslContext(defaultSpec)
                                .setSniAsyncMappings(shenyuSniAsyncMapping), false);
                } else if ("k8s".equals(sniProperties.getMod())) {
                    TcpSslContextSpec defaultSpec = Objects.requireNonNull(tcpSslContextSpecs.getIfAvailable());
                    server = server.secure(spec -> spec.sslContext(defaultSpec)
                            .setSniAsyncMappings(shenyuSniAsyncMapping), false);
                    shenyuSniAsyncMapping.addSslProvider("shenyu-default", SslProvider.builder().sslContext(defaultSpec).build());
                } else {
                    throw new ShenyuException("Cannot read the sni mod");
                }
            }
            return server;
        }));
        return webServerFactory;
    }
Netty reactive web server factory.

@param properties the properties
@param shenyuSniAsyncMappingProvider shenyuSniAsyncMapping
@param tcpSslContextSpecs default tcpSslContextSpecs
@return the netty reactive web server factory
shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/src/main/java/org/apache/shenyu/springboot/starter/netty/ShenyuNettyWebServerConfiguration.java