Strip out most of websocket autoconfig

... leaving only the embedded Tomcat enabling feature (registering
the WsSci).

Fixes part of gh-65
pull/450/head
Dave Syer 11 years ago
parent 326c12d1f5
commit 3bc37ddde0

@ -16,122 +16,45 @@
package org.springframework.boot.autoconfigure.websocket;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.Servlet;
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.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.apache.catalina.deploy.ApplicationListener;
import org.apache.catalina.startup.Tomcat;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ClassUtils;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService;
/**
* Auto configuration for websocket server (and sockjs in particular). Users should be
* able to just define beans of type {@link WebSocketHandler}. If
* <code>spring-websocket</code> is detected on the classpath then we add a
* {@link DefaultSockJsService} and an MVC handler mapping to
* <code>/&lt;beanName&gt;/**</code> for all of the <code>WebSocketHandler</code> beans
* that have a bean name beginning with "/".
* Auto configuration for websocket server in embedded Tomcat. If
* <code>spring-websocket</code> is detected on the classpath then we add a listener that
* installs the Tomcat Websocket initializer. In a non-embedded container it should
* already be there.
*
* @author Dave Syer
*/
@Configuration
@ConditionalOnClass({ WebSocketHandler.class })
@ConditionalOnClass(name = "org.apache.tomcat.websocket.server.WsSci", value = {
Servlet.class, Tomcat.class, WebSocketHandler.class })
@AutoConfigureBefore(EmbeddedServletContainerAutoConfiguration.class)
@ConditionalOnMissingBean(WebSocketConfigurer.class)
@EnableWebSocket
public class WebSocketAutoConfiguration {
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 final Map<String, WebSocketHandler> prefixes = new HashMap<String, WebSocketHandler>();
private ListableBeanFactory beanFactory;
private static final ApplicationListener WS_APPLICATION_LISTENER = new ApplicationListener(
"org.apache.tomcat.websocket.server.WsContextListener", false);
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = (ListableBeanFactory) beanFactory;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof WebSocketHandler && beanName.startsWith("/")) {
this.prefixes.put(beanName, (WebSocketHandler) bean);
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory() {
@Override
protected void postProcessContext(Context context) {
context.addApplicationListener(WS_APPLICATION_LISTENER);
}
return bean;
}
private WebSocketHandler getHandler(String prefix) {
return this.prefixes.get(prefix);
}
private String[] getPrefixes() {
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();
}
}
}
@Configuration
@ConditionalOnClass(name = "org.apache.tomcat.websocket.server.WsSci")
protected static class TomcatWebSocketConfiguration {
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory() {
@Override
protected void postProcessContext(Context context) {
context.addServletContainerInitializer(
(ServletContainerInitializer) BeanUtils
.instantiate(ClassUtils.resolveClassName(
"org.apache.tomcat.websocket.server.WsSci",
null)), null);
}
};
return factory;
}
};
return factory;
}
}

@ -23,6 +23,9 @@ import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.handler.PerConnectionWebSocketHandler;
import samples.websocket.client.GreetingService;
@ -34,7 +37,15 @@ import samples.websocket.snake.SnakeWebSocketHandler;
@Configuration
@EnableAutoConfiguration
public class SampleWebSocketsApplication extends SpringBootServletInitializer {
@EnableWebSocket
public class SampleWebSocketsApplication extends SpringBootServletInitializer implements
WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(echoWebSocketHandler(), "/echo").withSockJS();
registry.addHandler(snakeWebSocketHandler(), "/snake").withSockJS();
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
@ -55,12 +66,12 @@ public class SampleWebSocketsApplication extends SpringBootServletInitializer {
return new SimpleGreetingService();
}
@Bean(name = "/echo")
@Bean
public WebSocketHandler echoWebSocketHandler() {
return new EchoWebSocketHandler(echoService());
}
@Bean(name = "/snake")
@Bean
public WebSocketHandler snakeWebSocketHandler() {
return new PerConnectionWebSocketHandler(SnakeWebSocketHandler.class);
}

Loading…
Cancel
Save