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

我可以在 IDEA 中很好地运行我的 springboot 项目,但是当将它打包到一个 jar 并使用 java 命令运行时,从 spring 上下文获取 bean 时只得到 java.lang.NullPointerException。


刚刚出现错误的第一堂课:


@Service

public 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***

    }

}

第二类:


@Service

public 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 的部分原因......非常感谢!


料青山看我应如是
浏览 339回答 2
2回答

慕娘9325324

SpringContextUtil不应该像您正在做的那样静态访问...因为您将其定义为@Component执行以下操作;@Servicepublic class MdspiImpl extends CThostFtdcMdSpi {&nbsp; &nbsp; @Autowired&nbsp; &nbsp; private SpringContextUtil springContextUtil;&nbsp; &nbsp; public MdspiImpl(CThostFtdcMdApi mdapi) {&nbsp; &nbsp; &nbsp; &nbsp; m_mdapi = mdapi;&nbsp; &nbsp; &nbsp; &nbsp; logger.info("MdspiImpl is creating...");&nbsp; &nbsp; &nbsp; &nbsp; ***mdr = springContextUtil.getBean("marketDataRobot");&nbsp; &nbsp; }}由于SpringContextUtil不是通过 Spring 注入,而是简单地静态访问,因此applicationContext它的内部被忽略并且在您的情况下为 null。同时去掉static修饰符;@Componentpublic class SpringContextUtil implements ApplicationContextAware {&nbsp; &nbsp; private ApplicationContext applicationContext;&nbsp; &nbsp; // include getter/setter for applicationContext as well&nbsp; &nbsp; public <T> T getBean(String name) {&nbsp; &nbsp; &nbsp; &nbsp; return (T) applicationContext.getBean(name);&nbsp; &nbsp; }}编辑来自最新示例项目的麻烦;@Servicepublic class ExampleService {&nbsp; &nbsp; @Autowired&nbsp; &nbsp; private Logger logger;&nbsp; &nbsp; public ExampleService() {&nbsp; &nbsp; &nbsp; &nbsp; this.logger=logger;&nbsp; &nbsp; &nbsp; &nbsp; logger.info("Im working");&nbsp; &nbsp; }}这里Logger将是 null,当ExampleService构造函数被触发时,因为构造函数在注入开始之前被调用,但是如果您通过所述构造函数合并注入,则可以合并此行为,如下所示;@Servicepublic class ExampleService {&nbsp; &nbsp; private final Logger logger;&nbsp; &nbsp; public ExampleService(Logger logger) {&nbsp; &nbsp; &nbsp; &nbsp; this.logger = logger;&nbsp; &nbsp; &nbsp; &nbsp; logger.info("Im working");&nbsp; &nbsp; }}完美运行,没有任何问题......

慕森王

您永远不应该像使用 this 那样以编程方式访问 bean&nbsp;SpringContextUtil,只需注入MarketDataRobot的构造函数MdspiImpl就可以了(因为它被注释为@Service)。首选的方法是使用构造函数注入而不是字段注入,这将使您更容易编写单元测试。@Autowired如果你只有一个构造函数,你也可以去掉。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java