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

猜你喜欢

转载自www.cnblogs.com/fnlingnzb-learner/p/9939873.html