Skip to content

Commit a455217

Browse files
committed
Modify how SpringConfigurator finds Endpoint singleton
First try the endpoint type name converted to property Then try @component value Issue: SPR-10605
1 parent c211c98 commit a455217

2 files changed

Lines changed: 56 additions & 26 deletions

File tree

spring-websocket/src/main/java/org/springframework/web/socket/server/endpoint/SpringConfigurator.java

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@
1616

1717
package org.springframework.web.socket.server.endpoint;
1818

19-
import java.util.Map;
20-
2119
import javax.websocket.server.ServerEndpoint;
2220
import javax.websocket.server.ServerEndpointConfig.Configurator;
2321

2422
import org.apache.commons.logging.Log;
2523
import org.apache.commons.logging.LogFactory;
24+
import org.springframework.core.annotation.AnnotationUtils;
25+
import org.springframework.stereotype.Component;
26+
import org.springframework.util.ClassUtils;
2627
import org.springframework.web.context.ContextLoader;
2728
import org.springframework.web.context.WebApplicationContext;
2829

@@ -58,25 +59,28 @@ public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationExc
5859
throw new IllegalStateException(message);
5960
}
6061

61-
Map<String, T> beans = wac.getBeansOfType(endpointClass);
62-
if (beans.isEmpty()) {
62+
String beanName = ClassUtils.getShortNameAsProperty(endpointClass);
63+
if (wac.containsBean(beanName)) {
64+
T endpoint = wac.getBean(beanName, endpointClass);
6365
if (logger.isTraceEnabled()) {
64-
logger.trace("Creating new @ServerEndpoint instance of type " + endpointClass);
66+
logger.trace("Using @ServerEndpoint singleton " + endpoint);
6567
}
66-
return wac.getAutowireCapableBeanFactory().createBean(endpointClass);
68+
return endpoint;
6769
}
68-
else if (beans.size() == 1) {
70+
71+
Component annot = AnnotationUtils.findAnnotation(endpointClass, Component.class);
72+
if ((annot != null) && wac.containsBean(annot.value())) {
73+
T endpoint = wac.getBean(annot.value(), endpointClass);
6974
if (logger.isTraceEnabled()) {
70-
logger.trace("Using @ServerEndpoint singleton " + beans.keySet().iterator().next());
75+
logger.trace("Using @ServerEndpoint singleton " + endpoint);
7176
}
72-
return beans.values().iterator().next();
77+
return endpoint;
7378
}
74-
else {
75-
// Should not happen ..
76-
String message = "Found more than one matching @ServerEndpoint beans of type " + endpointClass;
77-
logger.error(message);
78-
throw new IllegalStateException(message);
79+
80+
if (logger.isTraceEnabled()) {
81+
logger.trace("Creating new @ServerEndpoint instance of type " + endpointClass);
7982
}
83+
return wac.getAutowireCapableBeanFactory().createBean(endpointClass);
8084
}
8185

8286
}

spring-websocket/src/test/java/org/springframework/web/socket/server/endpoint/SpringConfiguratorTests.java

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@
2525
import org.junit.Test;
2626
import org.springframework.beans.factory.annotation.Autowired;
2727
import org.springframework.context.annotation.Bean;
28+
import org.springframework.context.annotation.ComponentScan;
2829
import org.springframework.context.annotation.Configuration;
2930
import org.springframework.mock.web.test.MockServletContext;
31+
import org.springframework.stereotype.Component;
3032
import org.springframework.web.context.ContextLoader;
3133
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
3234

@@ -40,6 +42,8 @@ public class SpringConfiguratorTests {
4042

4143
private AnnotationConfigWebApplicationContext webAppContext;
4244

45+
private SpringConfigurator configurator;
46+
4347

4448
@Before
4549
public void setup() {
@@ -50,6 +54,8 @@ public void setup() {
5054

5155
this.contextLoader = new ContextLoader(this.webAppContext);
5256
this.contextLoader.initWebApplicationContext(this.servletContext);
57+
58+
this.configurator = new SpringConfigurator();
5359
}
5460

5561
@After
@@ -59,29 +65,33 @@ public void destroy() {
5965

6066

6167
@Test
62-
public void getEndpointInstanceCreateBean() throws Exception {
63-
64-
PerConnectionEchoEndpoint endpoint = new SpringConfigurator().getEndpointInstance(PerConnectionEchoEndpoint.class);
65-
68+
public void getEndpointInstancePerConnection() throws Exception {
69+
PerConnectionEchoEndpoint endpoint = this.configurator.getEndpointInstance(PerConnectionEchoEndpoint.class);
6670
assertNotNull(endpoint);
6771
}
6872

6973
@Test
70-
public void getEndpointInstanceUseBean() throws Exception {
71-
72-
EchoEndpointBean expected = this.webAppContext.getBean(EchoEndpointBean.class);
73-
EchoEndpointBean actual = new SpringConfigurator().getEndpointInstance(EchoEndpointBean.class);
74+
public void getEndpointInstanceSingletonByType() throws Exception {
75+
EchoEndpoint expected = this.webAppContext.getBean(EchoEndpoint.class);
76+
EchoEndpoint actual = this.configurator.getEndpointInstance(EchoEndpoint.class);
77+
assertSame(expected, actual);
78+
}
7479

80+
@Test
81+
public void getEndpointInstanceSingletonByComponentName() throws Exception {
82+
AlternativeEchoEndpoint expected = this.webAppContext.getBean(AlternativeEchoEndpoint.class);
83+
AlternativeEchoEndpoint actual = this.configurator.getEndpointInstance(AlternativeEchoEndpoint.class);
7584
assertSame(expected, actual);
7685
}
7786

7887

7988
@Configuration
89+
@ComponentScan(basePackageClasses=SpringConfiguratorTests.class)
8090
static class Config {
8191

8292
@Bean
83-
public EchoEndpointBean echoEndpointBean() {
84-
return new EchoEndpointBean(echoService());
93+
public EchoEndpoint echoEndpoint() {
94+
return new EchoEndpoint(echoService());
8595
}
8696

8797
@Bean
@@ -90,13 +100,29 @@ public EchoService echoService() {
90100
}
91101
}
92102

93-
private static class EchoEndpointBean extends Endpoint {
103+
private static class EchoEndpoint extends Endpoint {
104+
105+
@SuppressWarnings("unused")
106+
private final EchoService service;
107+
108+
@Autowired
109+
public EchoEndpoint(EchoService service) {
110+
this.service = service;
111+
}
112+
113+
@Override
114+
public void onOpen(Session session, EndpointConfig config) {
115+
}
116+
}
117+
118+
@Component("echoEndpoint")
119+
private static class AlternativeEchoEndpoint extends Endpoint {
94120

95121
@SuppressWarnings("unused")
96122
private final EchoService service;
97123

98124
@Autowired
99-
public EchoEndpointBean(EchoService service) {
125+
public AlternativeEchoEndpoint(EchoService service) {
100126
this.service = service;
101127
}
102128

0 commit comments

Comments
 (0)