• 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

  • 相关阅读:
    React使用iconfont图标下载到本地symbol引用
    【汇编】求100以内的素数asm
    jQuery Ajax.BeginForm方法回调函数高版本3.3.1不兼容问题
    python中的深拷贝与浅拷贝
    闲来无事做个C#小项目——2
    C#使用MD5加密
    数据结构部分总结(c语言版)
    vue 上传视频和图片 并且截取视频第一帧作为播放前默认图片
    vue el-cascader取id和lable的值
    C# 枚举的定义,枚举的用法,获取枚举值
  • 原文地址:https://www.cnblogs.com/fnlingnzb-learner/p/9939873.html
Copyright © 2020-2023  润新知