最近在做项目的时候,发现程序运行的时候有一个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. Nodejs新手村指引——30分钟上手

    概要 #准备工作 #开启简单的服务 #路由 #获取参数的三种方式 #静态文件 #数据库集成 #async解决多重嵌套问题 本文适合没有nodejs项目开发经验而又想对nodejs有个大概了解的你阅读, ...

  2. JSP中的指令概述和示例

    一.JSP——Java server page :java服务端的页面,这是属于一个后端技术 1.前端技术: html.css.javascript 2.后端技术: java语言.框架(mybatis ...

  3. Android-Binder(一)

    Android-Binder(一) 学习自 <Android开发艺术探索> https://www.jianshu.com/p/bdef9e3178c9 https://blog.csdn ...

  4. UOJ.41.[清华集训2014]矩阵变换(稳定婚姻)

    题目链接 稳定婚姻问题:有n个男生n个女生,每个男/女生对每个女/男生有一个不同的喜爱程度.给每个人选择配偶. 若不存在 x,y未匹配,且x喜欢y胜过喜欢x当前的配偶,y喜欢x也胜过y当前的配偶 的完 ...

  5. Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem C. Cargo Transportation 暴力

    Problem C. Cargo Transportation 题目连接: http://opentrains.snarknews.info/~ejudge/team.cgi?SID=c75360ed ...

  6. FireDAC 下的 Sqlite [9] - 关于排序

    SQLite 内部是按二进制排序, 可以支持 ANSI; FrieDAC 通过 TFDSQLiteCollation 支持了 Unicode 排序, 并可通过其 OnCompare 事件自定义排序. ...

  7. 【Go命令教程】4. go get

    hc@ubt:~$ go get github.com/hyper-carrot/go_lib/logging 命令 go get 可以根据要求和实际情况从互联网上下载或更新指定的代码包及其依赖包,并 ...

  8. 面试题07_用两个栈实现队列——剑指offer系列

    题目描写叙述: 用两个栈实现一个队列. 队列的声明例如以下,请实现它的两个函数appendTail 和 deleteHead.分别完毕在队列尾部插入结点和在队列头部删除结点的功能. 解题思路: 栈的特 ...

  9. 搭建《深入Linux内核架构》的Linux环境

    作者 彭东林 pengdonglin137@163.com 软件 Host: Ubuntu14.04 64 Qemu 2.8.0 Linux 2.6.24 busybox 1.24.2 gcc 4.4 ...

  10. WordPress主题开发实例:查询单篇文章

    xxx/?page_id=5 想在首页调用以上页面的内容怎么做呢? 完整: <?php //查询 $my_query = new WP_Query( 'page_id=5' ); if($my_ ...