spring自定義類中@AutoWired標識的元素注入為null
阿新 • • 發佈:2018-11-10
最近在做專案的時候,發現程式執行的時候有一個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