【问题标题】:class is not instantiated in spring-boot (j2EE to spring-boot migration)类未在 spring-boot 中实例化(j2EE 到 spring-boot 迁移)
【发布时间】:2019-11-23 11:55:45
【问题描述】:

我正在将一个 j2EE 应用程序迁移到 spring-boot.. 我在这里面临很多挑战.. 需要你的小帮助,以下是我遵循的步骤

  1. 是否设置了 POM、JAR 和 WAR 打包
  2. 尝试将 Servlet 转换为 RestController
  3. 我已注册为的过滤器
@Configuration

public class FilterConfigService {

    @Bean
    public FilterRegistrationBean mdcFilter() {
        FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
        filterRegBean.setFilter(new MDCFilter());
        filterRegBean.addUrlPatterns("/v2/*");
        filterRegBean.setOrder(1);
        return filterRegBean;
    }

    @Bean
    public FilterRegistrationBean apiOriginFilter() {
        FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
        filterRegBean.setFilter(new ApiOriginFilter());
        filterRegBean.addUrlPatterns("/v2/*");
        filterRegBean.setOrder(2);
        return filterRegBean;
    }
}
  1. 有一个单例类,用于通过 servlet 的 Init() 实例化一些必要的东西,因为所有 bean 默认情况下在范围内都是单例的,所以我删除了这些单例类,并按照以下方式进行实例化(不知道这是否是好的做法)
    @Configuration
    public class PdfExtractServerConfig implements ApplicationListener<ContextRefreshedEvent> {

        @Autowired
        PdfExtractServer pdfExtractServer;

        private static Logger log = Logger.getLogger(PdfExtractServerConfig.class);

        @Override
        public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
            try {
                pdfExtractServer.instance(); // this was called in init of servlet
                System.out.println("instance created ..");
            }
            catch (Throwable e) {
                log.error("Unable to start PdfExtractServer", e);
                throw e;
            }
            //Start monitoring for system health
            ResourceCheck.startMonitoring();
            SplunkMgr.instance().addSplunkMessage("BackPressure", LogLevel.INFO);
        }
    }

单吨类如下..

以前是这样的

    public static PdfExtractServer instance() {
            if (instance == null) {
                synchronized (startupLock) {
                    if (instance == null) {
                        instance = new PdfExtractServer();
                        instance.start("PES");
                    }
                }
            }
            return instance;
        }

现在我把它做成了

    public static PdfExtractServer instance() {
    //      instance = new PdfExtractServer();
            instance.start("PES");
            return instance;
        }

这是我的测试控制器

    @RestController
    //@RequestMapping("/")
    public class Test {
        @RequestMapping("/test" )
        public String test(){
            return "Tested OK";
        }
    }

我不明白我在哪里做错了......当我尝试运行此渲染时

无法在以下位置启动 PdfExtractServer java.lang.NullPointerException com.it.pes.pdfextract.service.PdfExtractServer.instance(PdfExtractServer.java:78) 在 com.it.pes.pdfextract.config.PdfExtractServerConfig.onApplicationEvent(PdfExtractServerConfig.java:24) 在 com.it.pes.pdfextract.config.PdfExtractServerConfig.onApplicationEvent(PdfExtractServerConfig.java:13) 在 com.it.pes.pdfextract.config.PdfExtractServerConfig$$EnhancerBySpringCGLIB$$e703305a.onApplicationEvent() 在 org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) 在 org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) 在 org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) 在 org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:393) 在 org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347) 在 org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:883) 在 org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:144) 在 org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) 在 org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) 在 org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) 在 org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:303) 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)

观察:我尝试通过 glassfish jersey 注册我的过滤器,但在某些 jars 内部,使用了 1.1.1 的 javax.ws.rs-api,因此存在冲突并且我的应用程序未启动,因此注册了过滤器以上述不同的方式。

您的帮助对我来说将是一个非常好的举措..提前谢谢..

这里附上包结构。

【问题讨论】:

    标签: java spring-boot


    【解决方案1】:

    当您要求容器将其提供给您时,您的 PdfExtractServer 对象为空。该类中的实例对象为空。

    当调用类的构造函数(在您的情况下为 PdfExtractServer)时,@Autowired 实例变量尚不包含它们的值。由于您依赖它来执行特定的逻辑/或实例创建,我建议使用 @PostConstruct 注释。此注释允许在构造实例之后以及在注入所有 @Autowired 实例之后执行特定方法。更多关于这个here

    下面的链接应该能够帮助您理解并可能修复空指针问题。

    The usual Autowiring not working issues and it's intended fixes

    【讨论】:

      【解决方案2】:

      我同意上述观点。我认为你把事情复杂化了。

      我相信这就是你所需要的。 @Configuration 带注释的类将在服务器启动时运行。 @Bean 带注释的方法将被执行一次,并默认创建一个可供@Autowire 使用的单例bean

      首先运行所有的配置类,然后它会扫描所有的包并满足服务、组件、存储库、控制器。

      @Configuration
      public class PdfExtractServerConfig {
      
          @Bean
          public PdfExtractServer pdfExtractServer() {
             final PdfExtractServer pdfExtractServer = new PdfExtractServer();
             pdfExtractServer.start("PES");
             return pdfExtractServer
          }
      }
      

      所以当你想在任何其他spring managed bean 中使用你的 singelton 时

      // Spring will by default scan after this annotation recursively through
      // packages on classes and create by default a singleton. It will also 
      // search after all bean dependencies that need to be injected. in this case 
      // PdfExtracServer and then inject it.
      @Component 
      public class Foo {
      
          @Autowire
          private PdfExtractServer pdfExtractServer;
      
          //different methods here
      
      }
      

      【讨论】:

      • M 试试这个方法.. 看看是否有效.. 非常感谢 yiu 的宝贵时间
      • 我尝试了同样的方法,没有异常但是当我执行 url 时控制器没有被调用。 Whitelabel 错误页面 此应用程序没有针对 /error 的显式映射,因此您将其视为后备。 IST 2019 年 7 月 15 日星期一 12:50:42 出现意外错误(类型=未找到,状态=404)。 /测试
      • 怎么调用,什么地址
      • localhost:8080/test是测试的地址,控制器是否被调用...
      • 你的数据包结构是什么样的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-07
      • 2019-05-24
      • 1970-01-01
      • 1970-01-01
      • 2020-12-07
      • 2019-01-07
      • 2020-11-18
      相关资源
      最近更新 更多