Spring引导@Autowired不能在服务器启动的servlet中工作

时间:2017-06-24 09:23:04

标签: spring spring-boot

我的servlet在启动属性上的加载为'1',在这个servlet中我必须在应用服务器启动期间缓存数据库条目。 在这个servlet中,我调用CacheService来检索db对象,它使用@Autowired annoatation进行注释,在应用程序启动期间,CacheService对象为null。我已使用@Service注释注释了CacheService。 @Autowired注释不起作用。

@Service
public class CacheService {
    @Autowired
    private IJobsService jobsServiceImpl; 
    public List<Jobs> getALLJobs(){
        List<Jobs> alljobs = jobsServiceImpl.findAllJobs();
        return alljobs;
    }

}


public class StartupServlet extends HttpServlet {

       @Autowired
       private CacheService cacheService; -- object is null not autowired
}

Below is the main class


@EnableCaching
@EnableJpaRepositories(basePackages = {"com.example.demo.repository"})
@EntityScan(basePackages = {"com.example.demo.entity"})
@SpringBootApplication
@ComponentScan(basePackages={"com.example.demo"})
@EnableAutoConfiguration(exclude = {
        org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class,
        org.springframework.boot.actuate.autoconfigure.ManagementWebSecurityAutoConfiguration.class})

public class DemoApplication  extends SpringBootServletInitializer implements WebApplicationInitializer{

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Override
       protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
          return builder.sources(DemoApplication.class);
       }

     @Bean
        ServletRegistrationBean myServletRegistration () {
            ServletRegistrationBean srb = new ServletRegistrationBean();
            srb.setServlet(new StartupServlet());
            srb.setUrlMappings(Arrays.asList("/path2/*"));
            srb.setLoadOnStartup(1);
            return srb;
        }
}

有些人可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

您正在使用new创建servlet,因此您需要提供其依赖项。由于您使用的是注释和Java代码配置的混合,您可以像这样完成它:

public class StartupServlet extends HttpServlet {

  private CacheService cacheService;

  public StartupServlet(CacheService cacheService) {
    this.cacheService = cacheService;
  }

  // ... rest of servlet
}

主要课程:

   @Bean
   ServletRegistrationBean myServletRegistration (CacheService cacheService) { // <<<--- cacheService will be provided here by Spring because it's annotated
        ServletRegistrationBean srb = new ServletRegistrationBean();
        srb.setServlet(new StartupServlet(cacheService));
        srb.setUrlMappings(Arrays.asList("/path2/*"));
        srb.setLoadOnStartup(1);
        return srb;
    }

答案 1 :(得分:1)

你应该为此做一些额外的工作。您必须与beanFactory交谈 - 就像spring组件一样,并要求它使该特定实例成为符合条件的bean。 AutowireCapableBeanFactory应该做到这一点。

以下是基于您提供的代码的简单示例

@SpringBootApplication
public class So44734879Application {

    public static void main(String[] args) {
        SpringApplication.run(So44734879Application.class, args);
    }

    @Autowired
    AutowireCapableBeanFactory beanFactory;

    @Bean
    ServletRegistrationBean myServletRegistration() {
        ServletRegistrationBean srb = new ServletRegistrationBean();
        final StartupServlet servlet = new StartupServlet();
        beanFactory.autowireBean(servlet);  // <--- The most important part
        srb.setServlet(servlet);
        srb.setUrlMappings(Arrays.asList("/path2/*"));
        srb.setLoadOnStartup(1);
        return srb;
    }

    @Bean
    MyService myService() {
        return new MyService();
    }

    public static class MyService {
        String time() {
            return "Time: " + System.currentTimeMillis();
        }
    }

    public static class StartupServlet extends HttpServlet {
        @Autowired
        MyService myService;

        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            final PrintWriter writer = resp.getWriter();
            writer.write(myService.time());
            writer.close();
        }
    }
}

=&GT;

$ curl -XGET localhost:8080/path2
Time: 1498299772141%