spring-cloud-gateway使用其他容器遇到的問題

在使用spring-cloud-gateway的時(shí)候,想使用其他的web容器氢伟,但是會遇到一個(gè)報(bào)錯(cuò)

java.lang.ClassCastException: org.springframework.core.io.buffer.DefaultDataBufferFactory cannot be cast to org.springframework.core.io.buffer.NettyDataBufferFactory

筆者折騰了半天酷宵、百度谷歌都沒有解決方案,無奈只能去找源頭Spencer Gibb 大神問了問器虾。

image.png

他說現(xiàn)在只支持默認(rèn)的NettyWebServer讯嫂。不支持其他容器。
但是他也寫了一個(gè)解決方案兆沙,


image.png

于是我翻閱了一下他的源碼發(fā)現(xiàn)這兩個(gè)bean是注釋掉的欧芽。
如果想啟用的話只能修改源碼,于是我改了一下他的源碼GatewayAutoConfiguration這個(gè)配置類:

/*
 * Copyright 2013-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package org.springframework.cloud.gateway.config;

import com.netflix.hystrix.HystrixObservableCommand;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.cloud.gateway.actuate.GatewayControllerEndpoint;
import org.springframework.cloud.gateway.filter.*;
import org.springframework.cloud.gateway.filter.factory.*;
import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyRequestBodyGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyResponseBodyGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.headers.ForwardedHeadersFilter;
import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter;
import org.springframework.cloud.gateway.filter.headers.RemoveHopByHopHeadersFilter;
import org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.cloud.gateway.filter.ratelimit.PrincipalNameKeyResolver;
import org.springframework.cloud.gateway.filter.ratelimit.RateLimiter;
import org.springframework.cloud.gateway.handler.FilteringWebHandler;
import org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping;
import org.springframework.cloud.gateway.handler.predicate.*;
import org.springframework.cloud.gateway.route.*;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.cloud.stream.reactive.shaded.rx.RxReactiveStreams;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.util.StringUtils;
import org.springframework.validation.Validator;
import org.springframework.web.reactive.DispatcherHandler;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient;
import org.springframework.web.reactive.socket.client.WebSocketClient;
import org.springframework.web.reactive.socket.server.WebSocketService;
import org.springframework.web.reactive.socket.server.support.HandshakeWebSocketService;
import reactor.core.publisher.Flux;
import reactor.ipc.netty.http.client.HttpClient;
import reactor.ipc.netty.http.client.HttpClientOptions;
import reactor.ipc.netty.options.ClientProxyOptions;
import reactor.ipc.netty.resources.PoolResources;

import java.util.List;
import java.util.function.Consumer;

import static org.springframework.cloud.gateway.config.HttpClientProperties.Pool.PoolType.DISABLED;
import static org.springframework.cloud.gateway.config.HttpClientProperties.Pool.PoolType.FIXED;

/**
 * @author Spencer Gibb
 */
@Configuration
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore(HttpHandlerAutoConfiguration.class)
@AutoConfigureAfter({GatewayLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class})
@ConditionalOnClass(DispatcherHandler.class)
public class GatewayAutoConfiguration {

    @Configuration
    @ConditionalOnClass(HttpClient.class)
    protected static class NettyConfiguration {
        @Bean
        @ConditionalOnMissingBean
        public HttpClient httpClient(@Qualifier("nettyClientOptions") Consumer<? super HttpClientOptions.Builder> options) {
            return HttpClient.create(options);
        }

        @Bean
        public Consumer<? super HttpClientOptions.Builder> nettyClientOptions(HttpClientProperties properties) {
            return opts -> {

                // configure ssl
                HttpClientProperties.Ssl ssl = properties.getSsl();

                if (ssl.isUseInsecureTrustManager()) {
                    opts.sslSupport(sslContextBuilder -> {
                        sslContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);
                    });
                }

                // configure pool resources
                HttpClientProperties.Pool pool = properties.getPool();

                if (pool.getType() == DISABLED) {
                    opts.disablePool();
                } else if (pool.getType() == FIXED) {
                    PoolResources poolResources = PoolResources.fixed(pool.getName(),
                            pool.getMaxConnections(), pool.getAcquireTimeout());
                    opts.poolResources(poolResources);
                } else {
                    PoolResources poolResources = PoolResources.elastic(pool.getName());
                    opts.poolResources(poolResources);
                }


                // configure proxy if proxy host is set.
                HttpClientProperties.Proxy proxy = properties.getProxy();
                if (StringUtils.hasText(proxy.getHost())) {
                    opts.proxy(typeSpec -> {
                        ClientProxyOptions.Builder builder = typeSpec
                                .type(ClientProxyOptions.Proxy.HTTP)
                                .host(proxy.getHost());

                        PropertyMapper map = PropertyMapper.get();

                        map.from(proxy::getPort)
                                .whenNonNull()
                                .to(builder::port);
                        map.from(proxy::getUsername)
                                .whenHasText()
                                .to(builder::username);
                        map.from(proxy::getPassword)
                                .whenHasText()
                                .to(password -> builder.password(s -> password));
                        map.from(proxy::getNonProxyHostsPattern)
                                .whenHasText()
                                .to(builder::nonProxyHosts);

                        return builder;
                    });
                }
            };
        }

        @Bean
        public HttpClientProperties httpClientProperties() {
            return new HttpClientProperties();
        }

        //        @Bean
        public NettyRoutingFilter routingFilter(HttpClient httpClient,
                                                ObjectProvider<List<HttpHeadersFilter>> headersFilters) {
            return new NettyRoutingFilter(httpClient, headersFilters);
        }

        //        @Bean
        public NettyWriteResponseFilter nettyWriteResponseFilter(GatewayProperties properties) {
            return new NettyWriteResponseFilter(properties.getStreamingMediaTypes());
        }

        @Bean
        public ReactorNettyWebSocketClient reactorNettyWebSocketClient(@Qualifier("nettyClientOptions") Consumer<? super HttpClientOptions.Builder> options) {
            return new ReactorNettyWebSocketClient(options);
        }
    }

    @Bean
    public RouteLocatorBuilder routeLocatorBuilder(ConfigurableApplicationContext context) {
        return new RouteLocatorBuilder(context);
    }

    @Bean
    @ConditionalOnMissingBean
    public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(GatewayProperties properties) {
        return new PropertiesRouteDefinitionLocator(properties);
    }

    @Bean
    @ConditionalOnMissingBean(RouteDefinitionRepository.class)
    public InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository() {
        return new InMemoryRouteDefinitionRepository();
    }

    @Bean
    @Primary
    public RouteDefinitionLocator routeDefinitionLocator(List<RouteDefinitionLocator> routeDefinitionLocators) {
        return new CompositeRouteDefinitionLocator(Flux.fromIterable(routeDefinitionLocators));
    }

    @Bean
    public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,
                                                    List<GatewayFilterFactory> GatewayFilters,
                                                    List<RoutePredicateFactory> predicates,
                                                    RouteDefinitionLocator routeDefinitionLocator) {
        return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, GatewayFilters, properties);
    }

    @Bean
    @Primary
    //TODO: property to disable composite?
    public RouteLocator cachedCompositeRouteLocator(List<RouteLocator> routeLocators) {
        return new CachingRouteLocator(new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
    }

    @Bean
    public RouteRefreshListener routeRefreshListener(ApplicationEventPublisher publisher) {
        return new RouteRefreshListener(publisher);
    }

    @Bean
    public FilteringWebHandler filteringWebHandler(List<GlobalFilter> globalFilters) {
        return new FilteringWebHandler(globalFilters);
    }

    @Bean
    public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler,
                                                                     RouteLocator routeLocator) {
        return new RoutePredicateHandlerMapping(webHandler, routeLocator);
    }

    // ConfigurationProperty beans

    @Bean
    public GatewayProperties gatewayProperties() {
        return new GatewayProperties();
    }

    @Bean
    public SecureHeadersProperties secureHeadersProperties() {
        return new SecureHeadersProperties();
    }

    // HttpHeaderFilter beans

    @Bean
    @ConditionalOnProperty(name = "spring.cloud.gateway.forwarded.enabled", matchIfMissing = true)
    public ForwardedHeadersFilter forwardedHeadersFilter() {
        return new ForwardedHeadersFilter();
    }

    @Bean
    public RemoveHopByHopHeadersFilter removeHopByHopHeadersFilter() {
        return new RemoveHopByHopHeadersFilter();
    }

    @Bean
    @ConditionalOnProperty(name = "spring.cloud.gateway.x-forwarded.enabled", matchIfMissing = true)
    public XForwardedHeadersFilter xForwardedHeadersFilter() {
        return new XForwardedHeadersFilter();
    }


    // GlobalFilter beans

    @Bean
    public AdaptCachedBodyGlobalFilter adaptCachedBodyGlobalFilter() {
        return new AdaptCachedBodyGlobalFilter();
    }

    @Bean
    public RouteToRequestUrlFilter routeToRequestUrlFilter() {
        return new RouteToRequestUrlFilter();
    }

    @Bean
    @ConditionalOnBean(DispatcherHandler.class)
    public ForwardRoutingFilter forwardRoutingFilter(DispatcherHandler dispatcherHandler) {
        return new ForwardRoutingFilter(dispatcherHandler);
    }

    @Bean
    public ForwardPathFilter forwardPathFilter() {
        return new ForwardPathFilter();
    }

    @Bean
    public WebSocketService webSocketService() {
        return new HandshakeWebSocketService();
    }

    @Bean
    public WebsocketRoutingFilter websocketRoutingFilter(WebSocketClient webSocketClient,
                                                         WebSocketService webSocketService,
                                                         ObjectProvider<List<HttpHeadersFilter>> headersFilters) {
        return new WebsocketRoutingFilter(webSocketClient, webSocketService, headersFilters);
    }

    @Bean
    public WeightCalculatorWebFilter weightCalculatorWebFilter(@Qualifier("webFluxValidator") Validator validator) {
        return new WeightCalculatorWebFilter(validator);
    }

    @Bean
    //TODO: default over netty? configurable
    public WebClientHttpRoutingFilter webClientHttpRoutingFilter() {
        //TODO: WebClient bean
        return new WebClientHttpRoutingFilter(WebClient.builder().build());
    }

    @Bean
    public WebClientWriteResponseFilter webClientWriteResponseFilter() {
        return new WebClientWriteResponseFilter();
    }

    // Predicate Factory beans

    @Bean
    public AfterRoutePredicateFactory afterRoutePredicateFactory() {
        return new AfterRoutePredicateFactory();
    }

    @Bean
    public BeforeRoutePredicateFactory beforeRoutePredicateFactory() {
        return new BeforeRoutePredicateFactory();
    }

    @Bean
    public BetweenRoutePredicateFactory betweenRoutePredicateFactory() {
        return new BetweenRoutePredicateFactory();
    }

    @Bean
    public CookieRoutePredicateFactory cookieRoutePredicateFactory() {
        return new CookieRoutePredicateFactory();
    }

    @Bean
    public HeaderRoutePredicateFactory headerRoutePredicateFactory() {
        return new HeaderRoutePredicateFactory();
    }

    @Bean
    public HostRoutePredicateFactory hostRoutePredicateFactory() {
        return new HostRoutePredicateFactory();
    }

    @Bean
    public MethodRoutePredicateFactory methodRoutePredicateFactory() {
        return new MethodRoutePredicateFactory();
    }

    @Bean
    public PathRoutePredicateFactory pathRoutePredicateFactory() {
        return new PathRoutePredicateFactory();
    }

    @Bean
    public QueryRoutePredicateFactory queryRoutePredicateFactory() {
        return new QueryRoutePredicateFactory();
    }

    @Bean
    public ReadBodyPredicateFactory readBodyPredicateFactory(ServerCodecConfigurer codecConfigurer) {
        return new ReadBodyPredicateFactory(codecConfigurer);
    }

    @Bean
    public RemoteAddrRoutePredicateFactory remoteAddrRoutePredicateFactory() {
        return new RemoteAddrRoutePredicateFactory();
    }

    @Bean
    @DependsOn("weightCalculatorWebFilter")
    public WeightRoutePredicateFactory weightRoutePredicateFactory() {
        return new WeightRoutePredicateFactory();
    }

    // GatewayFilter Factory beans

    @Bean
    public AddRequestHeaderGatewayFilterFactory addRequestHeaderGatewayFilterFactory() {
        return new AddRequestHeaderGatewayFilterFactory();
    }

    @Bean
    public AddRequestParameterGatewayFilterFactory addRequestParameterGatewayFilterFactory() {
        return new AddRequestParameterGatewayFilterFactory();
    }

    @Bean
    public AddResponseHeaderGatewayFilterFactory addResponseHeaderGatewayFilterFactory() {
        return new AddResponseHeaderGatewayFilterFactory();
    }

    @Configuration
    @ConditionalOnClass({HystrixObservableCommand.class, RxReactiveStreams.class})
    protected static class HystrixConfiguration {
        @Bean
        public HystrixGatewayFilterFactory hystrixGatewayFilterFactory(DispatcherHandler dispatcherHandler) {
            return new HystrixGatewayFilterFactory(dispatcherHandler);
        }
    }

    @Bean
    public ModifyRequestBodyGatewayFilterFactory modifyRequestBodyGatewayFilterFactory(ServerCodecConfigurer codecConfigurer) {
        return new ModifyRequestBodyGatewayFilterFactory(codecConfigurer);
    }

    @Bean
    public ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory(ServerCodecConfigurer codecConfigurer) {
        return new ModifyResponseBodyGatewayFilterFactory(codecConfigurer);
    }

    @Bean
    public PrefixPathGatewayFilterFactory prefixPathGatewayFilterFactory() {
        return new PrefixPathGatewayFilterFactory();
    }

    @Bean
    public PreserveHostHeaderGatewayFilterFactory preserveHostHeaderGatewayFilterFactory() {
        return new PreserveHostHeaderGatewayFilterFactory();
    }

    @Bean
    public RedirectToGatewayFilterFactory redirectToGatewayFilterFactory() {
        return new RedirectToGatewayFilterFactory();
    }

    @Bean
    public RemoveRequestHeaderGatewayFilterFactory removeRequestHeaderGatewayFilterFactory() {
        return new RemoveRequestHeaderGatewayFilterFactory();
    }

    @Bean
    public RemoveResponseHeaderGatewayFilterFactory removeResponseHeaderGatewayFilterFactory() {
        return new RemoveResponseHeaderGatewayFilterFactory();
    }

    @Bean(name = PrincipalNameKeyResolver.BEAN_NAME)
    @ConditionalOnBean(RateLimiter.class)
    public PrincipalNameKeyResolver principalNameKeyResolver() {
        return new PrincipalNameKeyResolver();
    }

    @Bean
    @ConditionalOnBean({RateLimiter.class, KeyResolver.class})
    public RequestRateLimiterGatewayFilterFactory requestRateLimiterGatewayFilterFactory(RateLimiter rateLimiter, PrincipalNameKeyResolver resolver) {
        return new RequestRateLimiterGatewayFilterFactory(rateLimiter, resolver);
    }

    @Bean
    public RewritePathGatewayFilterFactory rewritePathGatewayFilterFactory() {
        return new RewritePathGatewayFilterFactory();
    }

    @Bean
    public RetryGatewayFilterFactory retryGatewayFilterFactory() {
        return new RetryGatewayFilterFactory();
    }

    @Bean
    public SetPathGatewayFilterFactory setPathGatewayFilterFactory() {
        return new SetPathGatewayFilterFactory();
    }

    @Bean
    public SecureHeadersGatewayFilterFactory secureHeadersGatewayFilterFactory(SecureHeadersProperties properties) {
        return new SecureHeadersGatewayFilterFactory(properties);
    }

    @Bean
    public SetRequestHeaderGatewayFilterFactory setRequestHeaderGatewayFilterFactory() {
        return new SetRequestHeaderGatewayFilterFactory();
    }

    @Bean
    public SetResponseHeaderGatewayFilterFactory setResponseHeaderGatewayFilterFactory() {
        return new SetResponseHeaderGatewayFilterFactory();
    }

    @Bean
    public SetStatusGatewayFilterFactory setStatusGatewayFilterFactory() {
        return new SetStatusGatewayFilterFactory();
    }

    @Bean
    public SaveSessionGatewayFilterFactory saveSessionGatewayFilterFactory() {
        return new SaveSessionGatewayFilterFactory();
    }

    @Bean
    public StripPrefixGatewayFilterFactory stripPrefixGatewayFilterFactory() {
        return new StripPrefixGatewayFilterFactory();
    }

    @Bean
    public RequestHeaderToRequestUriGatewayFilterFactory requestHeaderToRequestUriGatewayFilterFactory() {
        return new RequestHeaderToRequestUriGatewayFilterFactory();
    }

    @Configuration
    @ConditionalOnClass(Health.class)
    protected static class GatewayActuatorConfiguration {

        @Bean
        @ConditionalOnEnabledEndpoint
        public GatewayControllerEndpoint gatewayControllerEndpoint(RouteDefinitionLocator routeDefinitionLocator, List<GlobalFilter> globalFilters,
                                                                   List<GatewayFilterFactory> GatewayFilters, RouteDefinitionWriter routeDefinitionWriter,
                                                                   RouteLocator routeLocator) {
            return new GatewayControllerEndpoint(routeDefinitionLocator, globalFilters, GatewayFilters, routeDefinitionWriter, routeLocator);
        }
    }

}

將NettyRoutingFilter和NettyWriteResponseFilter這兩個(gè)bean注釋掉把GB大神說的WebClientHttpRoutingFilter和WebClientWriteResponseFilter注釋放開葛圃。啟動成功千扔,訪問正常】庹看似解決了曲楚,但是偶爾還會報(bào)一下錯(cuò),還是netty的東西褥符,

o.netty.util.ReferenceCountUtil         : Failed to release a message: DefaultHttpContent(data: PooledUnsafeHeapByteBuf(freed), decoderResult: success)

io.netty.util.IllegalReferenceCountException: refCnt: 0, increment: 1
  at io.netty.buffer.AbstractReferenceCountedByteBuf.release0(AbstractReferenceCountedByteBuf.java:100) ~[netty-buffer-4.1.23.Final.jar!/:4.1.23.Final]
  at 

最后決定暫時(shí)不折騰了龙誊,只能老老實(shí)實(shí)用他的NettyWebServer

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市喷楣,隨后出現(xiàn)的幾起案子载迄,更是在濱河造成了極大的恐慌,老刑警劉巖抡蛙,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件护昧,死亡現(xiàn)場離奇詭異,居然都是意外死亡粗截,警方通過查閱死者的電腦和手機(jī)惋耙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來熊昌,“玉大人绽榛,你說我怎么就攤上這事⌒鲆伲” “怎么了灭美?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長昂利。 經(jīng)常有香客問我届腐,道長铁坎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任犁苏,我火速辦了婚禮硬萍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘围详。我一直安慰自己朴乖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布助赞。 她就那樣靜靜地躺著买羞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪雹食。 梳的紋絲不亂的頭發(fā)上畜普,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機(jī)與錄音婉徘,去河邊找鬼。 笑死咐汞,一個(gè)胖子當(dāng)著我的面吹牛盖呼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播化撕,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼几晤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了植阴?” 一聲冷哼從身側(cè)響起蟹瘾,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掠手,沒想到半個(gè)月后憾朴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喷鸽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年众雷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片做祝。...
    茶點(diǎn)故事閱讀 40,013評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡砾省,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出混槐,到底是詐尸還是另有隱情编兄,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布声登,位于F島的核電站狠鸳,受9級特大地震影響揣苏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碰煌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一舒岸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芦圾,春花似錦蛾派、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至夜焦,卻和暖如春壳澳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背茫经。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工巷波, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人卸伞。 一個(gè)月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓抹镊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親荤傲。 傳聞我的和親對象是個(gè)殘疾皇子垮耳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)遂黍,斷路器终佛,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • 1.1 spring IoC容器和beans的簡介 Spring 框架的最核心基礎(chǔ)的功能是IoC(控制反轉(zhuǎn))容器,...
    simoscode閱讀 6,717評論 2 22
  • 本來是準(zhǔn)備看一看Spring源碼的雾家。然后在知乎上看到來一個(gè)帖子铃彰,說有一群**自己連Spring官方文檔都沒有完全讀...
    此魚不得水閱讀 6,935評論 4 21
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong閱讀 22,409評論 1 92
  • 一天,過了一天 窗外的樹葉又長大一點(diǎn) 世界慢慢是暖春季節(jié) 一天唬党,過了一天 世界還是一片蒙蒙細(xì)雨 空氣中都是泥土香味...
    不過花開閱讀 367評論 0 1