Springboot的Bean的Scope


 這周在項目中遇到這樣一個Bug,代碼大致是這樣的,有一個LogEntity日志類,里面有一個InnerLog負責存儲每次請求的RPCInfo相關信息,

每次請求的時候會把RPC相關信息加入到InnerLog中。

public class LogEntity {

public LogEntity() {
}

private InnerLog inner = new InnerLog();
   public void addRpcInfo(RpcInfo rpcInfo) {
  if (gene == null) {
  initRpcGene();
  }
  if (rpcInfo.getRpctype() != null) {
   if (StringUtils.isBlank(rpcInfo.getRpcid())) {
   rpcInfo.setRpcid(gene.genRpcId());
   }
   inner.getInnerinfo().add(rpcInfo);
   }
  }
}

然后在Controller中,注入LogEntity,記錄日志信息。

@RestController
@RequestMapping("/v")
public class VideoController extends BaseController {

@Autowired
public VideoService videoService;

@Autowired
LogEntity logEntity;
  @Override
  @RequestMapping(value = "/search", method = RequestMethod.GET)
  public Response search(Request request) {
  long start = System.currentTimeMillis();
  logEntity.put(LogConst.STARTTIMESTAMP, String.valueOf(start));
     ......
  ......
     logEntity.logging(logger);
  }
}

然后在壓測的時候發現日志很快就到幾十個G了。排查發現第二次請求時候的InnerLog中也包括第一次的InnerLog信息。這說明第二次請求和第一次請求

的時候用的是一個LogEntity實例。因此,想到這應該是注入的問題。因為對SpringBoot研究不是很深入,只是會簡單的實用。因此,對一些性質還不是很

了解。查閱資料發現,注入的Bean是有范圍可選的,默認的范圍是Singleton,也就是容器中只有一個Bean實例。接下來,詳細的看看Bean都有那幾類范

圍:

(1)singleton: 表示在spring容器中的單例,通過spring容器獲得該bean時總是返回唯一的實例

(2)prototype:表示每次獲得bean都會生成一個新的對象

(3)request:表示在一次http請求內有效(只適用於web應用)

(4)session:表示在一個用戶會話內有效(只適用於web應用)

(5)globalSession:表示在全局會話內有效(只適用於web應用)

在多數情況,我們只會使用singleton和prototype兩種scope,如果未指定scope屬性,默認為singleton。

因此,針對這個問題,我們可以再LogEntity類上加上@Scope("prototype")注解,問題就解決了。也可以不改變LogEntity的范圍,不過每次請求的時候新建

一個InnerLog就好了。

 

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM