1. 程式人生 > >spring自定義類中@AutoWired標識的元素注入為null

spring自定義類中@AutoWired標識的元素注入為null

最近在做專案的時候,發現程式執行的時候有一個nullpointer exception,一臉懵逼因為感覺程式沒什麼邏輯。後來發現是因為new出來的component不會自動注入它的元素。

現象:@Component修飾的自定義普通類中@Autowired屬性為null

原因:如果是通過new例項化的物件,脫離了Spring的管理,所以獲取不到Spring註解的屬性值。

在新執行緒中也會存在註解獲取不到Spring管理的Bean,也是因為new出來的執行緒,脫離了Spring容器

 

我在實際開發中遇到有一段公共的程式碼,幾個方法都需要掉,但如果單獨拉出來寫一個方法的話,入參又不同,所以想到了用泛型。

比如這是一段公共程式碼:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 //儲存訂單資訊,需要多個方法呼叫 OrderFilterRequest orderFilterRequest =  new  OrderFilterRequest(); btOrderFilterRequest.setUserId( "1" ); btOrderFilterRequest.setStatus(
"0" ); List<Order> orderResultList = orderService.findOrders(orderFilterRequest); Order result =  null ; if (CollectionUtils.isEmpty(orderResultList )){      Order order = CopierUtils.convert(request, Order. class );      order.setRealName(customer.getRealName());      order.setIdcardNo(customer.getIdcardNo());      order.setOrderNo( "order"  + DateUtil.getYMDHMS());      order.setStatus( "0" );      order.setCreateTime( new  Date());      order.setUpdateTime( new  Date());      order.setUserId( "1" );      result = orderService.createOrder(Order); } else {      Order orderResult =  orderResultList.get( 0 );      CopierUtils.copy(request, orderResult);      orderResult.setUpdateTime( new  Date());      result = orderService.updateOrder(btOrderResult); }

將這段程式碼提煉成泛型類:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 @Transactional (readOnly =  true ) @Component public  class  OrderRequest<T>{            @Autowired      private  OrderService orderService;        @Transactional      public  Order orderInfoSave(T request) {          OrderFilterRequest orderFilterRequest =  new  OrderFilterRequest();                  btOrderFilterRequest.setUserId( "1" );                  btOrderFilterRequest.setStatus( "0" );                  List<Order> orderResultList = orderService.findOrders(orderFilterRequest);                  Order result =  null ;                  if (CollectionUtils.isEmpty(orderResultList )){                      Order order = CopierUtils.convert(request, Order. class );                      order.setRealName(customer.getRealName());                      order.setIdcardNo(customer.getIdcardNo());                      order.setOrderNo( "order"  + DateUtil.getYMDHMS());                      order.setStatus( "0" );                      order.setCreateTime( new  Date());                      order.setUpdateTime( new  Date());                      order.setUserId( "1" );                      result = orderService.createOrder(Order);                  } else {                      Order orderResult =  orderResultList.get( 0 );                      CopierUtils.copy(request, orderResult);                      orderResult.setUpdateTime( new  Date());                      result = orderService.updateOrder(btOrderResult);                  }          return  result;      } }

最開始我是這麼呼叫的:

1 2 3 4 5 6 7 8 9 public  void  method1(Request1 request ) {       OrderRequest<Request1>  orderCreateRequest =  new  OrderRequest <Request1>();       Order result = OrderCreateRequest.orderInfoSave(request); }   public  void  method2(Request2 request ) {       OrderRequest<Request2>  orderCreateRequest =  new  OrderRequest <Request2>();       Order result = OrderCreateRequest.orderInfoSave(request); }

但是OrderRequest中orderService為null。(在controller層中注入service介面,在service層中注入orderService是有值的),嘗試可很多解決辦法,最後發現,原來spring自定義的類例項化時也需要用注入的方式,不能用new,否則脫離了spring的管理。改成如下方式就可以了:

1 2 3 4 5 6 7 8 9 10 11 12 @Autowired private  OrderRequest<Request1> request1; @Autowired private  OrderRequest<Request2> request2;   public  void  method1(Request1 request ) {       Order result = request1.orderInfoSave(request); }   public  void  method2(Request2 request ) {       Order result = request2.orderInfoSave(request); }  

 

總結:

    如果在A類中的屬性b有@Autowired這樣的註解,則類A的例項化不能用new 操作,必須要用注入的方式,否則脫離了spring的管理;

 

解決方法:

呼叫ApplicationContextUtil.getApplicationContext().getBean("XXX", XXX.class);方法獲取component