Updated WebSocketAutoConfiguration to use @EnableWebSocket

pull/50/head
Dave Syer 11 years ago committed by Phillip Webb
parent 5fa0166dea
commit c4223d645d

@ -16,15 +16,19 @@
package org.springframework.boot.autoconfigure.websocket; package org.springframework.boot.autoconfigure.websocket;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletContainerInitializer; import javax.servlet.ServletContainerInitializer;
import org.apache.catalina.Context; import org.apache.catalina.Context;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@ -33,13 +37,11 @@ import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoCo
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.sockjs.SockJsHttpRequestHandler; import org.springframework.web.socket.server.config.EnableWebSocket;
import org.springframework.web.socket.sockjs.SockJsService; import org.springframework.web.socket.server.config.WebSocketConfigurer;
import org.springframework.web.socket.sockjs.support.AbstractSockJsService; import org.springframework.web.socket.server.config.WebSocketHandlerRegistry;
import org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService; import org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService;
/** /**
@ -54,12 +56,27 @@ import org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsServ
@Configuration @Configuration
@ConditionalOnClass({ WebSocketHandler.class }) @ConditionalOnClass({ WebSocketHandler.class })
@AutoConfigureBefore(EmbeddedServletContainerAutoConfiguration.class) @AutoConfigureBefore(EmbeddedServletContainerAutoConfiguration.class)
@ConditionalOnMissingBean(WebSocketConfigurer.class)
@EnableWebSocket
public class WebSocketAutoConfiguration { public class WebSocketAutoConfiguration {
private static class WebSocketEndpointPostProcessor implements BeanPostProcessor { private static Log logger = LogFactory.getLog(WebSocketAutoConfiguration.class);
// Nested class to avoid having to load WebSocketConfigurer before conditions are
// evaluated
@Configuration
protected static class WebSocketRegistrationConfiguration implements
BeanPostProcessor, BeanFactoryAware, WebSocketConfigurer {
private Map<String, WebSocketHandler> prefixes = new HashMap<String, WebSocketHandler>(); private Map<String, WebSocketHandler> prefixes = new HashMap<String, WebSocketHandler>();
private ListableBeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = (ListableBeanFactory) beanFactory;
}
@Override @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException { throws BeansException {
@ -75,58 +92,24 @@ public class WebSocketAutoConfiguration {
return bean; return bean;
} }
public WebSocketHandler getHandler(String prefix) { private WebSocketHandler getHandler(String prefix) {
return this.prefixes.get(prefix); return this.prefixes.get(prefix);
} }
public String[] getPrefixes() { private String[] getPrefixes() {
return this.prefixes.keySet().toArray(new String[this.prefixes.size()]); return this.prefixes.keySet().toArray(new String[this.prefixes.size()]);
} }
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// Force initialization of WebSocketHandler beans
this.beanFactory.getBeansOfType(WebSocketHandler.class);
for (String prefix : getPrefixes()) {
logger.info("Adding SockJS handler: " + prefix);
registry.addHandler(getHandler(prefix), prefix).withSockJS();
} }
@Bean
public WebSocketEndpointPostProcessor webSocketEndpointPostProcessor() {
return new WebSocketEndpointPostProcessor();
}
@Bean
@ConditionalOnMissingBean(SockJsService.class)
public DefaultSockJsService sockJsService() {
DefaultSockJsService service = new DefaultSockJsService(sockJsTaskScheduler());
service.setSockJsClientLibraryUrl("https://cdn.sockjs.org/sockjs-0.3.4.min.js");
service.setWebSocketsEnabled(true);
return service;
}
@Bean
public SimpleUrlHandlerMapping handlerMapping(SockJsService sockJsService,
Collection<WebSocketHandler> handlers) {
WebSocketEndpointPostProcessor processor = webSocketEndpointPostProcessor();
Map<String, Object> urlMap = new HashMap<String, Object>();
for (String prefix : webSocketEndpointPostProcessor().getPrefixes()) {
urlMap.put(prefix + "/**", new SockJsHttpRequestHandler(sockJsService,
processor.getHandler(prefix)));
}
if (sockJsService instanceof AbstractSockJsService) {
((AbstractSockJsService) sockJsService).setValidSockJsPrefixes(processor
.getPrefixes());
}
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
handlerMapping.setOrder(-1);
handlerMapping.setUrlMap(urlMap);
return handlerMapping;
} }
@Bean
@ConditionalOnMissingBean(name = "sockJsTaskScheduler")
public ThreadPoolTaskScheduler sockJsTaskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setThreadNamePrefix("SockJS-");
return taskScheduler;
} }
@Configuration @Configuration

Loading…
Cancel
Save