Spring中new出一个对象导致的空指针异常

报错概述

背景

单体项目升级微服务时,在BeforeSave_2250042中调用了一个公共模块CommonVerifyHandlerverifySeal()方法,但是运行时显示空指针异常

代码

根据断点和报错信息可以看到是这里出错

image

大致报错内容

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2715c179] was not registered for synchronization because synchronization is not active
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@bd1cd86] will not be managed by Spring
==>  Preparing: select count(1) from 签约主体映射组织视图 where 签约主体编号=? and 组织编号 = ? 
==> Parameters: QYZT-0001(String), ORG100000(String)
<==    Columns: COUNT(1)
<==        Row: 1
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2715c179]
[http-nio-8075-exec-1] 01/26 21:51:18.703 ERROR [c.d.s.beforesave.BeforeSave_2250042] - 不涉及金额合同 保存前事件处理异常,功能编号:2250042,单据ID:624060420265480192,错误信息:{}
java.lang.NullPointerException: null
	at com.dhcc.sdg.beforeinsert.CommonVerifyHandler.verifySeal(CommonVerifyHandler.java:41)
	at com.dhcc.sdg.beforesave.BeforeSave_2250042.doBefore(BeforeSave_2250042.java:46)
	at 
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@79a446c1] was not registered for synchronization because synchronization is not active
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@bd1cd86] will not be managed by Spring
==>  Preparing: SELECT 集团内外 FROM 签约方信息视图 WHERE 签约方编号= ? AND DELETED_MARK =0 
==> Parameters: GYS-2022-013436(String)
<==    Columns: 集团内外
<==        Row: 0
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@79a446c1]

CommonVerifyHandler

@Component
public class CommonVerifyHandler {
    @Autowired
    public  CommonVerifyHandlerMapper commonVerifyHandlerMapper;
    /**
     * 验证印章 xlm
     */
    public boolean verifySeal(BillData billData){
        boolean result = true;
        String PHY_ID = billData.getMasterData().get("PHY_SEAL_ID").toString().trim();
        String PHY_PARTY_ID = getSignPhyId( billData);
        System.out.println("PHY_ID:"+PHY_ID+",PHY_PARTY_ID:"+PHY_PARTY_ID);
        System.out.println("开始执行commonVerifyHandlerMapper.sealInfo");
        List<String> maps = commonVerifyHandlerMapper.sealInfo(PHY_ID, PHY_PARTY_ID);
        System.out.println("map:"+maps);
        if (maps == null || maps.isEmpty()) {
            result = false;
        }
        return result;
    }
}

错误一:

commonVerifyHandler没有加入@Component注解被Spring管理

错误二:

BeforeSave_2250042commonVerifyHandler没有被注入,相当于于commonVerifyHandler是new出来的


在Spring管理的类中直接通过new关键字来创建一个对象(模块)时,Spring容器本身是不会自动识别和管理这个新创建的对象的。Spring容器负责管理和装配的是那些被它自己创建和初始化的bean。

使用new来创建一个对象时,这个对象是在Spring容器的控制之外的,也就是说,它不会享受到Spring容器的任何服务,比如依赖注入、事务管理、AOP等。

如果想要Spring容器能够识别并管理一个对象,需要将这个对象声明为一个Spring bean。这可以通过在类上添加@Component@Service@Repository@Controller等注解来实现,或者在Spring的配置文件中显式地声明这个bean。

如果确实需要在Spring管理的类中创建一个新的对象,并且希望这个对象能够享受到Spring容器的某些服务,你可以考虑使用ApplicationContext.getBean()方法来从Spring容器中获取这个对象,而不是直接使用new来创建它。但是,这要求这个对象必须已经被声明为一个Spring bean,并且已经被Spring容器初始化和管理。

另外,如果想要Spring容器能够管理通过new关键字创建的对象的某些方面,可以考虑使用AspectJ等AOP框架来在运行时动态地为这些对象添加额外的行为。但是,这通常会增加系统的复杂性和维护成本,因此应该谨慎使用。

总之,直接在Spring管理的类中通过new来创建一个对象通常不是一个好的做法,除非有特殊的理由需要这样做,并且了解这样做可能带来的后果。更好的做法是让Spring容器来负责对象的创建和管理,这样可以确保对象能够享受到Spring容器提供的所有服务,并且更容易地进行单元测试和集成测试。

posted @ 2024-04-18 01:32  燕子去了  阅读(2)  评论(0编辑  收藏  举报

我会翻山越岭,到每一个我想去的地方

...