为了账号安全,请及时绑定邮箱和手机立即绑定

运行从 springboot 项目打包的 jar 时无法获取 bean

运行从 springboot 项目打包的 jar 时无法获取 bean

料青山看我应如是 2023-03-17 17:09:02
我可以在 IDEA 中很好地运行我的 springboot 项目,但是当将它打包到一个 jar 并使用 java 命令运行时,从 spring 上下文获取 bean 时只得到 java.lang.NullPointerException。刚刚出现错误的第一堂课:@Servicepublic class MdspiImpl extends CThostFtdcMdSpi {public MdspiImpl(CThostFtdcMdApi mdapi) {        m_mdapi = mdapi;        logger.info("MdspiImpl is creating...");        ***mdr = SpringContextUtil.getBean("marketDataRobot");//this is the error code***    }}第二类:@Servicepublic class MarketDataRobot {}SpringContextUtil 类:@Component("SpringContextUtil")public class SpringContextUtil implements ApplicationContextAware {    private static ApplicationContext applicationContext;    public static <T> T getBean(String name) {        return (T) applicationContext.getBean(name);    }}渐变文件:jar {    baseName = 'programmingTrading'    version =  '0.1.0'    manifest {        attributes 'Main-Class': 'com.blackHole.programmingTrading'    }}这是使用 SpringContextUtil 获取 bean 的部分原因......非常感谢!
查看完整描述

2 回答

?
慕娘9325324

TA贡献1783条经验 获得超4个赞

SpringContextUtil不应该像您正在做的那样静态访问...因为您将其定义为@Component执行以下操作;


@Service

public class MdspiImpl extends CThostFtdcMdSpi {


    @Autowired

    private SpringContextUtil springContextUtil;


    public MdspiImpl(CThostFtdcMdApi mdapi) {

        m_mdapi = mdapi;

        logger.info("MdspiImpl is creating...");

        ***mdr = springContextUtil.getBean("marketDataRobot");

    }

}

由于SpringContextUtil不是通过 Spring 注入,而是简单地静态访问,因此applicationContext它的内部被忽略并且在您的情况下为 null。


同时去掉static修饰符;


@Component

public class SpringContextUtil implements ApplicationContextAware {


    private ApplicationContext applicationContext;


    // include getter/setter for applicationContext as well


    public <T> T getBean(String name) {

        return (T) applicationContext.getBean(name);

    }

}

编辑


来自最新示例项目的麻烦;


@Service

public class ExampleService {

    @Autowired

    private Logger logger;


    public ExampleService() {

        this.logger=logger;

        logger.info("Im working");

    }

}

这里Logger将是 null,当ExampleService构造函数被触发时,因为构造函数在注入开始之前被调用,但是如果您通过所述构造函数合并注入,则可以合并此行为,如下所示;


@Service

public class ExampleService {


    private final Logger logger;


    public ExampleService(Logger logger) {

        this.logger = logger;

        logger.info("Im working");

    }

}

完美运行,没有任何问题......


查看完整回答
反对 回复 2023-03-17
?
慕森王

TA贡献1777条经验 获得超3个赞

您永远不应该像使用 this 那样以编程方式访问 bean SpringContextUtil,只需注入MarketDataRobot的构造函数MdspiImpl就可以了(因为它被注释为@Service)。首选的方法是使用构造函数注入而不是字段注入,这将使您更容易编写单元测试。@Autowired如果你只有一个构造函数,你也可以去掉。



查看完整回答
反对 回复 2023-03-17
  • 2 回答
  • 0 关注
  • 338 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信