Skip to content

Commit c7fbf78

Browse files
committed
Provide @WebSocketScope annotation and public SCOPE_WEBSOCKET constant
Closes gh-35235
1 parent 7316aab commit c7fbf78

File tree

3 files changed

+74
-6
lines changed

3 files changed

+74
-6
lines changed

framework-docs/modules/ROOT/pages/web/websocket/stomp/scope.adoc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
[[websocket-stomp-websocket-scope]]
22
= WebSocket Scope
33

4-
Each WebSocket session has a map of attributes. The map is attached as a header to
5-
inbound client messages and may be accessed from a controller method, as the following example shows:
4+
Each WebSocket session has a map of attributes. The map is attached as a header to inbound
5+
client messages and may be accessed from a controller method, as the following example shows:
66

77
[source,java,indent=0,subs="verbatim,quotes"]
88
----
@@ -20,13 +20,13 @@ public class MyController {
2020
You can declare a Spring-managed bean in the `websocket` scope.
2121
You can inject WebSocket-scoped beans into controllers and any channel interceptors
2222
registered on the `clientInboundChannel`. Those are typically singletons and live
23-
longer than any individual WebSocket session. Therefore, you need to use a
24-
scope proxy mode for WebSocket-scoped beans, as the following example shows:
23+
longer than any individual WebSocket session. Therefore, you need to use
24+
WebSocket-scoped beans in proxy mode, conveniently defined with `@WebSocketScope`:
2525

2626
[source,java,indent=0,subs="verbatim,quotes"]
2727
----
2828
@Component
29-
@Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
29+
@WebSocketScope
3030
public class MyBean {
3131
3232
@PostConstruct

spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebSocketMessageBrokerConfigurationSupport.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,18 @@
5454
* @author Rossen Stoyanchev
5555
* @author Artem Bilan
5656
* @author Sebastien Deleuze
57+
* @author Juergen Hoeller
5758
* @since 4.0
5859
*/
5960
public abstract class WebSocketMessageBrokerConfigurationSupport extends AbstractMessageBrokerConfiguration {
6061

62+
/**
63+
* Scope identifier for WebSocket scope: "websocket".
64+
* @since 7.0
65+
*/
66+
public static final String SCOPE_WEBSOCKET = "websocket";
67+
68+
6169
private @Nullable WebSocketTransportRegistration transportRegistration;
6270

6371

@@ -137,7 +145,7 @@ protected void configureWebSocketTransport(WebSocketTransportRegistration regist
137145
@Bean
138146
public static CustomScopeConfigurer webSocketScopeConfigurer() {
139147
CustomScopeConfigurer configurer = new CustomScopeConfigurer();
140-
configurer.addScope("websocket", new SimpSessionScope());
148+
configurer.addScope(SCOPE_WEBSOCKET, new SimpSessionScope());
141149
return configurer;
142150
}
143151

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2002-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.web.socket.config.annotation;
18+
19+
import java.lang.annotation.Documented;
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.RetentionPolicy;
23+
import java.lang.annotation.Target;
24+
25+
import org.springframework.context.annotation.Scope;
26+
import org.springframework.context.annotation.ScopedProxyMode;
27+
import org.springframework.core.annotation.AliasFor;
28+
29+
/**
30+
* {@code @WebSocketScope} is a specialization of {@link Scope @Scope} for a
31+
* component whose lifecycle is bound to the current WebSocket lifecycle.
32+
*
33+
* <p>Specifically, {@code @WebSocketScope} is a <em>composed annotation</em> that
34+
* acts as a shortcut for {@code @Scope("websocket")} with the default
35+
* {@link #proxyMode} set to {@link ScopedProxyMode#TARGET_CLASS TARGET_CLASS}.
36+
*
37+
* <p>{@code @WebSocketScope} may be used as a meta-annotation to create custom
38+
* composed annotations.
39+
*
40+
* @author Juergen Hoeller
41+
* @since 7.0
42+
* @see org.springframework.context.annotation.Scope
43+
* @see WebSocketMessageBrokerConfigurationSupport#SCOPE_WEBSOCKET
44+
* @see org.springframework.stereotype.Component
45+
* @see org.springframework.context.annotation.Bean
46+
*/
47+
@Target({ElementType.TYPE, ElementType.METHOD})
48+
@Retention(RetentionPolicy.RUNTIME)
49+
@Documented
50+
@Scope(WebSocketMessageBrokerConfigurationSupport.SCOPE_WEBSOCKET)
51+
public @interface WebSocketScope {
52+
53+
/**
54+
* Alias for {@link Scope#proxyMode}.
55+
* <p>Defaults to {@link ScopedProxyMode#TARGET_CLASS}.
56+
*/
57+
@AliasFor(annotation = Scope.class)
58+
ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
59+
60+
}

0 commit comments

Comments
 (0)