34
34
import org .springframework .boot .context .web .NonEmbeddedServletContainerFactory ;
35
35
import org .springframework .context .annotation .Bean ;
36
36
import org .springframework .context .annotation .Configuration ;
37
+ import org .springframework .util .Assert ;
37
38
import org .springframework .util .ClassUtils ;
38
39
import org .springframework .util .ReflectionUtils ;
39
40
import org .springframework .web .socket .WebSocketHandler ;
45
46
* already be there.
46
47
*
47
48
* @author Dave Syer
49
+ * @author Phillip Webb
48
50
*/
49
51
@ Configuration
50
52
@ ConditionalOnClass (name = "org.apache.tomcat.websocket.server.WsSci" , value = {
@@ -56,38 +58,35 @@ public class WebSocketAutoConfiguration {
56
58
57
59
private static final String TOMCAT_8_LISTENER_TYPE = "org.apache.tomcat.util.descriptor.web.ApplicationListener" ;
58
60
61
+ private static final String WS_LISTENER = "org.apache.tomcat.websocket.server.WsContextListener" ;
62
+
59
63
private static Log logger = LogFactory .getLog (WebSocketAutoConfiguration .class );
60
64
61
65
@ Bean
62
66
@ ConditionalOnMissingBean (name = "websocketContainerCustomizer" )
63
67
public EmbeddedServletContainerCustomizer websocketContainerCustomizer () {
64
-
65
- EmbeddedServletContainerCustomizer customizer = new EmbeddedServletContainerCustomizer () {
68
+ return new EmbeddedServletContainerCustomizer () {
66
69
67
70
@ Override
68
71
public void customize (ConfigurableEmbeddedServletContainer container ) {
69
72
if (container instanceof NonEmbeddedServletContainerFactory ) {
70
- logger .info ("NonEmbeddedServletContainerFactory detected. Websockets support should be native so this normally is not a problem." );
73
+ logger .info ("NonEmbeddedServletContainerFactory detected. Websockets "
74
+ + "support should be native so this normally is not a problem." );
71
75
return ;
72
76
}
73
- if (!(container instanceof TomcatEmbeddedServletContainerFactory )) {
74
- throw new IllegalStateException (
75
- "Websockets are currently only supported in Tomcat (found "
76
- + container .getClass () + "). " );
77
- }
78
- ((TomcatEmbeddedServletContainerFactory ) container )
79
- .addContextCustomizers (new TomcatContextCustomizer () {
80
- @ Override
81
- public void customize (Context context ) {
82
- addListener (context , findListenerType ());
83
- }
84
- });
77
+ Assert .state (container instanceof TomcatEmbeddedServletContainerFactory ,
78
+ "Websockets are currently only supported in Tomcat (found "
79
+ + container .getClass () + "). " );
80
+ TomcatEmbeddedServletContainerFactory tomcatContainer = (TomcatEmbeddedServletContainerFactory ) container ;
81
+ tomcatContainer .addContextCustomizers (new TomcatContextCustomizer () {
82
+ @ Override
83
+ public void customize (Context context ) {
84
+ addListener (context , findListenerType ());
85
+ }
86
+ });
85
87
}
86
88
87
89
};
88
-
89
- return customizer ;
90
-
91
90
}
92
91
93
92
private static Class <?> findListenerType () {
@@ -97,23 +96,30 @@ private static Class<?> findListenerType() {
97
96
if (ClassUtils .isPresent (TOMCAT_8_LISTENER_TYPE , null )) {
98
97
return ClassUtils .resolveClassName (TOMCAT_8_LISTENER_TYPE , null );
99
98
}
100
- throw new UnsupportedOperationException (
101
- "Cannot find Tomcat 7 or 8 ApplicationListener class" ) ;
99
+ // With Tomcat 8.0.8 ApplicationListener is not required
100
+ return null ;
102
101
}
103
102
104
103
/**
105
104
* Instead of registering the WsSci directly as a ServletContainerInitializer, we use
106
105
* the ApplicationListener provided by Tomcat. Unfortunately the ApplicationListener
107
- * class moved packages in Tomcat 8 so we have to do it reflectively.
108
- *
106
+ * class moved packages in Tomcat 8 and been deleted in 8.0.8 so we have to use
107
+ * reflection.
109
108
* @param context the current context
110
109
* @param listenerType the type of listener to add
111
110
*/
112
111
private static void addListener (Context context , Class <?> listenerType ) {
113
- Object instance = BeanUtils .instantiateClass (ClassUtils
114
- .getConstructorIfAvailable (listenerType , String .class , boolean .class ),
115
- "org.apache.tomcat.websocket.server.WsContextListener" , false );
116
- ReflectionUtils .invokeMethod (ClassUtils .getMethod (context .getClass (),
117
- "addApplicationListener" , listenerType ), context , instance );
112
+ if (listenerType == null ) {
113
+ ReflectionUtils .invokeMethod (ClassUtils .getMethod (context .getClass (),
114
+ "addApplicationListener" , String .class ), context , WS_LISTENER );
115
+
116
+ }
117
+ else {
118
+ Object instance = BeanUtils .instantiateClass (
119
+ ClassUtils .getConstructorIfAvailable (listenerType , String .class ,
120
+ boolean .class ), WS_LISTENER , false );
121
+ ReflectionUtils .invokeMethod (ClassUtils .getMethod (context .getClass (),
122
+ "addApplicationListener" , listenerType ), context , instance );
123
+ }
118
124
}
119
125
}
0 commit comments