最近在做项目的时候,发现程序运行的时候有一个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的更多相关文章

  1. Spring自定义类扫描器 ClassPathScanningCandidateComponentProvider

    项目中有个需求 读取xml文件,然后 对xml文件进行解析,比如如果是 Gender=0/1的话,分别代表男女. 所以需要在构造函数之后,初始化bean之前进行过滤解析 xml文件: <inte ...

  2. spring boot 中@Autowired注解无法自动注入的错误

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/huihuilovei/article/de ...

  3. 关于在App_Code文件夹自定义类中Session无法使用

    由于前台页面需要调用App_Code中自定义类的函数,但在自定义类中找不到Session,解决方法如下: 新建一个类session,并自己定义函数GetSession(),引用命名空间 System. ...

  4. cocos2dx lua 绑定之一:自动绑定自定义类中的函数

    cococs2dx 3.13.1 + vs2013 + win10 1.首先定义C++类Student 在cocos2d-x\cocos文件夹下新建一个user_define的文件夹放置两个文件. 注 ...

  5. Spring同一个类中的注解方法调用AOP失效问题总结

    public interface XxxService { // a -> b void a(); void b(); } @Slf4j public class XxxServiceImpl ...

  6. 实体类相同属性间赋值与如何判断实体类中是否所有的字段都为null

    1,实体类相同属性间赋值 /// <summary> /// 将实体2的值动态赋值给实体1(名称一样的属性进行赋值) /// </summary> /// <param ...

  7. Spring Boot + Netty 中 @Autowired, @Value 为空解决

    问题描述 使用 Spring Boot + Netty 新建项目时 Handler 中的 @Autowired, @Value 注解的始终为空值 解决方法 @Component // 1. 添加 @C ...

  8. 关于工具类中@Autowired注入为NULL的问题记录

      记录:在实体类中加入@Component注解和@Autowired注解时Service不能注入成功. @Component //把普通pojo实例化到spring容器中 0 public clas ...

  9. 于工具类中@Autowired注入为NULL的问题记录

      记录:在实体类中加入@Component注解和@Autowired注解时Service不能注入成功. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ...

随机推荐

  1. tqdm:Python 进度条

    Tqdm 是 Python 进度条库,可以在 Python 长循环中添加一个进度提示信息.用户只需要封装任意的迭代器,是一个快速.扩展性强的进度条工具库. 用法:tqdm(iterator) 代码地址 ...

  2. js加入购物车抛物线动画

    天猫将商品加入购物车会有一个抛物线动画,告诉用户操作成功以及购物车的位置,业务中需要用到类似的效果,记录一下实现过程备忘,先上demo 一开始没有想到用抛物线函数去做,也已经忘记还有这么个函数了,想着 ...

  3. UI自动化测试(一)简介及Selenium工具的介绍和环境搭建

    自动化测试简介 1.1何为自动化测试? 是把以人为驱动的测试转化为机器执行的一种过程,它是一种以程序测试程序的过程.换言之,就是以程序实现的方式来代替手工测试. 1.2自动化测试分类 分为功能自动化测 ...

  4. Spring重复扫描导致事务失败的解决方案及深入分析

    问题及日志使用Spring和mybatis,然后配置事务,出现SqlSession was not registered for synchronization because synchroniza ...

  5. C/C++的64为长整型数的表示

    在C/C++中,64为整型一直是一种没有确定规范的数据类型.现今主流的编译器中,对64为整型的支持也是标准不一,形态各异.一般来说,64位整型的定义方式有long long和__int64两种(VC还 ...

  6. java基础学习总结——super关键字

    一.super关键字

  7. js识别用户设备是移动端手机时跳转到手机网站

    一.识别到用户的设备是手机等移动端设备时跳转到移动端网站 var mobileAgent = new Array("iphone", "ipod", " ...

  8. CentOS 7使用yum安装PHP5.6

    删除旧php包 yum remove php.x86_64 php-cli.x86_64 php-common.x86_64 php-gd.x86_64 php-ldap.x86_64 php-mbs ...

  9. 在触屏设备上面利用html5裁剪图片

    前言 如今触屏设备越来越流行,并且大多数已经支持html5了.针对此.对触屏设备开发图片裁剪功能, 让其能够直接处理图片.减轻服务端压力. 技术点 浏览器必须支持html5,包含fileReader. ...

  10. SpringBoot 中使用 @Value 为 static 变量赋值

    原文:https://www.jianshu.com/p/ea477fc9abf7 例如: public class Utils { @Value("${test.host}") ...