Skip to content

Commit bc0317a

Browse files
committed
Merge branch '5.1.x'
2 parents d61c3d4 + 9eb7f7e commit bc0317a

File tree

14 files changed

+158
-72
lines changed

14 files changed

+158
-72
lines changed

spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJProxyUtils.java

+12-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,27 +27,31 @@
2727
*
2828
* @author Rod Johnson
2929
* @author Ramnivas Laddad
30+
* @author Juergen Hoeller
3031
* @since 2.0
3132
*/
3233
public abstract class AspectJProxyUtils {
3334

3435
/**
35-
* Add special advisors if necessary to work with a proxy chain that contains AspectJ advisors.
36-
* This will expose the current Spring AOP invocation (necessary for some AspectJ pointcut matching)
37-
* and make available the current AspectJ JoinPoint. The call will have no effect if there are no
38-
* AspectJ advisors in the advisor chain.
36+
* Add special advisors if necessary to work with a proxy chain that contains AspectJ advisors:
37+
* concretely, {@link ExposeInvocationInterceptor} at the beginning of the list.
38+
* <p>This will expose the current Spring AOP invocation (necessary for some AspectJ pointcut
39+
* matching) and make available the current AspectJ JoinPoint. The call will have no effect
40+
* if there are no AspectJ advisors in the advisor chain.
3941
* @param advisors the advisors available
40-
* @return {@code true} if any special {@link Advisor Advisors} were added, otherwise {@code false}
42+
* @return {@code true} if an {@link ExposeInvocationInterceptor} was added to the list,
43+
* otherwise {@code false}
4144
*/
4245
public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
4346
// Don't add advisors to an empty list; may indicate that proxying is just not required
4447
if (!advisors.isEmpty()) {
4548
boolean foundAspectJAdvice = false;
4649
for (Advisor advisor : advisors) {
47-
// Be careful not to get the Advice without a guard, as
48-
// this might eagerly instantiate a non-singleton AspectJ aspect
50+
// Be careful not to get the Advice without a guard, as this might eagerly
51+
// instantiate a non-singleton AspectJ aspect...
4952
if (isAspectJAdvice(advisor)) {
5053
foundAspectJAdvice = true;
54+
break;
5155
}
5256
}
5357
if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ private Collection<ApplicationListener<?>> retrieveApplicationListeners(
269269
* type before trying to instantiate it.
270270
* <p>If this method returns {@code true} for a given listener as a first pass,
271271
* the listener instance will get retrieved and fully evaluated through a
272-
* {@link #supportsEvent(ApplicationListener, ResolvableType, Class)} call afterwards.
272+
* {@link #supportsEvent(ApplicationListener, ResolvableType, Class)} call afterwards.
273273
* @param listenerType the listener's type as determined by the BeanFactory
274274
* @param eventType the event type to check
275275
* @return whether the given listener should be included in the candidates

spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java

+10-8
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,9 @@ public void processEvent(ApplicationEvent event) {
188188

189189
/**
190190
* Resolve the method arguments to use for the specified {@link ApplicationEvent}.
191-
* <p>These arguments will be used to invoke the method handled by this instance. Can
192-
* return {@code null} to indicate that no suitable arguments could be resolved and
193-
* therefore the method should not be invoked at all for the specified event.
191+
* <p>These arguments will be used to invoke the method handled by this instance.
192+
* Can return {@code null} to indicate that no suitable arguments could be resolved
193+
* and therefore the method should not be invoked at all for the specified event.
194194
*/
195195
@Nullable
196196
protected Object[] resolveArguments(ApplicationEvent event) {
@@ -201,13 +201,15 @@ protected Object[] resolveArguments(ApplicationEvent event) {
201201
if (this.method.getParameterCount() == 0) {
202202
return new Object[0];
203203
}
204-
if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.toClass()) &&
204+
Class<?> declaredEventClass = declaredEventType.toClass();
205+
if (!ApplicationEvent.class.isAssignableFrom(declaredEventClass) &&
205206
event instanceof PayloadApplicationEvent) {
206-
return new Object[] {((PayloadApplicationEvent) event).getPayload()};
207-
}
208-
else {
209-
return new Object[] {event};
207+
Object payload = ((PayloadApplicationEvent) event).getPayload();
208+
if (declaredEventClass.isInstance(payload)) {
209+
return new Object[] {payload};
210+
}
210211
}
212+
return new Object[] {event};
211213
}
212214

213215
protected void handleResult(Object result) {

spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java

+6-7
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,13 @@
3636
* or through a {@link org.springframework.beans.factory.config.CustomScopeConfigurer} bean.
3737
*
3838
* <p>{@code SimpleThreadScope} <em>does not clean up any objects</em> associated with it.
39-
* As such, it is typically preferable to use
40-
* {@link org.springframework.web.context.request.RequestScope RequestScope}
41-
* in web environments.
39+
* It is therefore typically preferable to use a request-bound scope implementation such
40+
* as {@code org.springframework.web.context.request.RequestScope} in web environments,
41+
* implementing the full lifecycle for scoped attributes (including reliable destruction).
4242
*
43-
* <p>For an implementation of a thread-based {@code Scope} with support for
44-
* destruction callbacks, refer to the
45-
* <a href="http://www.springbyexample.org/examples/custom-thread-scope-module.html">
46-
* Spring by Example Custom Thread Scope Module</a>.
43+
* <p>For an implementation of a thread-based {@code Scope} with support for destruction
44+
* callbacks, refer to
45+
* <a href="http://www.springbyexample.org/examples/custom-thread-scope-module.html">Spring by Example</a>.
4746
*
4847
* <p>Thanks to Eugene Kuleshov for submitting the original prototype for a thread scope!
4948
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2002-2019 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+
* http://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.context.event;
18+
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
22+
import org.junit.Test;
23+
24+
import org.springframework.context.ApplicationContext;
25+
import org.springframework.context.PayloadApplicationEvent;
26+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
27+
import org.springframework.stereotype.Component;
28+
29+
import static org.junit.Assert.*;
30+
31+
/**
32+
* @author Juergen Hoeller
33+
*/
34+
public class PayloadApplicationEventTests {
35+
36+
@Test
37+
public void testEventClassWithInterface() {
38+
ApplicationContext ac = new AnnotationConfigApplicationContext(Listener.class);
39+
MyEventClass event = new MyEventClass<>(this, "xyz");
40+
ac.publishEvent(event);
41+
assertTrue(ac.getBean(Listener.class).events.contains(event));
42+
}
43+
44+
45+
public interface Auditable {
46+
}
47+
48+
49+
public static class MyEventClass<GT> extends PayloadApplicationEvent<GT> implements Auditable {
50+
51+
public MyEventClass(Object source, GT payload) {
52+
super(source, payload);
53+
}
54+
55+
public String toString() {
56+
return "Payload: " + getPayload();
57+
}
58+
}
59+
60+
61+
@Component
62+
public static class Listener {
63+
64+
public final List<Auditable> events = new ArrayList<>();
65+
66+
@EventListener
67+
public void onEvent(Auditable event) {
68+
events.add(event);
69+
}
70+
}
71+
72+
}

spring-core/src/main/java/org/springframework/util/ClassUtils.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@
4343
import org.springframework.lang.Nullable;
4444

4545
/**
46-
* Miscellaneous class utility methods.
46+
* Miscellaneous {@code java.lang.Class} utility methods.
4747
* Mainly for internal use within the framework.
4848
*
4949
* @author Juergen Hoeller

spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java

+25-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -74,7 +74,8 @@ public class MappingJackson2MessageConverter implements SmartMessageConverter, B
7474

7575
private MessageType targetType = MessageType.BYTES;
7676

77-
private String encoding = DEFAULT_ENCODING;
77+
@Nullable
78+
private String encoding;
7879

7980
@Nullable
8081
private String encodingPropertyName;
@@ -293,13 +294,21 @@ protected BytesMessage mapToBytesMessage(Object object, Session session, ObjectW
293294
throws JMSException, IOException {
294295

295296
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
296-
OutputStreamWriter writer = new OutputStreamWriter(bos, this.encoding);
297-
objectWriter.writeValue(writer, object);
297+
if (this.encoding != null) {
298+
OutputStreamWriter writer = new OutputStreamWriter(bos, this.encoding);
299+
objectWriter.writeValue(writer, object);
300+
}
301+
else {
302+
// Jackson usually defaults to UTF-8 but can also go straight to bytes, e.g. for Smile.
303+
// We use a direct byte array argument for the latter case to work as well.
304+
objectWriter.writeValue(bos, object);
305+
}
298306

299307
BytesMessage message = session.createBytesMessage();
300308
message.writeBytes(bos.toByteArray());
301309
if (this.encodingPropertyName != null) {
302-
message.setStringProperty(this.encodingPropertyName, this.encoding);
310+
message.setStringProperty(this.encodingPropertyName,
311+
(this.encoding != null ? this.encoding : DEFAULT_ENCODING));
303312
}
304313
return message;
305314
}
@@ -393,12 +402,18 @@ protected Object convertFromBytesMessage(BytesMessage message, JavaType targetJa
393402
}
394403
byte[] bytes = new byte[(int) message.getBodyLength()];
395404
message.readBytes(bytes);
396-
try {
397-
String body = new String(bytes, encoding);
398-
return this.objectMapper.readValue(body, targetJavaType);
405+
if (encoding != null) {
406+
try {
407+
String body = new String(bytes, encoding);
408+
return this.objectMapper.readValue(body, targetJavaType);
409+
}
410+
catch (UnsupportedEncodingException ex) {
411+
throw new MessageConversionException("Cannot convert bytes to String", ex);
412+
}
399413
}
400-
catch (UnsupportedEncodingException ex) {
401-
throw new MessageConversionException("Cannot convert bytes to String", ex);
414+
else {
415+
// Jackson internally performs encoding detection, falling back to UTF-8.
416+
return this.objectMapper.readValue(bytes, targetJavaType);
402417
}
403418
}
404419

spring-jms/src/test/java/org/springframework/jms/support/converter/MappingJackson2MessageConverterTests.java

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -56,7 +56,7 @@ public class MappingJackson2MessageConverterTests {
5656

5757

5858
@Before
59-
public void setUp() throws Exception {
59+
public void setup() {
6060
sessionMock = mock(Session.class);
6161
converter = new MappingJackson2MessageConverter();
6262
converter.setEncodingPropertyName("__encoding__");
@@ -263,17 +263,18 @@ public MyAnotherBean invalid() {
263263
return new MyAnotherBean();
264264
}
265265

266+
266267
public static class MyBean {
267268

269+
private String foo;
270+
268271
public MyBean() {
269272
}
270273

271274
public MyBean(String foo) {
272275
this.foo = foo;
273276
}
274277

275-
private String foo;
276-
277278
public String getFoo() {
278279
return foo;
279280
}
@@ -290,13 +291,10 @@ public boolean equals(Object o) {
290291
if (o == null || getClass() != o.getClass()) {
291292
return false;
292293
}
293-
294294
MyBean bean = (MyBean) o;
295-
296295
if (foo != null ? !foo.equals(bean.foo) : bean.foo != null) {
297296
return false;
298297
}
299-
300298
return true;
301299
}
302300

@@ -306,9 +304,12 @@ public int hashCode() {
306304
}
307305
}
308306

307+
309308
private interface Summary {};
309+
310310
private interface Full extends Summary {};
311311

312+
312313
private static class MyAnotherBean {
313314

314315
@JsonView(Summary.class)

spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompSession.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,8 +19,8 @@
1919
import org.springframework.lang.Nullable;
2020

2121
/**
22-
* Represents a STOMP session with operations to send messages, create
23-
* subscriptions and receive messages on those subscriptions.
22+
* Represents a STOMP session with operations to send messages,
23+
* create subscriptions and receive messages on those subscriptions.
2424
*
2525
* @author Rossen Stoyanchev
2626
* @since 4.2

spring-web/src/main/java/org/springframework/web/server/adapter/HttpWebHandlerAdapter.java

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -197,8 +197,7 @@ public ForwardedHeaderTransformer getForwardedHeaderTransformer() {
197197
/**
198198
* Configure the {@code ApplicationContext} associated with the web application,
199199
* if it was initialized with one via
200-
* {@link org.springframework.web.server.adapter.WebHttpHandlerBuilder#applicationContext
201-
* WebHttpHandlerBuilder#applicationContext}.
200+
* {@link org.springframework.web.server.adapter.WebHttpHandlerBuilder#applicationContext(ApplicationContext)}.
202201
* @param applicationContext the context
203202
* @since 5.0.3
204203
*/
@@ -232,11 +231,9 @@ public void afterPropertiesSet() {
232231

233232
@Override
234233
public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
235-
236234
if (this.forwardedHeaderTransformer != null) {
237235
request = this.forwardedHeaderTransformer.apply(request);
238236
}
239-
240237
ServerWebExchange exchange = createExchange(request, response);
241238

242239
LogFormatUtils.traceDebug(logger, traceOn ->
@@ -274,7 +271,6 @@ private String formatHeaders(HttpHeaders responseHeaders) {
274271
}
275272

276273
private Mono<Void> handleUnresolvedError(ServerWebExchange exchange, Throwable ex) {
277-
278274
ServerHttpRequest request = exchange.getRequest();
279275
ServerHttpResponse response = exchange.getResponse();
280276
String logPrefix = exchange.getLogPrefix();
@@ -294,7 +290,7 @@ else if (response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR)) {
294290
return Mono.empty();
295291
}
296292
else {
297-
// After the response is committed, propagate errors to the server..
293+
// After the response is committed, propagate errors to the server...
298294
logger.error(logPrefix + "Error [" + ex + "] for " + formatRequest(request) +
299295
", but ServerHttpResponse already committed (" + response.getStatusCode() + ")");
300296
return Mono.error(ex);

0 commit comments

Comments
 (0)