最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot?隱式參數(shù)注入詳解告別重復(fù)代碼,讓?Controller?更優(yōu)雅

 更新時(shí)間:2026年03月10日 09:47:40   作者:程序員西西  
本文介紹了使用SpringBoot的HandlerMethodArgumentResolver實(shí)現(xiàn)隱式參數(shù)注入的技巧,通過(guò)自定義注解和解析器,可以簡(jiǎn)化Controller中的重復(fù)參數(shù)處理邏輯,提升代碼的可維護(hù)性和可讀性,感興趣的朋友跟隨小編一起看看吧

前言

你是不是也遇到過(guò)這樣的情況?在開(kāi)發(fā) SpringBoot 接口時(shí),只要涉及用戶(hù)信息、請(qǐng)求上下文這類(lèi)通用參數(shù),就不得不重復(fù)寫(xiě)request.getAttribute("userId")或者ThreadLocal.get()的代碼?有時(shí)候一個(gè)項(xiàng)目里幾十上百個(gè)接口,每個(gè)接口都要做一遍參數(shù)獲取、類(lèi)型轉(zhuǎn)換,不僅寫(xiě)得煩躁,還容易因?yàn)槭终`出現(xiàn)NullPointerException—— 比如忘了判空,或者把String類(lèi)型的用戶(hù) ID 錯(cuò)轉(zhuǎn)成Long。

前陣子我?guī)屯屡挪橐粋€(gè)線上問(wèn)題,就是因?yàn)樵谌齻€(gè)不同的Service方法里重復(fù)寫(xiě)了ThreadLocal獲取用戶(hù)信息的邏輯,其中一個(gè)地方漏了判空,導(dǎo)致用戶(hù)登錄狀態(tài)過(guò)期時(shí)直接拋出異常。排查的時(shí)候翻了一大堆代碼才定位到問(wèn)題,當(dāng)時(shí)就想:有沒(méi)有辦法能把這些重復(fù)的參數(shù)處理邏輯 “藏起來(lái)”,讓 Controller 里只關(guān)注核心業(yè)務(wù)邏輯?今天就跟大家分享一個(gè) SpringBoot 自帶的 “隱藏技能”—— 隱式參數(shù)注入,幫你徹底解決這個(gè)痛點(diǎn)。

為什么重復(fù)參數(shù)處理會(huì)成為 “坑”?

在聊解決方案之前,我們先搞清楚:為什么重復(fù)的參數(shù)獲取邏輯會(huì)頻繁出問(wèn)題?其實(shí)本質(zhì)上是兩個(gè)原因:代碼冗余導(dǎo)致的維護(hù)成本高,以及手動(dòng)處理的容錯(cuò)性差。

先說(shuō)說(shuō)代碼冗余。以獲取當(dāng)前登錄用戶(hù) ID 為例,傳統(tǒng)的做法通常是這樣:要么在 Controller 里通過(guò)HttpServletRequest獲取請(qǐng)求頭或請(qǐng)求參數(shù)里的用戶(hù)信息,再傳給 Service;要么用 ThreadLocal 把用戶(hù)信息存在線程上下文里,在 Service 層直接獲取。不管哪種方式,只要多個(gè)接口、多個(gè) Service 需要用到用戶(hù)信息,就必須重復(fù)寫(xiě)這段邏輯。我之前統(tǒng)計(jì)過(guò)一個(gè)中型項(xiàng)目,單是 “獲取用戶(hù) ID 并轉(zhuǎn)換為 Long 類(lèi)型” 這段代碼,就在 23 個(gè)地方出現(xiàn)過(guò),后來(lái)因?yàn)橛脩?hù) ID 規(guī)則調(diào)整(從自增 Long 改成 String),光是修改這些重復(fù)代碼就花了大半天,還差點(diǎn)漏改了兩個(gè)隱藏在工具類(lèi)里的地方。

再說(shuō)說(shuō)容錯(cuò)性差。手動(dòng)處理參數(shù)時(shí),我們很容易忽略邊界情況:比如用戶(hù)未登錄時(shí)request.getAttribute("userId")返回 null,直接強(qiáng)轉(zhuǎn)會(huì)拋ClassCastException;或者前端傳的用戶(hù) ID 格式不對(duì),轉(zhuǎn)成 Long 時(shí)會(huì)拋NumberFormatException。這些問(wèn)題如果沒(méi)做統(tǒng)一的異常處理,就會(huì)直接暴露給用戶(hù),影響體驗(yàn)。更麻煩的是,不同開(kāi)發(fā)人員處理這些邊界情況的方式不一樣:有的加了判空,有的沒(méi)加;有的返回 401,有的返回 500,導(dǎo)致項(xiàng)目代碼風(fēng)格混亂,排查問(wèn)題時(shí)也找不到統(tǒng)一的入口。

其實(shí) SpringBoot 早就為我們提供了更優(yōu)雅的解決方案,只是很多人沒(méi)注意到 —— 通過(guò)自定義
HandlerMethodArgumentResolver,實(shí)現(xiàn)參數(shù)的隱式注入,讓框架幫我們搞定這些重復(fù)且容易出錯(cuò)的邏輯。

三步實(shí)現(xiàn) SpringBoot 隱式參數(shù)注入

接下來(lái)就是核心部分:具體怎么實(shí)現(xiàn)隱式參數(shù)注入?整個(gè)過(guò)程只需要三步,不需要引入任何第三方依賴(lài),純 SpringBoot 原生支持。我們以 “注入當(dāng)前登錄用戶(hù)信息” 為例,一步步拆解操作流程。

第一步:定義參數(shù)封裝類(lèi)(DTO)

首先,我們需要一個(gè)類(lèi)來(lái)封裝要注入的參數(shù),比如當(dāng)前登錄用戶(hù)的 ID、用戶(hù)名、角色等信息。這個(gè)類(lèi)不用加任何特殊注解,就是一個(gè)普通的 POJO:

/**
 * 當(dāng)前登錄用戶(hù)信息封裝類(lèi)
 */
@Data
public class CurrentUser {
    // 用戶(hù)ID
    private Long userId;
    // 用戶(hù)名
    private String username;
    // 用戶(hù)角色
    private String role;
    // 登錄token(可選,根據(jù)業(yè)務(wù)需求添加)
    private String token;
}

這里要注意:封裝類(lèi)里的字段要跟你從請(qǐng)求中獲取到的用戶(hù)信息對(duì)應(yīng),比如從 JWT 令牌解析出的用戶(hù) ID、用戶(hù)名,或者從 Session 中獲取的角色信息。字段類(lèi)型也要提前確定好,避免后續(xù)轉(zhuǎn)換時(shí)出問(wèn)題。

第二步:自定義參數(shù)解析器(HandlerMethodArgumentResolver)

這是實(shí)現(xiàn)隱式注入的關(guān)鍵步驟。SpringBoot 在處理 Controller 方法參數(shù)時(shí),會(huì)調(diào)用
HandlerMethodArgumentResolver接口的兩個(gè)方法:supportsParameter判斷當(dāng)前參數(shù)是否需要用這個(gè)解析器處理,resolveArgument則是具體的參數(shù)獲取和封裝邏輯。

我們先寫(xiě)一個(gè)自定義的解析器,實(shí)現(xiàn)從請(qǐng)求頭的 JWT 令牌中解析用戶(hù)信息,并封裝成CurrentUser對(duì)象:

/**
 * 自定義當(dāng)前用戶(hù)參數(shù)解析器
 */
@Component
public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver {
    // 注入JWT工具類(lèi)(實(shí)際項(xiàng)目中可自行實(shí)現(xiàn))
    @Autowired
    private JwtUtils jwtUtils;
    /**
     * 判斷參數(shù)是否需要解析:如果參數(shù)類(lèi)型是CurrentUser,且加了@CurrentUser注解(后面會(huì)定義),就用這個(gè)解析器
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        // 1. 判斷參數(shù)類(lèi)型是否是CurrentUser
        boolean isCurrentUserType = parameter.getParameterType().equals(CurrentUser.class);
        // 2. 判斷參數(shù)是否加了@CurrentUser注解
        boolean hasCurrentUserAnnotation = parameter.hasParameterAnnotation(CurrentUser.class);
        // 兩個(gè)條件都滿(mǎn)足才解析
        return isCurrentUserType && hasCurrentUserAnnotation;
    }
    /**
     * 具體的參數(shù)解析邏輯:從請(qǐng)求頭獲取JWT令牌,解析出用戶(hù)信息,封裝成CurrentUser對(duì)象
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        // 1. 從請(qǐng)求頭獲取JWT令牌(假設(shè)前端將令牌放在Authorization請(qǐng)求頭中,格式為Bearer xxx)
        String authorizationHeader = webRequest.getHeader("Authorization");
        if (StringUtils.isEmpty(authorizationHeader) || !authorizationHeader.startsWith("Bearer ")) {
            // 如果沒(méi)有令牌,返回空的CurrentUser(也可根據(jù)業(yè)務(wù)需求拋出未登錄異常)
            return new CurrentUser();
        }
        String token = authorizationHeader.substring(7); // 去掉"Bearer "前綴
        // 2. 解析JWT令牌,獲取用戶(hù)信息(JwtUtils為自定義工具類(lèi),此處省略實(shí)現(xiàn))
        Claims claims = jwtUtils.parseToken(token);
        Long userId = claims.get("userId", Long.class);
        String username = claims.get("username", String.class);
        String role = claims.get("role", String.class);
        // 3. 封裝成CurrentUser對(duì)象并返回
        CurrentUser currentUser = new CurrentUser();
        currentUser.setUserId(userId);
        currentUser.setUsername(username);
        currentUser.setRole(role);
        currentUser.setToken(token);
        return currentUser;
    }
}

這里有兩個(gè)關(guān)鍵點(diǎn)需要注意:

  1. 我們定義了一個(gè)@CurrentUser注解(代碼在下一步),用來(lái)標(biāo)記需要隱式注入的參數(shù)。這樣做的好處是:如果其他地方也用到CurrentUser類(lèi)作為參數(shù),但不需要隱式注入,就不會(huì)被這個(gè)解析器處理,靈活性更高;
  2. 在resolveArgument方法中,一定要做好異常處理。比如令牌不存在、令牌過(guò)期、令牌解析失敗等情況,要根據(jù)業(yè)務(wù)需求返回默認(rèn)值或拋出統(tǒng)一的異常(建議結(jié)合全局異常處理器使用),避免直接拋原生異常。

接下來(lái)定義@CurrentUser注解,這個(gè)注解很簡(jiǎn)單,只需要標(biāo)記在方法參數(shù)上即可:

/**
 * 標(biāo)記當(dāng)前登錄用戶(hù)參數(shù)的注解
 */
@Target(ElementType.PARAMETER) // 只能用在方法參數(shù)上
@Retention(RetentionPolicy.RUNTIME) // 運(yùn)行時(shí)生效
public @interface CurrentUser {
}

第三步:注冊(cè)參數(shù)解析器

最后一步,我們需要把自定義的
CurrentUserArgumentResolver注冊(cè)到 SpringBoot 的參數(shù)解析器列表中,讓 SpringBoot 在處理 Controller 參數(shù)時(shí)能找到它。有兩種注冊(cè)方式,根據(jù)你的 SpringBoot 版本選擇即可。

方式一:實(shí)現(xiàn) WebMvcConfigurer 接口(推薦,SpringBoot 2.x 及以上)

/**
 * SpringMVC配置類(lèi)
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    private CurrentUserArgumentResolver currentUserArgumentResolver;
    /**
     * 注冊(cè)自定義參數(shù)解析器
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        // 把自定義解析器添加到列表中(建議放在前面,優(yōu)先級(jí)更高)
        resolvers.add(0, currentUserArgumentResolver);
    }
}

方式二:繼承 WebMvcConfigurationSupport 類(lèi)(適用于需要自定義更多配置的場(chǎng)景)

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    @Autowired
    private CurrentUserArgumentResolver currentUserArgumentResolver;
    @Override
    protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(currentUserArgumentResolver);
        // 注意:繼承WebMvcConfigurationSupport時(shí),需要手動(dòng)添加默認(rèn)的解析器,否則會(huì)覆蓋默認(rèn)配置
        super.addArgumentResolvers(resolvers);
    }
}

這里要提醒一下:如果用方式二,一定要調(diào)用
super.addArgumentResolvers(resolvers),否則會(huì)覆蓋 SpringBoot 默認(rèn)的參數(shù)解析器(比如@RequestParam、@RequestBody的解析器),導(dǎo)致其他參數(shù)無(wú)法正常解析。

實(shí)際效果:代碼簡(jiǎn)化了多少?

注冊(cè)完成后,我們就可以在 Controller 中直接使用@CurrentUser注解獲取用戶(hù)信息了。對(duì)比一下傳統(tǒng)寫(xiě)法和隱式注入寫(xiě)法的區(qū)別:

傳統(tǒng)寫(xiě)法(冗余):

@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private OrderService orderService;
    @PostMapping("/create")
    public Result createOrder(HttpServletRequest request, @RequestBody OrderCreateDTO orderDTO) {
        // 1. 重復(fù)獲取用戶(hù)信息:每個(gè)接口都要寫(xiě)
        String token = request.getHeader("Authorization");
        Claims claims = JwtUtils.parseToken(token);
        Long userId = claims.get("userId", Long.class);
        // 2. 重復(fù)判空:每個(gè)接口都要處理
        if (userId == null) {
            return Result.fail("用戶(hù)未登錄");
        }
        // 3. 核心業(yè)務(wù)邏輯
        return Result.success(orderService.createOrder(userId, orderDTO));
    }
}

隱式注入寫(xiě)法(簡(jiǎn)潔):

@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private OrderService orderService;
    @PostMapping("/create")
    public Result createOrder(@CurrentUser CurrentUser currentUser, @RequestBody OrderCreateDTO orderDTO) {
        // 1. 直接使用currentUser,無(wú)需重復(fù)獲取和判空(判空邏輯在解析器中統(tǒng)一處理)
        if (currentUser.getUserId() == null) {
            return Result.fail("用戶(hù)未登錄");
        }
        // 2. 核心業(yè)務(wù)邏輯:專(zhuān)注于訂單創(chuàng)建,不用關(guān)心用戶(hù)信息從哪來(lái)
        return Result.success(orderService.createOrder(currentUser.getUserId(), orderDTO));
    }
}

可以看到,每個(gè)接口至少減少了 3-5 行重復(fù)代碼,而且如果后續(xù)用戶(hù)信息的獲取邏輯需要調(diào)整(比如從 JWT 改成 Session,或者新增用戶(hù)手機(jī)號(hào)字段),只需要修改
CurrentUserArgumentResolver和CurrentUser類(lèi),不用逐個(gè)修改接口 —— 這就是 “一處修改,處處生效”,極大降低了維護(hù)成本。

更重要的是,容錯(cuò)性也提升了。比如之前提到的 “用戶(hù) ID 格式錯(cuò)誤” 問(wèn)題,現(xiàn)在可以在解析器中統(tǒng)一處理:

// 在resolveArgument方法中添加格式校驗(yàn)
try {
    Long userId = claims.get("userId", Long.class);
} catch (ClassCastException e) {
    // 統(tǒng)一返回參數(shù)格式錯(cuò)誤的異常
    throw new BusinessException("用戶(hù)ID格式錯(cuò)誤", 400);
}

結(jié)合全局異常處理器,就能給用戶(hù)返回統(tǒng)一格式的錯(cuò)誤信息,不用在每個(gè)接口里單獨(dú)處理格式問(wèn)題。

進(jìn)階用法:不止于用戶(hù)信息

看到這里,你可能會(huì)問(wèn):這個(gè)隱式參數(shù)注入只能用來(lái)注入用戶(hù)信息嗎?當(dāng)然不是!只要是需要從請(qǐng)求上下文(Request、Session、ThreadLocal 等)中獲取的參數(shù),都可以用這種方式實(shí)現(xiàn)隱式注入,比如:

1. 注入請(qǐng)求追蹤 ID(用于日志排查)

很多項(xiàng)目會(huì)在請(qǐng)求頭中加入Trace-Id,用來(lái)追蹤整個(gè)請(qǐng)求鏈路的日志。傳統(tǒng)寫(xiě)法需要在每個(gè) Controller 方法中獲取Trace-Id,再傳給 Service 層的日志工具類(lèi)。用隱式注入的話(huà),只需要定義TraceId類(lèi)和TraceIdArgumentResolver,就能直接在方法參數(shù)中注入@TraceId String traceId。

2. 注入客戶(hù)端設(shè)備信息(用于適配不同設(shè)備)

如果你的項(xiàng)目需要區(qū)分用戶(hù)是從 PC 端還是移動(dòng)端訪問(wèn),可以在解析器中解析User-Agent請(qǐng)求頭,封裝成DeviceInfo對(duì)象(包含設(shè)備類(lèi)型、瀏覽器版本等),然后在 Controller 中用@DeviceInfo DeviceInfo deviceInfo直接獲取,不用重復(fù)解析User-Agent。

3. 注入接口訪問(wèn)頻率限制信息

對(duì)于需要做接口限流的場(chǎng)景,可以在解析器中檢查當(dāng)前用戶(hù)的訪問(wèn)頻率(比如從 Redis 中獲取訪問(wèn)次數(shù)),封裝成RateLimitInfo對(duì)象(包含剩余訪問(wèn)次數(shù)、下次重置時(shí)間),在 Controller 中判斷是否需要限流,避免在每個(gè)接口中重復(fù)寫(xiě)限流邏輯。

這些進(jìn)階用法的實(shí)現(xiàn)思路和 “注入用戶(hù)信息” 完全一致,核心都是:將重復(fù)的參數(shù)處理邏輯抽離到解析器中,讓 Controller 聚焦業(yè)務(wù)。

總結(jié):為什么推薦你立刻用起來(lái)?

回顧一下今天分享的內(nèi)容:我們通過(guò)自定義
HandlerMethodArgumentResolver,實(shí)現(xiàn)了 SpringBoot 的隱式參數(shù)注入,解決了傳統(tǒng)參數(shù)處理中 “代碼冗余” 和 “容錯(cuò)性差” 的問(wèn)題。總結(jié)下來(lái),這個(gè)方案有三個(gè)核心優(yōu)勢(shì):

  1. 降低維護(hù)成本:重復(fù)邏輯集中管理,修改時(shí)不用逐個(gè)調(diào)整接口;
  2. 提升代碼可讀性:Controller 中只保留核心業(yè)務(wù)邏輯,新人接手時(shí)更容易理解;
  3. 統(tǒng)一容錯(cuò)標(biāo)準(zhǔn):邊界情況(如參數(shù)為空、格式錯(cuò)誤)在解析器中統(tǒng)一處理,避免代碼風(fēng)格混亂。

如果你正在開(kāi)發(fā) SpringBoot 項(xiàng)目,而且項(xiàng)目中存在大量重復(fù)的參數(shù)獲取邏輯,建議你現(xiàn)在就動(dòng)手試試這個(gè)方案。從定義CurrentUser類(lèi)開(kāi)始,到注冊(cè)解析器,整個(gè)過(guò)程不到 30 分鐘就能完成,卻能在后續(xù)的開(kāi)發(fā)中節(jié)省大量時(shí)間。

最后,也想跟大家互動(dòng)一下:你在項(xiàng)目中還遇到過(guò)哪些 “重復(fù)代碼” 的痛點(diǎn)?是怎么解決的?歡迎在評(píng)論區(qū)分享你的經(jīng)驗(yàn),我們一起探討更優(yōu)雅的編碼方式!

到此這篇關(guān)于SpringBoot 隱式參數(shù)注入:告別重復(fù)代碼,讓 Controller 更優(yōu)雅的文章就介紹到這了,更多相關(guān)SpringBoot 隱式參數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java map.getOrDefault()方法的用法詳解

    Java map.getOrDefault()方法的用法詳解

    這篇文章主要介紹了Java map.getOrDefault()方法的用法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • spring mvc4的日期/數(shù)字格式化、枚舉轉(zhuǎn)換示例

    spring mvc4的日期/數(shù)字格式化、枚舉轉(zhuǎn)換示例

    本篇文章主要介紹了spring mvc4的日期/數(shù)字格式化、枚舉轉(zhuǎn)換示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-01-01
  • java中通用的線程池實(shí)例代碼

    java中通用的線程池實(shí)例代碼

    java中通用的線程池實(shí)例代碼,需要的朋友可以參考一下
    2013-03-03
  • Spring?Boot中使用Spring?Retry重試框架的操作方法

    Spring?Boot中使用Spring?Retry重試框架的操作方法

    這篇文章主要介紹了Spring?Retry?在SpringBoot?中的應(yīng)用,介紹了RetryTemplate配置的時(shí)候,需要設(shè)置的重試策略和退避策略,需要的朋友可以參考下
    2022-04-04
  • Java中的數(shù)組與集合基本用法詳解

    Java中的數(shù)組與集合基本用法詳解

    本文介紹了Java數(shù)組和集合框架的基礎(chǔ)知識(shí),數(shù)組部分涵蓋了一維、二維及多維數(shù)組的聲明、初始化、訪問(wèn)與遍歷方法,以及Arrays類(lèi)的常用操作,對(duì)Java數(shù)組與集合相關(guān)知識(shí)感興趣的朋友一起看看吧
    2025-07-07
  • Java校驗(yàn)是否為連續(xù)的區(qū)間問(wèn)題

    Java校驗(yàn)是否為連續(xù)的區(qū)間問(wèn)題

    這篇文章主要介紹了Java校驗(yàn)是否為連續(xù)的區(qū)間問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • SpringBoot無(wú)法訪問(wèn)/static下靜態(tài)資源的解決

    SpringBoot無(wú)法訪問(wèn)/static下靜態(tài)資源的解決

    這篇文章主要介紹了SpringBoot無(wú)法訪問(wèn)/static下靜態(tài)資源的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java設(shè)計(jì)哈希映射的方法

    Java設(shè)計(jì)哈希映射的方法

    這篇文章主要介紹了Java設(shè)計(jì)哈希映射的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2025-05-05
  • PowerJob UseCacheLock工作流程源碼剖析

    PowerJob UseCacheLock工作流程源碼剖析

    這篇文章主要為大家介紹了PowerJob UseCacheLock工作流程源碼剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Springboot日期轉(zhuǎn)換器實(shí)現(xiàn)代碼及示例

    Springboot日期轉(zhuǎn)換器實(shí)現(xiàn)代碼及示例

    這篇文章主要介紹了Springboot日期轉(zhuǎn)換器實(shí)現(xiàn)代碼及示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08

最新評(píng)論

绩溪县| 平乡县| 马关县| 黄龙县| 阿鲁科尔沁旗| 阜新市| 湾仔区| 慈利县| 阳谷县| 嘉黎县| 通化市| 精河县| 湘潭市| 宁武县| 彰武县| 定兴县| 洪湖市| 福州市| 宜兰市| 响水县| 和林格尔县| 北碚区| 铜川市| 淄博市| 镇平县| 甘德县| 武城县| 宾川县| 锦州市| 托克托县| 鹰潭市| 临湘市| 重庆市| 班玛县| 新兴县| 马关县| 通江县| 郁南县| 南岸区| 西安市| 万年县|