我正在尝试制作Spring Boot应用程序的原型。我来自Guice JAX-RS应用程序,因此与Spring MVC相比,我更喜欢标准JAX- RS批注。我已经将Jetty装好并服务:
@Configuration @Import({ResteasyBootstrap.class, SpringBeanProcessorServletAware.class, HttpServletDispatcher.class}) public class EmbeddedJetty { @Bean @Singleton public EmbeddedServletContainerFactory servletContainer() { JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory(); factory.setPort(9000); factory.setSessionTimeout(10, TimeUnit.MINUTES); return factory; } }
但是,我只是不知道如何正确连接RESTEasy。通过上面的操作SpringBeanProcessorServletAware,看起来似乎ServletContext没有被注入,ServletContextAware直到最终被使用:
SpringBeanProcessorServletAware
ServletContext
ServletContextAware
java.lang.NullPointerException: null at org.jboss.resteasy.plugins.spring.SpringBeanProcessorServletAware.getRegistry(SpringBeanProcessorServletAware.java:30) at org.jboss.resteasy.plugins.spring.SpringBeanProcessor.postProcessBeanFactory(SpringBeanProcessor.java:247) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:284) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:174) at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:680) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:522) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766)
我也尝试过使用SpringContextLoaderListener,但这似乎与spring-boot AnnotationConfigEmbeddedWebApplicationContext类冲突。
SpringContextLoaderListener
AnnotationConfigEmbeddedWebApplicationContext
我正在使用spring-boot 1.3.3和spring-framework 4.3.0.rc1
另一个答案不会像Spring bean那样拥有您的资源,这种自动配置将正确地集成它们:
配置类:
@Configuration @ConditionalOnWebApplication public class RestEasyAutoConfigurer { private Environment environment; @Bean(name = "resteasyDispatcher") public ServletRegistrationBean resteasyServletRegistration() { ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HttpServletDispatcher(), getPrefix() + "/*"); registrationBean.setInitParameters(ImmutableMap.of("resteasy.servlet.mapping.prefix", "/rs/")); // set prefix here registrationBean.setLoadOnStartup(1); return registrationBean; } @Bean(destroyMethod = "cleanup") public static RestEasySpringInitializer restEasySpringInitializer() { return new RestEasySpringInitializer(); } @Bean // use Spring Boot configured Jackson public CustomResteasyJackson2Provider jackson2Provider(ObjectMapper mapper) { return new CustomResteasyJackson2Provider(mapper); } public static class RestEasySpringInitializer implements ServletContextInitializer, ApplicationContextAware, BeanFactoryPostProcessor { private ResteasyDeployment deployment; private ConfigurableApplicationContext applicationContext; private ConfigurableListableBeanFactory beanFactory; public void cleanup() { deployment.stop(); } @Override public void onStartup(ServletContext servletContext) throws ServletException { ListenerBootstrap config = new ListenerBootstrap(servletContext); deployment = config.createDeployment(); deployment.start(); servletContext.setAttribute(ResteasyProviderFactory.class.getName(), deployment.getProviderFactory()); servletContext.setAttribute(Dispatcher.class.getName(), deployment.getDispatcher()); servletContext.setAttribute(Registry.class.getName(), deployment.getRegistry()); SpringBeanProcessor processor = new SpringBeanProcessor(deployment.getDispatcher(), deployment.getRegistry(), deployment.getProviderFactory()); processor.postProcessBeanFactory(beanFactory); applicationContext.addApplicationListener(processor); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = (ConfigurableApplicationContext) applicationContext; } } }
和Jackson提供商:
@Provider @Consumes({"application/*+json", "text/json"}) @Produces({"application/*+json", "text/json"}) public class CustomResteasyJackson2Provider extends ResteasyJackson2Provider { private ObjectMapper mapper; public CustomResteasyJackson2Provider(ObjectMapper mapper) { this.mapper = mapper; } @Override public ObjectMapper locateMapper(Class<?> type, MediaType mediaType) { return Optional.ofNullable(_mapperConfig.getConfiguredMapper()).orElse(mapper); } }
注意:这是Spring Boot 1.3.3 / RESTEasy 3.0.16的有效配置