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


免責聲明!

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



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