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

原文地址:https://www.cnblogs.com/fnlingnzb-learner/p/9939873.html

时间: 2024-10-05 02:52:41

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

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

由于前台页面需要调用App_Code中自定义类的函数,但在自定义类中找不到Session,解决方法如下: 新建一个类session,并自己定义函数GetSession(),引用命名空间 System.Web 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 6 public static class session 7 { 8 public static o

在自定义类中使用setMouseCallBack

TOP 在opencv学习中教程中的鼠标回调函数的使用,都是在主函数中调用,但在自定义类中调用该函数时,会出现参数的类型与形参不匹配问题.最后在stackoverflow中找到了一些解决办法. 鼠标调用的函数为: 1 /** @brief Sets mouse handler for the specified window 2 3 @param winname Name of the window. 4 @param onMouse Callback function for mouse ev

Spring同一个类中的方法互相调用,注解失效问题的分析和解决

以Transaction注解为例: @Service public class TestService { @Autowired Dao dao; @Transactional public void methodOne(Object o) { dao.save(o); } public void methodTwo(Object o) { methodOne(o); } } 检查事务是否启动: 设置log leve为debug,可以查看是否有下面这个log,判断是否启动了Transaction

cocos2dx lua 绑定之二:手动绑定自定义类中的函数

cococs2dx 3.13.1 + vs2013 + win10 1.首先按照<cocos2dx lua 绑定之一:自动绑定自定义类>绑定Student类 2.在Student类中增加一个用于测试手动绑定的函数manual_call ①Student.h中增加函数 //手动绑定调用函数 void manual_call(); ②Student.cpp中增加函数实现 //和自动绑定相比,只增加了这个函数 void Student::manual_call() { std::cout <&

自定义的类型放入STL的set中,需要重载自定义类中的“&lt;”符号(转)

在以前学习STL的时候,曾经学到过,如果要将自定义的类型放入到set中的话,就需要重载“<”符号,原因是set是一个有序的集合,集合会按照“<”比较的大小,默认按照从小到大的顺序排列.假设我现在设计如下类型: class MyType { public: int a, b, c; } 这是,为了让MyType类型可以顺利的放进set中,我必须重载“<”,这时问题来了,要如何重载呢?这个类型有三个数据成员,我能不能要求按照a的大小排列,如果a相等的话就随便按照b或者c的大小排列呢?如果近实

【从零之三(更)】自定义类中调用讯飞语音包错误解决办法

原文:http://blog.csdn.net/monkeyduck/article/details/24302655 在科大讯飞语音包的Mscdemo中它的方法都是写在Activity中的,这样其实并不是很好,因为Activity只是负责UI交互的,如果项目很简单自然可以,但是一旦比较复杂肯定要自己定义很多包很多类,但是写在Activity中的方法就不能被自己定义的类调用了,咋办尼,那就把方法写在自己的类里就行了.准备工作:把Msc.jar包和libmsc.so拷贝到自己工程的libs目录下,

自定义类中定义两个方法,相互调用

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Test06 7 { 8 //class Class1 9 //{ 10 // public string Country() 11 // { 12 // string strCountry = "方法的示例!"; 13 // return strCountry; 14 /

(转).Net中自定义类作为Dictionary的key详解

在定义数据结构时,Dictionary提供了快速查找数据的功能,另外Dictionary< TKey, TValue >属于key-value键值对数据结构,提供了泛型的灵活性,是数据结构的一个利器,但是目前拥有的string,int,bool等基础数据类型并不能满足我们的需求,那么如何把自定义的数据类作为Dictionary的key呢? 本文对Dict的内部实现会有提出,但不详细讨论,以解决标题问题为主,如果有想详细了解Dictionary内部实现等更多细节,请转到官网: https://m

net core天马行空系列: 一个接口多个实现类,利用mixin技术通过自定义服务名,实现精准属性注入

系列目录 1.net core天马行空系列:原生DI+AOP实现spring boot注解式编程 2.net core天马行空系列: 泛型仓储和声明式事物实现最优雅的crud操作 哈哈哈哈,大家好,我就是高产似母猪的三合.日常开发中,我们常会遇到这样的场景,一个接口,有多个实现类,在某个业务中,我们希望指定某个实现类,如今网络上常见的解决方案,就是注入一个委托或者利用工厂模式,这些方式虽然能实现功能,但使用起来还是不够优雅,如何才称得上优雅呢?自然是在添加服务的时候给服务指定名称,注入的时候根据