spring自定义类中@AutoWired标识的元素注入为null

Posted Boblim

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

以上是关于spring自定义类中@AutoWired标识的元素注入为null的主要内容,如果未能解决你的问题,请参考以下文章

spring autowired怎么按照name注入

springBoot自定义注解

springBoot自定义注解

Spring MVC 自定义标签如何使用@Autowired自动装配注解

Autowired 在自定义约束验证器中给出 Null 值

spring boot filter -Autowired