From 6c599208f60c424066d85344a6d2af36e0ca250d Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 5 Mar 2019 13:07:57 +0100 Subject: [PATCH 1/6] Remove javadoc reference to unsupported FieldInterceptor Closes gh-22507 --- .../org/aopalliance/intercept/Interceptor.java | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/Interceptor.java b/spring-aop/src/main/java/org/aopalliance/intercept/Interceptor.java index 9f56db94048..f9742547291 100644 --- a/spring-aop/src/main/java/org/aopalliance/intercept/Interceptor.java +++ b/spring-aop/src/main/java/org/aopalliance/intercept/Interceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,7 @@ import org.aopalliance.aop.Advice; * *
  * class DebuggingInterceptor implements MethodInterceptor,
- *     ConstructorInterceptor, FieldInterceptor {
+ *     ConstructorInterceptor {
  *
  *   Object invoke(MethodInvocation i) throws Throwable {
  *     debug(i.getMethod(), i.getThis(), i.getArgs());
@@ -45,16 +45,6 @@ import org.aopalliance.aop.Advice;
  *     return i.proceed();
  *   }
  *
- *   Object get(FieldAccess fa) throws Throwable {
- *     debug(fa.getField(), fa.getThis(), null);
- *     return fa.proceed();
- *   }
- *
- *   Object set(FieldAccess fa) throws Throwable {
- *     debug(fa.getField(), fa.getThis(), fa.getValueToSet());
- *     return fa.proceed();
- *   }
- *
  *   void debug(AccessibleObject ao, Object this, Object value) {
  *     ...
  *   }

From f6693e790a4ac10edb324e3051ca045478c796ae Mon Sep 17 00:00:00 2001
From: Juergen Hoeller 
Date: Tue, 5 Mar 2019 13:08:04 +0100
Subject: [PATCH 2/6] Jackson2Tokenizer passes DeserializationContext into
 TokenBuffer

Closes gh-22510
---
 .../codec/json/AbstractJackson2Decoder.java   |  6 +-
 .../http/codec/json/Jackson2Tokenizer.java    | 70 +++++++++----------
 .../codec/json/Jackson2TokenizerTests.java    | 23 +++---
 3 files changed, 51 insertions(+), 48 deletions(-)

diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Decoder.java b/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Decoder.java
index 3afadd4fb68..a07c439630a 100644
--- a/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Decoder.java
+++ b/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Decoder.java
@@ -86,7 +86,8 @@ public abstract class AbstractJackson2Decoder extends Jackson2CodecSupport imple
 	public Flux decode(Publisher input, ResolvableType elementType,
 			@Nullable MimeType mimeType, @Nullable Map hints) {
 
-		Flux tokens = Jackson2Tokenizer.tokenize(Flux.from(input), this.jsonFactory, true);
+		Flux tokens = Jackson2Tokenizer.tokenize(
+				Flux.from(input), this.jsonFactory, getObjectMapper().getDeserializationContext(), true);
 		return decodeInternal(tokens, elementType, mimeType, hints);
 	}
 
@@ -94,7 +95,8 @@ public abstract class AbstractJackson2Decoder extends Jackson2CodecSupport imple
 	public Mono decodeToMono(Publisher input, ResolvableType elementType,
 			@Nullable MimeType mimeType, @Nullable Map hints) {
 
-		Flux tokens = Jackson2Tokenizer.tokenize(Flux.from(input), this.jsonFactory, false);
+		Flux tokens = Jackson2Tokenizer.tokenize(
+				Flux.from(input), this.jsonFactory, getObjectMapper().getDeserializationContext(), false);
 		return decodeInternal(tokens, elementType, mimeType, hints).singleOrEmpty();
 	}
 
diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java
index 8af3dffa18a..557948b5401 100644
--- a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java
+++ b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,13 +26,13 @@ import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.JsonToken;
 import com.fasterxml.jackson.core.async.ByteArrayFeeder;
+import com.fasterxml.jackson.databind.DeserializationContext;
 import com.fasterxml.jackson.databind.util.TokenBuffer;
 import reactor.core.publisher.Flux;
 
 import org.springframework.core.codec.DecodingException;
 import org.springframework.core.io.buffer.DataBuffer;
 import org.springframework.core.io.buffer.DataBufferUtils;
-import org.springframework.util.Assert;
 
 /**
  * {@link Function} to transform a JSON stream of arbitrary size, byte array
@@ -40,6 +40,8 @@ import org.springframework.util.Assert;
  * well-formed JSON object.
  *
  * @author Arjen Poutsma
+ * @author Rossen Stoyanchev
+ * @author Juergen Hoeller
  * @since 5.0
  */
 final class Jackson2Tokenizer {
@@ -59,36 +61,15 @@ final class Jackson2Tokenizer {
 	private final ByteArrayFeeder inputFeeder;
 
 
-	private Jackson2Tokenizer(JsonParser parser, boolean tokenizeArrayElements) {
-		Assert.notNull(parser, "'parser' must not be null");
+	private Jackson2Tokenizer(
+			JsonParser parser, DeserializationContext deserializationContext, boolean tokenizeArrayElements) {
 
 		this.parser = parser;
 		this.tokenizeArrayElements = tokenizeArrayElements;
-		this.tokenBuffer = new TokenBuffer(parser);
+		this.tokenBuffer = new TokenBuffer(parser, deserializationContext);
 		this.inputFeeder = (ByteArrayFeeder) this.parser.getNonBlockingInputFeeder();
 	}
 
-	/**
-	 * Tokenize the given {@code Flux} into {@code Flux}.
-	 * @param dataBuffers the source data buffers
-	 * @param jsonFactory the factory to use
-	 * @param tokenizeArrayElements if {@code true} and the "top level" JSON
-	 * object is an array, each element is returned individually, immediately
-	 * after it is received.
-	 * @return the result token buffers
-	 */
-	public static Flux tokenize(Flux dataBuffers, JsonFactory jsonFactory,
-			boolean tokenizeArrayElements) {
-
-		try {
-			JsonParser parser = jsonFactory.createNonBlockingByteArrayParser();
-			Jackson2Tokenizer tokenizer = new Jackson2Tokenizer(parser, tokenizeArrayElements);
-			return dataBuffers.flatMap(tokenizer::tokenize, Flux::error, tokenizer::endOfInput);
-		}
-		catch (IOException ex) {
-			return Flux.error(ex);
-		}
-	}
 
 	private Flux tokenize(DataBuffer dataBuffer) {
 		byte[] bytes = new byte[dataBuffer.readableByteCount()];
@@ -100,8 +81,7 @@ final class Jackson2Tokenizer {
 			return parseTokenBufferFlux();
 		}
 		catch (JsonProcessingException ex) {
-			return Flux.error(new DecodingException(
-					"JSON decoding error: " + ex.getOriginalMessage(), ex));
+			return Flux.error(new DecodingException("JSON decoding error: " + ex.getOriginalMessage(), ex));
 		}
 		catch (IOException ex) {
 			return Flux.error(ex);
@@ -114,8 +94,7 @@ final class Jackson2Tokenizer {
 			return parseTokenBufferFlux();
 		}
 		catch (JsonProcessingException ex) {
-			return Flux.error(new DecodingException(
-					"JSON decoding error: " + ex.getOriginalMessage(), ex));
+			return Flux.error(new DecodingException("JSON decoding error: " + ex.getOriginalMessage(), ex));
 		}
 		catch (IOException ex) {
 			return Flux.error(ex);
@@ -128,12 +107,11 @@ final class Jackson2Tokenizer {
 		while (true) {
 			JsonToken token = this.parser.nextToken();
 			// SPR-16151: Smile data format uses null to separate documents
-			if ((token == JsonToken.NOT_AVAILABLE) ||
+			if (token == JsonToken.NOT_AVAILABLE ||
 					(token == null && (token = this.parser.nextToken()) == null)) {
 				break;
 			}
 			updateDepth(token);
-
 			if (!this.tokenizeArrayElements) {
 				processTokenNormal(token, result);
 			}
@@ -164,8 +142,7 @@ final class Jackson2Tokenizer {
 	private void processTokenNormal(JsonToken token, List result) throws IOException {
 		this.tokenBuffer.copyCurrentEvent(this.parser);
 
-		if ((token.isStructEnd() || token.isScalarValue()) &&
-				this.objectDepth == 0 && this.arrayDepth == 0) {
+		if ((token.isStructEnd() || token.isScalarValue()) && this.objectDepth == 0 && this.arrayDepth == 0) {
 			result.add(this.tokenBuffer);
 			this.tokenBuffer = new TokenBuffer(this.parser);
 		}
@@ -177,8 +154,7 @@ final class Jackson2Tokenizer {
 			this.tokenBuffer.copyCurrentEvent(this.parser);
 		}
 
-		if (this.objectDepth == 0 &&
-				(this.arrayDepth == 0 || this.arrayDepth == 1) &&
+		if (this.objectDepth == 0 && (this.arrayDepth == 0 || this.arrayDepth == 1) &&
 				(token == JsonToken.END_OBJECT || token.isScalarValue())) {
 			result.add(this.tokenBuffer);
 			this.tokenBuffer = new TokenBuffer(this.parser);
@@ -190,4 +166,26 @@ final class Jackson2Tokenizer {
 				(token == JsonToken.END_ARRAY && this.arrayDepth == 0));
 	}
 
+
+	/**
+	 * Tokenize the given {@code Flux} into {@code Flux}.
+	 * @param dataBuffers the source data buffers
+	 * @param jsonFactory the factory to use
+	 * @param tokenizeArrayElements if {@code true} and the "top level" JSON object is
+	 * an array, each element is returned individually immediately after it is received
+	 * @return the resulting token buffers
+	 */
+	public static Flux tokenize(Flux dataBuffers, JsonFactory jsonFactory,
+			DeserializationContext deserializationContext, boolean tokenizeArrayElements) {
+
+		try {
+			JsonParser parser = jsonFactory.createNonBlockingByteArrayParser();
+			Jackson2Tokenizer tokenizer = new Jackson2Tokenizer(parser, deserializationContext, tokenizeArrayElements);
+			return dataBuffers.flatMap(tokenizer::tokenize, Flux::error, tokenizer::endOfInput);
+		}
+		catch (IOException ex) {
+			return Flux.error(ex);
+		}
+	}
+
 }
diff --git a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2TokenizerTests.java b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2TokenizerTests.java
index 8eac524857a..236e8193083 100644
--- a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2TokenizerTests.java
+++ b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2TokenizerTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -37,19 +37,20 @@ import org.springframework.core.codec.DecodingException;
 import org.springframework.core.io.buffer.AbstractLeakCheckingTestCase;
 import org.springframework.core.io.buffer.DataBuffer;
 
-import static java.util.Arrays.asList;
-import static java.util.Collections.singletonList;
+import static java.util.Arrays.*;
+import static java.util.Collections.*;
 
 /**
  * @author Arjen Poutsma
  * @author Rossen Stoyanchev
+ * @author Juergen Hoeller
  */
 public class Jackson2TokenizerTests extends AbstractLeakCheckingTestCase {
 
-	private ObjectMapper objectMapper;
-
 	private JsonFactory jsonFactory;
 
+	private ObjectMapper objectMapper;
+
 
 	@Before
 	public void createParser() {
@@ -57,6 +58,7 @@ public class Jackson2TokenizerTests extends AbstractLeakCheckingTestCase {
 		this.objectMapper = new ObjectMapper(this.jsonFactory);
 	}
 
+
 	@Test
 	public void doNotTokenizeArrayElements() {
 		testTokenize(
@@ -185,7 +187,8 @@ public class Jackson2TokenizerTests extends AbstractLeakCheckingTestCase {
 		Flux source = Flux.just(buffer)
 				.concatWith(Flux.error(new RuntimeException()));
 
-		Flux result = Jackson2Tokenizer.tokenize(source, this.jsonFactory, true);
+		Flux result = Jackson2Tokenizer.tokenize(
+				source, this.jsonFactory, this.objectMapper.getDeserializationContext(), true);
 
 		StepVerifier.create(result)
 				.expectError(RuntimeException.class)
@@ -195,7 +198,8 @@ public class Jackson2TokenizerTests extends AbstractLeakCheckingTestCase {
 	@Test // SPR-16521
 	public void jsonEOFExceptionIsWrappedAsDecodingError() {
 		Flux source = Flux.just(stringBuffer("{\"status\": \"noClosingQuote}"));
-		Flux tokens = Jackson2Tokenizer.tokenize(source, this.jsonFactory, false);
+		Flux tokens = Jackson2Tokenizer.tokenize(
+				source, this.jsonFactory, this.objectMapper.getDeserializationContext(), false);
 
 		StepVerifier.create(tokens)
 				.expectError(DecodingException.class)
@@ -204,10 +208,9 @@ public class Jackson2TokenizerTests extends AbstractLeakCheckingTestCase {
 
 
 	private void testTokenize(List source, List expected, boolean tokenizeArrayElements) {
-
 		Flux tokenBufferFlux = Jackson2Tokenizer.tokenize(
 				Flux.fromIterable(source).map(this::stringBuffer),
-				this.jsonFactory,
+				this.jsonFactory, this.objectMapper.getDeserializationContext(),
 				tokenizeArrayElements);
 
 		Flux result = tokenBufferFlux
@@ -234,7 +237,6 @@ public class Jackson2TokenizerTests extends AbstractLeakCheckingTestCase {
 	}
 
 
-
 	private static class JSONAssertConsumer implements Consumer {
 
 		private final String expected;
@@ -253,4 +255,5 @@ public class Jackson2TokenizerTests extends AbstractLeakCheckingTestCase {
 			}
 		}
 	}
+
 }

From 013c0bca92d121c23fbf5185b3f74f04741fd4d7 Mon Sep 17 00:00:00 2001
From: Juergen Hoeller 
Date: Tue, 5 Mar 2019 13:08:11 +0100
Subject: [PATCH 3/6] Polishing

---
 .../aop/config/TopLevelAopTagTests.java       | 11 ++---
 .../aop/framework/PrototypeTargetTests.java   | 11 +++--
 .../ExposeInvocationInterceptorTests.java     | 10 ++---
 .../aop/scope/ScopedProxyAutowireTests.java   | 17 ++++----
 ...MethodPointcutAdvisorIntegrationTests.java |  5 ++-
 .../target/HotSwappableTargetSourceTests.java | 41 ++++++-------------
 .../target/PrototypeTargetSourceTests.java    | 17 ++++----
 .../target/ThreadLocalTargetSourceTests.java  | 16 ++++----
 .../factory/ConcurrentBeanFactoryTests.java   | 31 +++++++-------
 .../CustomAutowireConfigurerTests.java        | 11 ++---
 .../FieldRetrievingFactoryBeanTests.java      | 10 ++---
 ...ObjectFactoryCreatingFactoryBeanTests.java | 21 +++++-----
 .../factory/config/SimpleScopeTests.java      | 13 +++---
 .../parsing/CustomProblemReporterTests.java   | 10 ++---
 .../http/codec/json/Jackson2CodecSupport.java |  4 +-
 .../support/GenericWebApplicationContext.java | 11 +++--
 .../codec/json/Jackson2JsonDecoderTests.java  | 30 +++++++-------
 17 files changed, 120 insertions(+), 149 deletions(-)

diff --git a/spring-aop/src/test/java/org/springframework/aop/config/TopLevelAopTagTests.java b/spring-aop/src/test/java/org/springframework/aop/config/TopLevelAopTagTests.java
index a0c220d079f..9c9552a2989 100644
--- a/spring-aop/src/test/java/org/springframework/aop/config/TopLevelAopTagTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/config/TopLevelAopTagTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ import org.junit.Test;
 
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
-import org.springframework.core.io.Resource;
 
 import static org.junit.Assert.*;
 import static org.springframework.tests.TestResourceUtils.*;
@@ -33,13 +32,11 @@ import static org.springframework.tests.TestResourceUtils.*;
  */
 public class TopLevelAopTagTests {
 
-	private static final Resource CONTEXT = qualifiedResource(TopLevelAopTagTests.class, "context.xml");
-
 	@Test
-	public void testParse() throws Exception {
+	public void testParse() {
 		DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
-		XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
-		reader.loadBeanDefinitions(CONTEXT);
+		new XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(
+				qualifiedResource(TopLevelAopTagTests.class, "context.xml"));
 
 		assertTrue(beanFactory.containsBeanDefinition("testPointcut"));
 	}
diff --git a/spring-aop/src/test/java/org/springframework/aop/framework/PrototypeTargetTests.java b/spring-aop/src/test/java/org/springframework/aop/framework/PrototypeTargetTests.java
index 455778c83e8..c5de9deee27 100644
--- a/spring-aop/src/test/java/org/springframework/aop/framework/PrototypeTargetTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/framework/PrototypeTargetTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@ public class PrototypeTargetTests {
 
 	private static final Resource CONTEXT = qualifiedResource(PrototypeTargetTests.class, "context.xml");
 
+
 	@Test
 	public void testPrototypeProxyWithPrototypeTarget() {
 		TestBeanImpl.constructionCount = 0;
@@ -64,12 +65,15 @@ public class PrototypeTargetTests {
 		assertEquals(10, interceptor.invocationCount);
 	}
 
-	public static interface TestBean {
-		public void doSomething();
+
+	public interface TestBean {
+
+		void doSomething();
 	}
 
 
 	public static class TestBeanImpl implements TestBean {
+
 		private static int constructionCount = 0;
 
 		public TestBeanImpl() {
@@ -83,6 +87,7 @@ public class PrototypeTargetTests {
 
 
 	public static class TestInterceptor implements MethodInterceptor {
+
 		private int invocationCount = 0;
 
 		@Override
diff --git a/spring-aop/src/test/java/org/springframework/aop/interceptor/ExposeInvocationInterceptorTests.java b/spring-aop/src/test/java/org/springframework/aop/interceptor/ExposeInvocationInterceptorTests.java
index 38f0bd9501f..4c2735abf23 100644
--- a/spring-aop/src/test/java/org/springframework/aop/interceptor/ExposeInvocationInterceptorTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/interceptor/ExposeInvocationInterceptorTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@ import org.junit.Test;
 
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
-import org.springframework.core.io.Resource;
 import org.springframework.tests.sample.beans.ITestBean;
 import org.springframework.tests.sample.beans.TestBean;
 
@@ -36,13 +35,11 @@ import static org.springframework.tests.TestResourceUtils.*;
  */
 public class ExposeInvocationInterceptorTests {
 
-	private static final Resource CONTEXT =
-		qualifiedResource(ExposeInvocationInterceptorTests.class, "context.xml");
-
 	@Test
 	public void testXmlConfig() {
 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
-		new XmlBeanDefinitionReader(bf).loadBeanDefinitions(CONTEXT);
+		new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
+				qualifiedResource(ExposeInvocationInterceptorTests.class, "context.xml"));
 		ITestBean tb = (ITestBean) bf.getBean("proxy");
 		String name = "tony";
 		tb.setName(name);
@@ -74,6 +71,7 @@ abstract class ExposedInvocationTestBean extends TestBean {
 
 
 class InvocationCheckExposedInvocationTestBean extends ExposedInvocationTestBean {
+
 	@Override
 	protected void assertions(MethodInvocation invocation) {
 		assertTrue(invocation.getThis() == this);
diff --git a/spring-aop/src/test/java/org/springframework/aop/scope/ScopedProxyAutowireTests.java b/spring-aop/src/test/java/org/springframework/aop/scope/ScopedProxyAutowireTests.java
index 4b5634f2b0a..67e1c30ddce 100644
--- a/spring-aop/src/test/java/org/springframework/aop/scope/ScopedProxyAutowireTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/scope/ScopedProxyAutowireTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import org.junit.Test;
 
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
-import org.springframework.core.io.Resource;
 
 import static org.junit.Assert.*;
 import static org.springframework.tests.TestResourceUtils.*;
@@ -34,16 +33,12 @@ import static org.springframework.tests.TestResourceUtils.*;
  */
 public class ScopedProxyAutowireTests {
 
-	private static final Resource SCOPED_AUTOWIRE_FALSE_CONTEXT =
-			qualifiedResource(ScopedProxyAutowireTests.class, "scopedAutowireFalse.xml");
-	private static final Resource SCOPED_AUTOWIRE_TRUE_CONTEXT =
-			qualifiedResource(ScopedProxyAutowireTests.class, "scopedAutowireTrue.xml");
-
-
 	@Test
 	public void testScopedProxyInheritsAutowireCandidateFalse() {
 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
-		new XmlBeanDefinitionReader(bf).loadBeanDefinitions(SCOPED_AUTOWIRE_FALSE_CONTEXT);
+		new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
+				qualifiedResource(ScopedProxyAutowireTests.class, "scopedAutowireFalse.xml"));
+
 		assertTrue(Arrays.asList(bf.getBeanNamesForType(TestBean.class, false, false)).contains("scoped"));
 		assertTrue(Arrays.asList(bf.getBeanNamesForType(TestBean.class, true, false)).contains("scoped"));
 		assertFalse(bf.containsSingleton("scoped"));
@@ -55,7 +50,9 @@ public class ScopedProxyAutowireTests {
 	@Test
 	public void testScopedProxyReplacesAutowireCandidateTrue() {
 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
-		new XmlBeanDefinitionReader(bf).loadBeanDefinitions(SCOPED_AUTOWIRE_TRUE_CONTEXT);
+		new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
+				qualifiedResource(ScopedProxyAutowireTests.class, "scopedAutowireTrue.xml"));
+
 		assertTrue(Arrays.asList(bf.getBeanNamesForType(TestBean.class, true, false)).contains("scoped"));
 		assertTrue(Arrays.asList(bf.getBeanNamesForType(TestBean.class, false, false)).contains("scoped"));
 		assertFalse(bf.containsSingleton("scoped"));
diff --git a/spring-aop/src/test/java/org/springframework/aop/support/RegexpMethodPointcutAdvisorIntegrationTests.java b/spring-aop/src/test/java/org/springframework/aop/support/RegexpMethodPointcutAdvisorIntegrationTests.java
index 68b9d26b9ce..b1a5b478d5c 100644
--- a/spring-aop/src/test/java/org/springframework/aop/support/RegexpMethodPointcutAdvisorIntegrationTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/support/RegexpMethodPointcutAdvisorIntegrationTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -39,7 +39,8 @@ import static org.springframework.tests.TestResourceUtils.*;
 public class RegexpMethodPointcutAdvisorIntegrationTests {
 
 	private static final Resource CONTEXT =
-		qualifiedResource(RegexpMethodPointcutAdvisorIntegrationTests.class, "context.xml");
+			qualifiedResource(RegexpMethodPointcutAdvisorIntegrationTests.class, "context.xml");
+
 
 	@Test
 	public void testSinglePattern() throws Throwable {
diff --git a/spring-aop/src/test/java/org/springframework/aop/target/HotSwappableTargetSourceTests.java b/spring-aop/src/test/java/org/springframework/aop/target/HotSwappableTargetSourceTests.java
index 7eb90b8781f..051340bed9b 100644
--- a/spring-aop/src/test/java/org/springframework/aop/target/HotSwappableTargetSourceTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/target/HotSwappableTargetSourceTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,7 +25,6 @@ import org.springframework.aop.framework.ProxyFactory;
 import org.springframework.aop.support.DefaultPointcutAdvisor;
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
-import org.springframework.core.io.Resource;
 import org.springframework.tests.aop.interceptor.SerializableNopInterceptor;
 import org.springframework.tests.sample.beans.Person;
 import org.springframework.tests.sample.beans.SerializablePerson;
@@ -41,31 +40,31 @@ import static org.springframework.tests.TestResourceUtils.*;
  */
 public class HotSwappableTargetSourceTests {
 
-	private static final Resource CONTEXT = qualifiedResource(HotSwappableTargetSourceTests.class, "context.xml");
-
 	/** Initial count value set in bean factory XML */
 	private static final int INITIAL_COUNT = 10;
 
 	private DefaultListableBeanFactory beanFactory;
 
+
 	@Before
-	public void setUp() throws Exception {
+	public void setup() {
 		this.beanFactory = new DefaultListableBeanFactory();
-		new XmlBeanDefinitionReader(this.beanFactory).loadBeanDefinitions(CONTEXT);
+		new XmlBeanDefinitionReader(this.beanFactory).loadBeanDefinitions(
+				qualifiedResource(HotSwappableTargetSourceTests.class, "context.xml"));
 	}
 
 	/**
 	 * We must simulate container shutdown, which should clear threads.
 	 */
 	@After
-	public void tearDown() {
+	public void close() {
 		// Will call pool.close()
 		this.beanFactory.destroySingletons();
 	}
 
+
 	/**
 	 * Check it works like a normal invoker
-	 *
 	 */
 	@Test
 	public void testBasicFunctionality() {
@@ -106,18 +105,13 @@ public class HotSwappableTargetSourceTests {
 		assertEquals(target1.getCount(), proxied.getCount());
 	}
 
-
-	/**
-	 *
-	 * @param invalid
-	 * @return the message
-	 */
-	private IllegalArgumentException testRejectsSwapToInvalidValue(Object invalid) {
+	@Test
+	public void testRejectsSwapToNull() {
 		HotSwappableTargetSource swapper = (HotSwappableTargetSource) beanFactory.getBean("swapper");
 		IllegalArgumentException aopex = null;
 		try {
-			swapper.swap(invalid);
-			fail("Shouldn't be able to swap to invalid value [" + invalid + "]");
+			swapper.swap(null);
+			fail("Shouldn't be able to swap to invalid value");
 		}
 		catch (IllegalArgumentException ex) {
 			// Ok
@@ -126,19 +120,9 @@ public class HotSwappableTargetSourceTests {
 
 		// It shouldn't be corrupted, it should still work
 		testBasicFunctionality();
-		return aopex;
+		assertTrue(aopex.getMessage().contains("null"));
 	}
 
-	@Test
-	public void testRejectsSwapToNull() {
-		IllegalArgumentException ex = testRejectsSwapToInvalidValue(null);
-		assertTrue(ex.getMessage().contains("null"));
-	}
-
-	// TODO test reject swap to wrong interface or class?
-	// how to decide what's valid?
-
-
 	@Test
 	public void testSerialization() throws Exception {
 		SerializablePerson sp1 = new SerializablePerson();
@@ -165,4 +149,5 @@ public class HotSwappableTargetSourceTests {
 		assertEquals(sp1.getName(), p.getName());
 
 	}
+
 }
diff --git a/spring-aop/src/test/java/org/springframework/aop/target/PrototypeTargetSourceTests.java b/spring-aop/src/test/java/org/springframework/aop/target/PrototypeTargetSourceTests.java
index 995ee9f89ac..528dce52aa0 100644
--- a/spring-aop/src/test/java/org/springframework/aop/target/PrototypeTargetSourceTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/target/PrototypeTargetSourceTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,11 +19,8 @@ package org.springframework.aop.target;
 import org.junit.Before;
 import org.junit.Test;
 
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
-import org.springframework.core.io.Resource;
 import org.springframework.tests.sample.beans.SideEffectBean;
 
 import static org.junit.Assert.*;
@@ -35,19 +32,20 @@ import static org.springframework.tests.TestResourceUtils.*;
  */
 public class PrototypeTargetSourceTests {
 
-	private static final Resource CONTEXT = qualifiedResource(PrototypeTargetSourceTests.class, "context.xml");
-
 	/** Initial count value set in bean factory XML */
 	private static final int INITIAL_COUNT = 10;
 
-	private BeanFactory beanFactory;
+	private DefaultListableBeanFactory beanFactory;
+
 
 	@Before
-	public void setUp() throws Exception {
+	public void setup() {
 		this.beanFactory = new DefaultListableBeanFactory();
-		new XmlBeanDefinitionReader((BeanDefinitionRegistry) this.beanFactory).loadBeanDefinitions(CONTEXT);
+		new XmlBeanDefinitionReader(this.beanFactory).loadBeanDefinitions(
+				qualifiedResource(PrototypeTargetSourceTests.class, "context.xml"));
 	}
 
+
 	/**
 	 * Test that multiple invocations of the prototype bean will result
 	 * in no change to visible state, as a new instance is used.
@@ -66,5 +64,4 @@ public class PrototypeTargetSourceTests {
 		assertEquals(INITIAL_COUNT, prototype.getCount());
 	}
 
-
 }
diff --git a/spring-aop/src/test/java/org/springframework/aop/target/ThreadLocalTargetSourceTests.java b/spring-aop/src/test/java/org/springframework/aop/target/ThreadLocalTargetSourceTests.java
index 0ff97aa8a98..baa6005d0f8 100644
--- a/spring-aop/src/test/java/org/springframework/aop/target/ThreadLocalTargetSourceTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/target/ThreadLocalTargetSourceTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@ import org.junit.Test;
 
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
-import org.springframework.core.io.Resource;
 import org.springframework.tests.sample.beans.ITestBean;
 import org.springframework.tests.sample.beans.SideEffectBean;
 
@@ -34,26 +33,27 @@ import static org.springframework.tests.TestResourceUtils.*;
  */
 public class ThreadLocalTargetSourceTests {
 
-	private static final Resource CONTEXT = qualifiedResource(ThreadLocalTargetSourceTests.class, "context.xml");
-
 	/** Initial count value set in bean factory XML */
 	private static final int INITIAL_COUNT = 10;
 
 	private DefaultListableBeanFactory beanFactory;
 
+
 	@Before
-	public void setUp() throws Exception {
+	public void setup() {
 		this.beanFactory = new DefaultListableBeanFactory();
-		new XmlBeanDefinitionReader(this.beanFactory).loadBeanDefinitions(CONTEXT);
+		new XmlBeanDefinitionReader(this.beanFactory).loadBeanDefinitions(
+				qualifiedResource(ThreadLocalTargetSourceTests.class, "context.xml"));
 	}
 
 	/**
 	 * We must simulate container shutdown, which should clear threads.
 	 */
-	protected void tearDown() {
+	protected void close() {
 		this.beanFactory.destroySingletons();
 	}
 
+
 	/**
 	 * Check we can use two different ThreadLocalTargetSources
 	 * managing objects of different types without them interfering
@@ -141,7 +141,7 @@ public class ThreadLocalTargetSourceTests {
 	}
 
 	/**
-	 * Test for SPR-1442. Destroyed target should re-associated with thread and not throw NPE
+	 * Test for SPR-1442. Destroyed target should re-associated with thread and not throw NPE.
 	 */
 	@Test
 	public void testReuseDestroyedTarget() {
diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/ConcurrentBeanFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/ConcurrentBeanFactoryTests.java
index c21ab35c9f5..a18f0a32663 100644
--- a/spring-beans/src/test/java/org/springframework/beans/factory/ConcurrentBeanFactoryTests.java
+++ b/spring-beans/src/test/java/org/springframework/beans/factory/ConcurrentBeanFactoryTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -50,10 +50,8 @@ import static org.springframework.tests.TestResourceUtils.*;
  */
 public class ConcurrentBeanFactoryTests {
 
-	private static final Log logger = LogFactory.getLog(ConcurrentBeanFactoryTests.class);
-	private static final Resource CONTEXT = qualifiedResource(ConcurrentBeanFactoryTests.class, "context.xml");
-
 	private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd");
+
 	private static final Date DATE_1, DATE_2;
 
 	static {
@@ -66,27 +64,32 @@ public class ConcurrentBeanFactoryTests {
 		}
 	}
 
+
+	private static final Log logger = LogFactory.getLog(ConcurrentBeanFactoryTests.class);
+
 	private BeanFactory factory;
 
-	private final Set set = Collections.synchronizedSet(new HashSet());
+	private final Set set = Collections.synchronizedSet(new HashSet<>());
+
+	private Throwable ex;
 
-	private Throwable ex = null;
 
 	@Before
-	public void setUp() throws Exception {
+	public void setup() throws Exception {
 		Assume.group(TestGroup.PERFORMANCE);
 
 		DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
-		new XmlBeanDefinitionReader(factory).loadBeanDefinitions(CONTEXT);
-		factory.addPropertyEditorRegistrar(new PropertyEditorRegistrar() {
-			@Override
-			public void registerCustomEditors(PropertyEditorRegistry registry) {
-				registry.registerCustomEditor(Date.class, new CustomDateEditor((DateFormat) DATE_FORMAT.clone(), false));
-			}
-		});
+		new XmlBeanDefinitionReader(factory).loadBeanDefinitions(
+				qualifiedResource(ConcurrentBeanFactoryTests.class, "context.xml"));
+
+		factory.addPropertyEditorRegistrar(
+				registry -> registry.registerCustomEditor(Date.class,
+						new CustomDateEditor((DateFormat) DATE_FORMAT.clone(), false)));
+
 		this.factory = factory;
 	}
 
+
 	@Test
 	public void testSingleThread() {
 		for (int i = 0; i < 100; i++) {
diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/CustomAutowireConfigurerTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/CustomAutowireConfigurerTests.java
index 83dd5af5c5f..027975beff4 100644
--- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/CustomAutowireConfigurerTests.java
+++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/CustomAutowireConfigurerTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,10 +21,8 @@ import org.junit.Test;
 import org.springframework.beans.factory.config.BeanDefinitionHolder;
 import org.springframework.beans.factory.config.DependencyDescriptor;
 import org.springframework.beans.factory.support.AutowireCandidateResolver;
-import org.springframework.beans.factory.support.BeanDefinitionReader;
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
-import org.springframework.core.io.Resource;
 
 import static org.junit.Assert.*;
 import static org.springframework.tests.TestResourceUtils.*;
@@ -38,13 +36,12 @@ import static org.springframework.tests.TestResourceUtils.*;
  */
 public class CustomAutowireConfigurerTests {
 
-	private static final Resource CONTEXT = qualifiedResource(CustomAutowireConfigurerTests.class, "context.xml");
-
 	@Test
 	public void testCustomResolver() {
 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
-		BeanDefinitionReader reader = new XmlBeanDefinitionReader(bf);
-		reader.loadBeanDefinitions(CONTEXT);
+		new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
+				qualifiedResource(CustomAutowireConfigurerTests.class, "context.xml"));
+
 		CustomAutowireConfigurer cac = new CustomAutowireConfigurer();
 		CustomResolver customResolver = new CustomResolver();
 		bf.setAutowireCandidateResolver(customResolver);
diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/config/FieldRetrievingFactoryBeanTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/config/FieldRetrievingFactoryBeanTests.java
index 2f432e33be5..7c827c5b2ae 100644
--- a/spring-beans/src/test/java/org/springframework/beans/factory/config/FieldRetrievingFactoryBeanTests.java
+++ b/spring-beans/src/test/java/org/springframework/beans/factory/config/FieldRetrievingFactoryBeanTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import org.junit.Test;
 
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
-import org.springframework.core.io.Resource;
 import org.springframework.tests.sample.beans.TestBean;
 
 import static org.junit.Assert.*;
@@ -37,9 +36,6 @@ import static org.springframework.tests.TestResourceUtils.*;
  */
 public class FieldRetrievingFactoryBeanTests {
 
-	private static final Resource CONTEXT =
-		qualifiedResource(FieldRetrievingFactoryBeanTests.class, "context.xml");
-
 	@Test
 	public void testStaticField() throws Exception {
 		FieldRetrievingFactoryBean fr = new FieldRetrievingFactoryBean();
@@ -127,7 +123,9 @@ public class FieldRetrievingFactoryBeanTests {
 	@Test
 	public void testBeanNameSyntaxWithBeanFactory() throws Exception {
 		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
-		new XmlBeanDefinitionReader(bf).loadBeanDefinitions(CONTEXT);
+		new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
+				qualifiedResource(FieldRetrievingFactoryBeanTests.class, "context.xml"));
+
 		TestBean testBean = (TestBean) bf.getBean("testBean");
 		assertEquals(new Integer(Connection.TRANSACTION_SERIALIZABLE), testBean.getSomeIntegerArray()[0]);
 		assertEquals(new Integer(Connection.TRANSACTION_SERIALIZABLE), testBean.getSomeIntegerArray()[1]);
diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/config/ObjectFactoryCreatingFactoryBeanTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/config/ObjectFactoryCreatingFactoryBeanTests.java
index 5cc613d8ccd..d3535164a7b 100644
--- a/spring-beans/src/test/java/org/springframework/beans/factory/config/ObjectFactoryCreatingFactoryBeanTests.java
+++ b/spring-beans/src/test/java/org/springframework/beans/factory/config/ObjectFactoryCreatingFactoryBeanTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,7 +27,6 @@ import org.springframework.beans.factory.BeanFactory;
 import org.springframework.beans.factory.ObjectFactory;
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
-import org.springframework.core.io.Resource;
 import org.springframework.util.SerializationTestUtils;
 
 import static org.junit.Assert.*;
@@ -42,25 +41,25 @@ import static org.springframework.tests.TestResourceUtils.*;
  */
 public class ObjectFactoryCreatingFactoryBeanTests {
 
-	private static final Resource CONTEXT =
-		qualifiedResource(ObjectFactoryCreatingFactoryBeanTests.class, "context.xml");
-
 	private DefaultListableBeanFactory beanFactory;
 
+
 	@Before
-	public void setUp() {
+	public void setup() {
 		this.beanFactory = new DefaultListableBeanFactory();
-		new XmlBeanDefinitionReader(this.beanFactory).loadBeanDefinitions(CONTEXT);
+		new XmlBeanDefinitionReader(this.beanFactory).loadBeanDefinitions(
+				qualifiedResource(ObjectFactoryCreatingFactoryBeanTests.class, "context.xml"));
 		this.beanFactory.setSerializationId("test");
 	}
 
 	@After
-	public void tearDown() {
+	public void close() {
 		this.beanFactory.setSerializationId(null);
 	}
 
+
 	@Test
-	public void testFactoryOperation() throws Exception {
+	public void testFactoryOperation() {
 		FactoryTestBean testBean = beanFactory.getBean("factoryTestBean", FactoryTestBean.class);
 		ObjectFactory objectFactory = testBean.getObjectFactory();
 
@@ -82,7 +81,7 @@ public class ObjectFactoryCreatingFactoryBeanTests {
 	}
 
 	@Test
-	public void testProviderOperation() throws Exception {
+	public void testProviderOperation() {
 		ProviderTestBean testBean = beanFactory.getBean("providerTestBean", ProviderTestBean.class);
 		Provider provider = testBean.getProvider();
 
@@ -152,7 +151,7 @@ public class ObjectFactoryCreatingFactoryBeanTests {
 	}
 
 	@Test
-	public void testEnsureOFBFBReportsThatItActuallyCreatesObjectFactoryInstances() throws Exception {
+	public void testEnsureOFBFBReportsThatItActuallyCreatesObjectFactoryInstances() {
 		assertEquals("Must be reporting that it creates ObjectFactory instances (as per class contract).",
 			ObjectFactory.class, new ObjectFactoryCreatingFactoryBean().getObjectType());
 	}
diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/config/SimpleScopeTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/config/SimpleScopeTests.java
index 2a81acb06fa..dcca770141c 100644
--- a/spring-beans/src/test/java/org/springframework/beans/factory/config/SimpleScopeTests.java
+++ b/spring-beans/src/test/java/org/springframework/beans/factory/config/SimpleScopeTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,7 +25,6 @@ import org.junit.Test;
 import org.springframework.beans.factory.ObjectFactory;
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
-import org.springframework.core.io.Resource;
 import org.springframework.tests.sample.beans.TestBean;
 
 import static org.junit.Assert.*;
@@ -40,12 +39,11 @@ import static org.springframework.tests.TestResourceUtils.*;
  */
 public class SimpleScopeTests {
 
-	private static final Resource CONTEXT = qualifiedResource(SimpleScopeTests.class, "context.xml");
-
 	private DefaultListableBeanFactory beanFactory;
 
+
 	@Before
-	public void setUp() {
+	public void setup() {
 		beanFactory = new DefaultListableBeanFactory();
 		Scope scope = new NoOpScope() {
 			private int index;
@@ -69,10 +67,11 @@ public class SimpleScopeTests {
 		assertEquals("myScope", scopeNames[0]);
 		assertSame(scope, beanFactory.getRegisteredScope("myScope"));
 
-		XmlBeanDefinitionReader xbdr = new XmlBeanDefinitionReader(beanFactory);
-		xbdr.loadBeanDefinitions(CONTEXT);
+		new XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(
+				qualifiedResource(SimpleScopeTests.class, "context.xml"));
 	}
 
+
 	@Test
 	public void testCanGetScopedObject() {
 		TestBean tb1 = (TestBean) beanFactory.getBean("usesScope");
diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/parsing/CustomProblemReporterTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/parsing/CustomProblemReporterTests.java
index adfe6176cb1..7345475d9bd 100644
--- a/spring-beans/src/test/java/org/springframework/beans/factory/parsing/CustomProblemReporterTests.java
+++ b/spring-beans/src/test/java/org/springframework/beans/factory/parsing/CustomProblemReporterTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,7 +24,6 @@ import org.junit.Test;
 
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
-import org.springframework.core.io.Resource;
 import org.springframework.tests.sample.beans.TestBean;
 
 import static org.junit.Assert.*;
@@ -37,8 +36,6 @@ import static org.springframework.tests.TestResourceUtils.*;
  */
 public class CustomProblemReporterTests {
 
-	private static final Resource CONTEXT = qualifiedResource(CustomProblemReporterTests.class, "context.xml");
-
 	private CollatingProblemReporter problemReporter;
 
 	private DefaultListableBeanFactory beanFactory;
@@ -47,16 +44,17 @@ public class CustomProblemReporterTests {
 
 
 	@Before
-	public void setUp() {
+	public void setup() {
 		this.problemReporter = new CollatingProblemReporter();
 		this.beanFactory = new DefaultListableBeanFactory();
 		this.reader = new XmlBeanDefinitionReader(this.beanFactory);
 		this.reader.setProblemReporter(this.problemReporter);
 	}
 
+
 	@Test
 	public void testErrorsAreCollated() {
-		this.reader.loadBeanDefinitions(CONTEXT);
+		this.reader.loadBeanDefinitions(qualifiedResource(CustomProblemReporterTests.class, "context.xml"));
 		assertEquals("Incorrect number of errors collated", 4, this.problemReporter.getErrors().length);
 
 		TestBean bean = (TestBean) this.beanFactory.getBean("validBean");
diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2CodecSupport.java b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2CodecSupport.java
index ff3efa860cc..bfb5e450045 100644
--- a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2CodecSupport.java
+++ b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2CodecSupport.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -119,7 +119,7 @@ public abstract class Jackson2CodecSupport {
 
 	@Nullable
 	protected MethodParameter getParameter(ResolvableType type) {
-		return type.getSource() instanceof MethodParameter ? (MethodParameter) type.getSource() : null;
+		return (type.getSource() instanceof MethodParameter ? (MethodParameter) type.getSource() : null);
 	}
 
 	@Nullable
diff --git a/spring-web/src/main/java/org/springframework/web/context/support/GenericWebApplicationContext.java b/spring-web/src/main/java/org/springframework/web/context/support/GenericWebApplicationContext.java
index 69a22bbb1af..1e8fba2055d 100644
--- a/spring-web/src/main/java/org/springframework/web/context/support/GenericWebApplicationContext.java
+++ b/spring-web/src/main/java/org/springframework/web/context/support/GenericWebApplicationContext.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -39,11 +39,10 @@ import org.springframework.web.context.ServletContextAware;
 /**
  * Subclass of {@link GenericApplicationContext}, suitable for web environments.
  *
- * 

Implements the - * {@link org.springframework.web.context.ConfigurableWebApplicationContext}, - * but is not intended for declarative setup in {@code web.xml}. Instead, - * it is designed for programmatic setup, for example for building nested contexts or - * for use within Spring 3.1 {@link org.springframework.web.WebApplicationInitializer org.springframework.web.WebApplicationInitializers}. + *

Implements {@link org.springframework.web.context.ConfigurableWebApplicationContext}, + * but is not intended for declarative setup in {@code web.xml}. Instead, it is designed + * for programmatic setup, for example for building nested contexts or for use within + * {@link org.springframework.web.WebApplicationInitializer WebApplicationInitializers}. * *

If you intend to implement a WebApplicationContext that reads bean definitions * from configuration files, consider deriving from AbstractRefreshableWebApplicationContext, diff --git a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java index 0556f2ffc89..a3ac0dea091 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java @@ -42,18 +42,13 @@ import org.springframework.http.MediaType; import org.springframework.http.codec.Pojo; import org.springframework.util.MimeType; -import static java.util.Arrays.asList; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; +import static java.util.Arrays.*; +import static java.util.Collections.*; import static org.junit.Assert.*; -import static org.springframework.core.ResolvableType.forClass; -import static org.springframework.http.MediaType.APPLICATION_JSON; -import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8; -import static org.springframework.http.MediaType.APPLICATION_STREAM_JSON; -import static org.springframework.http.MediaType.APPLICATION_XML; -import static org.springframework.http.codec.json.Jackson2JsonDecoder.JSON_VIEW_HINT; -import static org.springframework.http.codec.json.JacksonViewBean.MyJacksonView1; -import static org.springframework.http.codec.json.JacksonViewBean.MyJacksonView3; +import static org.springframework.core.ResolvableType.*; +import static org.springframework.http.MediaType.*; +import static org.springframework.http.codec.json.Jackson2JsonDecoder.*; +import static org.springframework.http.codec.json.JacksonViewBean.*; /** * Unit tests for {@link Jackson2JsonDecoder}. @@ -67,10 +62,12 @@ public class Jackson2JsonDecoderTests extends AbstractDecoderTestCase { private static final long serialVersionUID = 1L; @@ -254,8 +253,7 @@ public class Jackson2JsonDecoderTests extends AbstractDecoderTestCase Date: Tue, 5 Mar 2019 13:08:24 +0100 Subject: [PATCH 4/6] Revised AOP documentation: load-time weaving, CGLIB etc Includes removal of outdated Spring 1.2/2.0 references. Closes gh-22429 --- src/docs/asciidoc/core/core-aop-api.adoc | 26 +- src/docs/asciidoc/core/core-aop.adoc | 450 ++++++++++------------- 2 files changed, 195 insertions(+), 281 deletions(-) diff --git a/src/docs/asciidoc/core/core-aop-api.adoc b/src/docs/asciidoc/core/core-aop-api.adoc index c1f75e0aae8..f2541e937b1 100644 --- a/src/docs/asciidoc/core/core-aop-api.adoc +++ b/src/docs/asciidoc/core/core-aop-api.adoc @@ -1,14 +1,10 @@ [[aop-api]] = Spring AOP APIs -The previous chapter described the Spring's support for AOP with -@AspectJ and schema-based aspect definitions. In this chapter, we discuss the lower-level -Spring AOP APIs and the AOP support typically used in Spring 1.2 applications. For new -applications, we recommend the use of the Spring 2.0 and later AOP support described in -the previous chapter. However, when you work with existing applications (or when you read books -and articles), you may come across Spring 1.2-style examples. Spring 5 remains backwards -compatible with Spring 1.2, and everything described in this chapter is fully supported -in Spring 5. +The previous chapter described the Spring's support for AOP with @AspectJ and schema-based +aspect definitions. In this chapter, we discuss the lower-level Spring AOP APIs. For common +applications, we recommend the use of Spring AOP with AspectJ pointcuts as described in the +previous chapter. @@ -117,7 +113,7 @@ Since 2.0, the most important type of pointcut used by Spring is `org.springframework.aop.aspectj.AspectJExpressionPointcut`. This is a pointcut that uses an AspectJ-supplied library to parse an AspectJ pointcut expression string. -See the <> for a discussion of supported AspectJ pointcut primitives. +See the <> for a discussion of supported AspectJ pointcut primitives. @@ -253,8 +249,7 @@ following example shows how to subclass `StaticMethodMatcherPointcut`: ==== There are also superclasses for dynamic pointcuts. - -You can use custom pointcuts with any advice type in Spring 1.0 RC2 and above. +You can use custom pointcuts with any advice type. @@ -1046,8 +1041,7 @@ to consider: and included in the spring-core JAR. In other words, CGLIB-based AOP works "`out of the box`", as do JDK dynamic proxies. -There is little performance difference between CGLIB proxying and dynamic proxies. As of -Spring 1.0, dynamic proxies are slightly faster. However, this may change in the future. +There is little performance difference between CGLIB proxying and dynamic proxies. Performance should not be a decisive consideration in this case. @@ -1150,7 +1144,7 @@ we override the transaction propagation settings: Note that in the parent bean example, we explicitly marked the parent bean definition as being abstract by setting the `abstract` attribute to `true`, as described -<>, so that it may not actually ever be +<>, so that it may not actually ever be instantiated. Application contexts (but not simple bean factories), by default, pre-instantiate all singletons. Therefore, it is important (at least for singleton beans) that, if you have a (parent) bean definition that you intend to use only as a template, @@ -1290,9 +1284,7 @@ Depending on how you created the proxy, you can usually set a `frozen` flag. In case, the `Advised` `isFrozen()` method returns `true`, and any attempts to modify advice through addition or removal results in an `AopConfigException`. The ability to freeze the state of an advised object is useful in some cases (for example, to -prevent calling code removing a security interceptor). It may also be used in Spring 1.1 -to allow aggressive optimization if runtime advice modification is known not to be -required. +prevent calling code removing a security interceptor). diff --git a/src/docs/asciidoc/core/core-aop.adoc b/src/docs/asciidoc/core/core-aop.adoc index 83ad5afdf9b..fbaf5c276a7 100644 --- a/src/docs/asciidoc/core/core-aop.adoc +++ b/src/docs/asciidoc/core/core-aop.adoc @@ -2,33 +2,31 @@ = Aspect Oriented Programming with Spring Aspect-oriented Programming (AOP) complements Object-oriented Programming (OOP) by -providing another way of thinking about program structure. The key unit of modularity in -OOP is the class, whereas in AOP the unit of modularity is the aspect. Aspects +providing another way of thinking about program structure. The key unit of modularity +in OOP is the class, whereas in AOP the unit of modularity is the aspect. Aspects enable the modularization of concerns (such as transaction management) that cut across -multiple types and objects. (Such concerns are often termed "`crosscutting`" concerns in -AOP literature.) +multiple types and objects. (Such concerns are often termed "`crosscutting`" concerns +in AOP literature.) One of the key components of Spring is the AOP framework. While the Spring IoC container does not depend on AOP (meaning you do not need to use AOP if you don't want to), AOP complements Spring IoC to provide a very capable middleware solution. -.Spring 2.0+ AOP +.Spring AOP with AspectJ pointcuts **** -Spring 2.0 introduced a simpler and more powerful way of writing custom aspects by using -either a <> or the <>. Both of these styles offer fully typed advice and use of the AspectJ pointcut -language while still using Spring AOP for weaving. - -This chapter discusses the Spring 2.0+ schema- and @AspectJ-based AOP support. -The lower-level AOP support, as commonly exposed in Spring 1.2 applications, is -discussed in <>. +Spring provides simple and powerful ways of writing custom aspects by using either a +<> or the <>. +Both of these styles offer fully typed advice and use of the AspectJ pointcut language +while still using Spring AOP for weaving. + +This chapter discusses the schema- and @AspectJ-based AOP support. +The lower-level AOP support is discussed in <>. **** AOP is used in the Spring Framework to: -* Provide declarative enterprise services, especially as a replacement for EJB - declarative services. The most important such service is - <>. +* Provide declarative enterprise services. The most important such service is + <>. * Let users implement custom aspects, complementing their use of OOP with AOP. NOTE: If you are interested only in generic declarative services or other pre-packaged @@ -48,7 +46,7 @@ However, it would be even more confusing if Spring used its own terminology. * Aspect: A modularization of a concern that cuts across multiple classes. Transaction management is a good example of a crosscutting concern in enterprise Java applications. In Spring AOP, aspects are implemented by using regular classes - (the <>) or regular classes annotated with the + (the <>) or regular classes annotated with the `@Aspect` annotation (the <>). * Join point: A point during the execution of a program, such as the execution of a method or the handling of an exception. In Spring AOP, a join point always @@ -104,14 +102,14 @@ the same thing. Using the most specific advice type provides a simpler programmi with less potential for errors. For example, you do not need to invoke the `proceed()` method on the `JoinPoint` used for around advice, and, hence, you cannot fail to invoke it. -In Spring 2.0, all advice parameters are statically typed so that you work with advice -parameters of the appropriate type (the type of the return value from a method execution -for example) rather than `Object` arrays. +All advice parameters are statically typed so that you work with advice parameters of +the appropriate type (e.g. the type of the return value from a method execution) rather +than `Object` arrays. The concept of join points matched by pointcuts is the key to AOP, which distinguishes it from older technologies offering only interception. Pointcuts enable advice to be -targeted independently of the object-oriented hierarchy. For example, you can apply an around advice -providing declarative transaction management to a set of methods that span +targeted independently of the object-oriented hierarchy. For example, you can apply an +around advice providing declarative transaction management to a set of methods that span multiple objects (such as all business operations in the service layer). @@ -149,8 +147,8 @@ frameworks such as AspectJ are valuable and that they are complementary, rather competition. Spring seamlessly integrates Spring AOP and IoC with AspectJ, to enable all uses of AOP within a consistent Spring-based application architecture. This integration does not affect the Spring AOP API or the AOP Alliance -API. Spring AOP remains backward-compatible. See <> for a -discussion of the Spring AOP APIs. +API. Spring AOP remains backward-compatible. See <> +for a discussion of the Spring AOP APIs. [NOTE] ==== @@ -171,8 +169,8 @@ configuration-style approach. The fact that this chapter chooses to introduce th @AspectJ-style approach first should not be taken as an indication that the Spring team favors the @AspectJ annotation-style approach over the Spring XML configuration-style. -See <> for a more complete discussion of the "`whys and wherefores`" of each -style. +See <> for a more complete discussion of the "`whys and wherefores`" of +each style. ==== @@ -188,7 +186,7 @@ Spring AOP can also use CGLIB proxies. This is necessary to proxy classes rather interfaces. By default, CGLIB is used if a business object does not implement an interface. As it is good practice to program to interfaces rather than classes, business classes normally implement one or more business interfaces. It is possible to -<>, in those (hopefully rare) cases where you +<>, in those (hopefully rare) cases where you need to advise a method that is not declared on an interface or where you need to pass a proxied object to a method as a concrete type. @@ -209,8 +207,8 @@ interprets the same annotations as AspectJ 5, using a library supplied by Aspect for pointcut parsing and matching. The AOP runtime is still pure Spring AOP, though, and there is no dependency on the AspectJ compiler or weaver. -NOTE: Using the AspectJ compiler and weaver enables use of the full AspectJ language and is -discussed in <>. +NOTE: Using the AspectJ compiler and weaver enables use of the full AspectJ language and +is discussed in <>. @@ -263,9 +261,9 @@ element, as the following example shows: ==== This assumes that you use schema support as described in -<>. See -<> for how to import the tags in the `aop` -namespace. +<>. +See <> for how to +import the tags in the `aop` namespace. @@ -277,8 +275,8 @@ class that is an @AspectJ aspect (has the `@Aspect` annotation) is automatically detected by Spring and used to configure Spring AOP. The next two examples show the minimal definition required for a not-very-useful aspect. -The first of the two example shows a regular bean definition in the application context that points to a bean class that has -the `@Aspect` annotation: +The first of the two example shows a regular bean definition in the application +context that points to a bean class that has the `@Aspect` annotation: ==== [source,xml,indent=0] @@ -290,8 +288,8 @@ the `@Aspect` annotation: ---- ==== -The second of the two examples shows the `NotVeryUsefulAspect` class definition, which is annotated with -the `org.aspectj.lang.annotation.Aspect` annotation; +The second of the two examples shows the `NotVeryUsefulAspect` class definition, +which is annotated with the `org.aspectj.lang.annotation.Aspect` annotation; ==== [source,java,indent=0] @@ -423,7 +421,7 @@ If a pointcut is strictly meant to be public-only, even in a CGLIB proxy scenari potential non-public interactions through proxies, it needs to be defined accordingly. If your interception needs include method calls or even constructors within the target -class, consider the use of Spring-driven <> instead +class, consider the use of Spring-driven <> instead of Spring's proxy-based AOP framework. This constitutes a different mode of AOP usage with different characteristics, so be sure to make yourself familiar with weaving before making a decision. @@ -1097,8 +1095,8 @@ taken by Spring is simpler and a better match to its proxy-based, execution-only semantics. You only need to be aware of this difference if you compile @AspectJ aspects written for Spring and use `proceed` with arguments with the AspectJ compiler and weaver. There is a way to write such aspects that is 100% compatible across both -Spring AOP and AspectJ, and this is discussed in the <>. +Spring AOP and AspectJ, and this is discussed in the +<>. The following example shows how to use around advice: @@ -1654,8 +1652,7 @@ of advice parameters. To use the aop namespace tags described in this section, you need to import the `spring-aop` schema, as described in <>. -See <> +XML Schema-based configuration>>. See <> for how to import the tags in the `aop` namespace. Within your Spring configurations, all aspect and advisor elements must be placed within @@ -1664,10 +1661,11 @@ application context configuration). An `` element can contain pointc advisor, and aspect elements (note that these must be declared in that order). WARNING: The `` style of configuration makes heavy use of Spring's -<> mechanism. This can cause issues (such as advice not -being woven) if you already use explicit auto-proxying through the use of -`BeanNameAutoProxyCreator` or something similar. The recommended usage pattern is to use either -only the `` style or only the `AutoProxyCreator` style and never mix them. +<> mechanism. This can cause issues (such as advice +not being woven) if you already use explicit auto-proxying through the use of +`BeanNameAutoProxyCreator` or something similar. The recommended usage pattern is to +use either only the `` style or only the `AutoProxyCreator` style and +never mix them. @@ -1725,10 +1723,9 @@ be defined as follows: ==== Note that the pointcut expression itself is using the same AspectJ pointcut expression -language as described in <>. If you use the schema based -declaration style, you can refer to named pointcuts defined in types -(@Aspects) within the pointcut expression. Another way of defining the above pointcut -would be as follows: +language as described in <>. If you use the schema based declaration +style, you can refer to named pointcuts defined in types (@Aspects) within the +pointcut expression. Another way of defining the above pointcut would be as follows: ==== [source,xml,indent=0] @@ -2582,11 +2579,11 @@ The downside of the XML approach is that you cannot define the The @AspectJ style supports additional instantiation models and richer pointcut composition. It has the advantage of keeping the aspect as a modular unit. It also has -the advantage that the @AspectJ aspects can be understood (and thus consumed) both by Spring -AOP and by AspectJ. So, if you later decide you need the capabilities of AspectJ to -implement additional requirements, you can easily migrate to an AspectJ-based -approach. On balance, the Spring team prefers the @AspectJ style whenever you have aspects -that do more than simple configuration of enterprise services. +the advantage that the @AspectJ aspects can be understood (and thus consumed) both by +Spring AOP and by AspectJ. So, if you later decide you need the capabilities of AspectJ +to implement additional requirements, you can easily migrate to a classic AspectJ setup. +On balance, the Spring team prefers the @AspectJ style for custom aspects beyond simple +configuration of enterprise services. @@ -2595,10 +2592,9 @@ that do more than simple configuration of enterprise services. == Mixing Aspect Types It is perfectly possible to mix @AspectJ style aspects by using the auto-proxying support, -schema-defined `` aspects, `` declared advisors, and even -proxies and interceptors defined with the Spring 1.2 style in the same configuration. -All of these are implemented by using the same underlying support mechanism and can -co-exist without any difficulty. +schema-defined `` aspects, `` declared advisors, and even proxies +and interceptors in other styles in the same configuration. All of these are implemented +by using the same underlying support mechanism and can co-exist without any difficulty. @@ -2607,29 +2603,26 @@ co-exist without any difficulty. == Proxying Mechanisms Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxy for a given -target object. (JDK dynamic proxies are preferred whenever you have a choice). +target object. JDK dynamic proxies are built into the JDK, whereas CGLIB is a common +open-source class definition library (repackaged into `spring-core`). If the target object to be proxied implements at least one interface, a JDK dynamic -proxy is used. All of the interfaces implemented by the target type are -proxied. If the target object does not implement any interfaces, a CGLIB proxy is -created. +proxy is used. All of the interfaces implemented by the target type are proxied. +If the target object does not implement any interfaces, a CGLIB proxy is created. If you want to force the use of CGLIB proxying (for example, to proxy every method -defined for the target object, not only those implemented by its interfaces), you can do -so. However, you should consider the following issues: - -* `final` methods cannot be advised, as they cannot be overridden. -* As of Spring 3.2, it is no longer necessary to add CGLIB to your project classpath, as - CGLIB classes are repackaged under `org.springframework` and included directly in the - spring-core JAR. This means that CGLIB-based proxy support "`just works`", in the same - way that JDK dynamic proxies always have. -* As of Spring 4.0, the constructor of your proxied object is NOT called twice - any more, since the CGLIB proxy instance is created through Objenesis. Only if your - JVM does not allow for constructor bypassing, you might see double invocations and +defined for the target object, not only those implemented by its interfaces), +you can do so. However, you should consider the following issues: + +* With CGLIB, `final` methods cannot be advised, as they cannot be overridden in + runtime-generated subclasses. +* As of Spring 4.0, the constructor of your proxied object is NOT called twice anymore, + since the CGLIB proxy instance is created through Objenesis. Only if your JVM does + not allow for constructor bypassing, you might see double invocations and corresponding debug log entries from Spring's AOP support. -To force the use of CGLIB proxies, set the value of the `proxy-target-class` attribute of -the `` element to true, as follows: +To force the use of CGLIB proxies, set the value of the `proxy-target-class` attribute +of the `` element to true, as follows: ==== [source,xml,indent=0] @@ -2642,8 +2635,8 @@ the `` element to true, as follows: ==== To force CGLIB proxying when you use the @AspectJ auto-proxy support, set the -`proxy-target-class` attribute of the `` element to `true`, as -follows: +`proxy-target-class` attribute of the `` element to `true`, +as follows: ==== [source,xml,indent=0] @@ -2709,9 +2702,7 @@ image::images/aop-proxy-plain-pojo-call.png[] public class Main { public static void main(String[] args) { - Pojo pojo = new SimplePojo(); - // this is a direct method call on the 'pojo' reference pojo.foo(); } @@ -2731,13 +2722,11 @@ image::images/aop-proxy-call.png[] public class Main { public static void main(String[] args) { - ProxyFactory factory = new ProxyFactory(new SimplePojo()); factory.addInterface(Pojo.class); factory.addAdvice(new RetryAdvice()); Pojo pojo = (Pojo) factory.getProxy(); - // this is a method call on the proxy! pojo.foo(); } @@ -2745,23 +2734,22 @@ image::images/aop-proxy-call.png[] ---- ==== -The key thing to understand here is that the client code inside the `main(..)` method of the -`Main` class has a reference to the proxy. This means that method calls on that -object reference are calls on the proxy. As a result, the proxy can -delegate to all of the interceptors (advice) that are relevant to that particular method -call. However, once the call has finally reached the target object (the `SimplePojo`, -reference in this case), any method calls that it may make on itself, such as -`this.bar()` or `this.foo()`, are going to be invoked against the `this` reference, -and not the proxy. This has important implications. It means that self-invocation is -not going to result in the advice associated with a method invocation getting a -chance to execute. +The key thing to understand here is that the client code inside the `main(..)` method +of the `Main` class has a reference to the proxy. This means that method calls on that +object reference are calls on the proxy. As a result, the proxy can delegate to all of +the interceptors (advice) that are relevant to that particular method call. However, +once the call has finally reached the target object (the `SimplePojo`, reference in +this case), any method calls that it may make on itself, such as `this.bar()` or +`this.foo()`, are going to be invoked against the `this` reference, and not the proxy. +This has important implications. It means that self-invocation is not going to result +in the advice associated with a method invocation getting a chance to execute. -Okay, so what is to be done about this? The best approach (the term, "`best,`" is used loosely -here) is to refactor your code such that the self-invocation does not happen. +Okay, so what is to be done about this? The best approach (the term, "`best,`" is used +loosely here) is to refactor your code such that the self-invocation does not happen. This does entail some work on your part, but it is the best, least-invasive approach. -The next approach is absolutely horrendous, and we hesitate to point it out, -precisely because it is so horrendous. You can (painful as it is to us) totally tie the logic within -your class to Spring AOP, as the following example shows: +The next approach is absolutely horrendous, and we hesitate to point it out, precisely +because it is so horrendous. You can (painful as it is to us) totally tie the logic +within your class to Spring AOP, as the following example shows: ==== [source,java,indent=0] @@ -2793,14 +2781,12 @@ following example shows: public class Main { public static void main(String[] args) { - ProxyFactory factory = new ProxyFactory(new SimplePojo()); factory.adddInterface(Pojo.class); factory.addAdvice(new RetryAdvice()); factory.setExposeProxy(true); Pojo pojo = (Pojo) factory.getProxy(); - // this is a method call on the proxy! pojo.foo(); } @@ -2817,11 +2803,11 @@ it is not a proxy-based AOP framework. [[aop-aspectj-programmatic]] == Programmatic Creation of @AspectJ Proxies -In addition to declaring aspects in your configuration by using either `` or -``, it is also possible to programmatically create proxies that -advise target objects. For the full details of Spring's AOP API, see the <>. -Here, we want to focus on the ability to automatically create proxies by using @AspectJ -aspects. +In addition to declaring aspects in your configuration by using either `` +or ``, it is also possible to programmatically create proxies +that advise target objects. For the full details of Spring's AOP API, see the +<>. Here, we want to focus on the ability to automatically +create proxies by using @AspectJ aspects. You can use the `org.springframework.aop.aspectj.annotation.AspectJProxyFactory` class to create a proxy for a target object that is advised by one or more @AspectJ aspects. @@ -2939,13 +2925,12 @@ Spring now looks for a bean definition named `account` and uses that as the definition to configure new `Account` instances. You can also use autowiring to avoid having to specify a dedicated bean definition at -all. To have Spring apply autowiring, use the `autowire` property of the -`@Configurable` annotation. You can specify either `@Configurable(autowire=Autowire.BY_TYPE)` or +all. To have Spring apply autowiring, use the `autowire` property of the `@Configurable` +annotation. You can specify either `@Configurable(autowire=Autowire.BY_TYPE)` or `@Configurable(autowire=Autowire.BY_NAME` for autowiring by type or by name, -respectively. As an alternative, as of Spring 2.5, it is preferable to specify explicit, -annotation-driven dependency injection for your `@Configurable` beans by using -`@Autowired` or `@Inject` at the field or method level (see <> -for further details). +respectively. As an alternative, it is preferable to specify explicit, annotation-driven +dependency injection for your `@Configurable` beans through `@Autowired` or `@Inject` +at the field or method level (see <> for further details). Finally, you can enable Spring dependency checking for the object references in the newly created and configured object by using the `dependencyCheck` attribute (for example, @@ -2955,13 +2940,13 @@ are not primitives or collections) have been set. Note that using the annotation on its own does nothing. It is the `AnnotationBeanConfigurerAspect` in `spring-aspects.jar` that acts on the presence of -the annotation. In essence, the aspect says, "`after returning from the initialization of a -new object of a type annotated with `@Configurable`, configure the newly created object +the annotation. In essence, the aspect says, "`after returning from the initialization of +a new object of a type annotated with `@Configurable`, configure the newly created object using Spring in accordance with the properties of the annotation`". In this context, -"`initialization`" refers to newly instantiated objects (for example, objects instantiated with -the `new` operator) as well as to `Serializable` objects that are undergoing +"`initialization`" refers to newly instantiated objects (for example, objects instantiated +with the `new` operator) as well as to `Serializable` objects that are undergoing deserialization (for example, through -http://docs.oracle.com/javase/6/docs/api/java/io/Serializable.html[readResolve()]). +http://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html[readResolve()]). [NOTE] ===== @@ -2978,7 +2963,7 @@ available for use in the body of the constructors, you need to define this on th [source,java,indent=0] [subs="verbatim,quotes"] ---- - @Configurable(preConstruction=true) + @Configurable(preConstruction = true) ---- ==== @@ -3005,7 +2990,6 @@ use Java-based configuration, you can add `@EnableSpringConfigured` to any @Configuration @EnableSpringConfigured public class AppConfig { - } ---- ==== @@ -3143,7 +3127,6 @@ fully qualified class names: initialization(new(..)) && SystemArchitecture.inDomainModel() && this(beanInstance); - } ---- ==== @@ -3231,14 +3214,12 @@ per-`ClassLoader` basis, which is more fine-grained and which can make more sense in a 'single-JVM-multiple-application' environment (such as is found in a typical application server environment). -Further, <>, this support enables +Further, <>, this support enables load-time weaving without making any modifications to the application server's launch -script that is needed to add `-javaagent:path/to/aspectjweaver.jar` or (as we -describe later in this section) -`-javaagent:path/to/org.springframework.instrument-{version}.jar` (previously named -`spring-agent.jar`). Developers modify one or more files that form the -application context to enable load-time weaving instead of relying on administrators who -typically are in charge of the deployment configuration, such as the launch script. +script that is needed to add `-javaagent:path/to/aspectjweaver.jar` or (as we describe +later in this section) `-javaagent:path/to/spring-instrument.jar`. Developers configure +the application context to enable load-time weaving instead of relying on administrators +who typically are in charge of the deployment configuration, such as the launch script. Now that the sales pitch is over, let us first walk through a quick example of AspectJ LTW that uses Spring, followed by detailed specifics about elements introduced in the @@ -3250,18 +3231,18 @@ https://github.com/spring-projects/spring-petclinic[Petclinic sample application ==== A First Example Assume that you are an application developer who has been tasked with diagnosing -the cause of some performance problems in a system. Rather than break out a profiling -tool, we are going to switch on a simple profiling aspect that lets us -quickly get some performance metrics. We can then apply a finer-grained -profiling tool to that specific area immediately afterwards. +the cause of some performance problems in a system. Rather than break out a +profiling tool, we are going to switch on a simple profiling aspect that lets us +quickly get some performance metrics. We can then apply a finer-grained profiling +tool to that specific area immediately afterwards. -NOTE: The example presented here uses XML configuration. You can also -configure and use @AspectJ with <>. -Specifically, you can use the `@EnableLoadTimeWeaving` annotation as an alternative to -`` (see <> for details). +NOTE: The example presented here uses XML configuration. You can also configure and +use @AspectJ with <>. Specifically, you can use the +`@EnableLoadTimeWeaving` annotation as an alternative to `` +(see <> for details). -The following example shows the profiling aspect, which is not fancy -- it is a time-based -profiler that uses the @AspectJ-style of aspect declaration: +The following example shows the profiling aspect, which is not fancy. +It is a time-based profiler that uses the @AspectJ-style of aspect declaration: ==== [source,java,indent=0] @@ -3297,10 +3278,10 @@ profiler that uses the @AspectJ-style of aspect declaration: ---- ==== -We also need to create an `META-INF/aop.xml` file, to inform the AspectJ weaver -that we want to weave our `ProfilingAspect` into our classes. This file convention, -namely the presence of a file (or files) on the Java classpath called -`META-INF/aop.xml` is standard AspectJ. The following example shows the `aop.xml` file: +We also need to create an `META-INF/aop.xml` file, to inform the AspectJ weaver that +we want to weave our `ProfilingAspect` into our classes. This file convention, namely +the presence of a file (or files) on the Java classpath called `META-INF/aop.xml` is +standard AspectJ. The following example shows the `aop.xml` file: ==== [source,xml,indent=0] @@ -3323,12 +3304,13 @@ namely the presence of a file (or files) on the Java classpath called ---- ==== -Now we can move on to the Spring-specific portion of the configuration. We need to configure a -`LoadTimeWeaver` (explained later). This load-time -weaver is the essential component responsible for weaving the aspect configuration in -one or more `META-INF/aop.xml` files into the classes in your application. The good -thing is that it does not require a lot of configuration (there -are some more options that you can specify, but these are detailed later), as can be seen in the following example: +Now we can move on to the Spring-specific portion of the configuration. We need +to configure a `LoadTimeWeaver` (explained later). This load-time weaver is the +essential component responsible for weaving the aspect configuration in one or +more `META-INF/aop.xml` files into the classes in your application. The good +thing is that it does not require a lot of configuration (there are some more +options that you can specify, but these are detailed later), as can be seen in +the following example: ==== [source,xml,indent=0] @@ -3355,8 +3337,8 @@ are some more options that you can specify, but these are detailed later), as ca ==== Now that all the required artifacts (the aspect, the `META-INF/aop.xml` -file, and the Spring configuration) are in place, we can create the following driver class with a -`main(..)` method to demonstrate the LTW in action: +file, and the Spring configuration) are in place, we can create the following +driver class with a `main(..)` method to demonstrate the LTW in action: ==== [source,java,indent=0] @@ -3369,11 +3351,10 @@ file, and the Spring configuration) are in place, we can create the following dr public final class Main { public static void main(String[] args) { - ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml", Main.class); - EntitlementCalculationService entitlementCalculationService - = (EntitlementCalculationService) ctx.getBean("entitlementCalculationService"); + EntitlementCalculationService entitlementCalculationService = + (EntitlementCalculationService) ctx.getBean("entitlementCalculationService"); // the profiling aspect is 'woven' around this method execution entitlementCalculationService.calculateEntitlement(); @@ -3384,8 +3365,8 @@ file, and the Spring configuration) are in place, we can create the following dr We have one last thing to do. The introduction to this section did say that one could switch on LTW selectively on a per-`ClassLoader` basis with Spring, and this is true. -However, for this example, we use a Java agent (supplied with Spring) -to switch on the LTW. We use the following command to run the `Main` class shown earlier: +However, for this example, we use a Java agent (supplied with Spring) to switch on LTW. +We use the following command to run the `Main` class shown earlier: ==== [literal] @@ -3396,7 +3377,7 @@ java -javaagent:C:/projects/foo/lib/global/spring-instrument.jar foo.Main ==== The `-javaagent` is a flag for specifying and enabling -http://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html[agents +http://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html[agents to instrument programs that run on the JVM]. The Spring Framework ships with such an agent, the `InstrumentationSavingAgent`, which is packaged in the `spring-instrument.jar` that was supplied as the value of the `-javaagent` argument in @@ -3437,11 +3418,10 @@ result: public final class Main { public static void main(String[] args) { - new ClassPathXmlApplicationContext("beans.xml", Main.class); EntitlementCalculationService entitlementCalculationService = - new StubEntitlementCalculationService(); + new StubEntitlementCalculationService(); // the profiling aspect will be 'woven' around this method execution entitlementCalculationService.calculateEntitlement(); @@ -3479,8 +3459,9 @@ Furthermore, the compiled aspect classes need to be available on the classpath. The AspectJ LTW infrastructure is configured by using one or more `META-INF/aop.xml` files that are on the Java classpath (either directly or, more typically, in jar files). -The structure and contents of this file is detailed in the LTW part http://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html[AspectJ reference -documentation]. Because the aop.xml file is 100% AspectJ, we do not describe it further here. +The structure and contents of this file is detailed in the LTW part of the +http://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html[AspectJ reference +documentation]. Because the `aop.xml` file is 100% AspectJ, we do not describe it further here. [[aop-aj-ltw-libraries]] @@ -3489,10 +3470,10 @@ documentation]. Because the aop.xml file is 100% AspectJ, we do not describe it At minimum, you need the following libraries to use the Spring Framework's support for AspectJ LTW: -* `spring-aop.jar` (version 2.5 or later, plus all mandatory dependencies) -* `aspectjweaver.jar` (version 1.6.8 or later) +* `spring-aop.jar` +* `aspectjweaver.jar` -If you use the <>, you also need: * `spring-instrument.jar` @@ -3528,7 +3509,6 @@ which typically is done by using the `@EnableLoadTimeWeaving` annotation, as fol @Configuration @EnableLoadTimeWeaving public class AppConfig { - } ---- ==== @@ -3557,50 +3537,50 @@ Alternatively, if you prefer XML-based configuration, use the ---- ==== -The preceding configuration automatically defines and registers a number of LTW-specific infrastructure -beans, such as a `LoadTimeWeaver` and an `AspectJWeavingEnabler`, for you. +The preceding configuration automatically defines and registers a number of LTW-specific +infrastructure beans, such as a `LoadTimeWeaver` and an `AspectJWeavingEnabler`, for you. The default `LoadTimeWeaver` is the `DefaultContextLoadTimeWeaver` class, which attempts -to decorate an automatically detected `LoadTimeWeaver`. The exact type of -`LoadTimeWeaver` that is "`automatically detected`" is dependent upon your runtime -environment. The following table summarizes various `LoadTimeWeaver` implementations: +to decorate an automatically detected `LoadTimeWeaver`. The exact type of `LoadTimeWeaver` +that is "`automatically detected`" is dependent upon your runtime environment. +The following table summarizes various `LoadTimeWeaver` implementations: [[aop-aj-ltw-spring-env-impls]] .DefaultContextLoadTimeWeaver LoadTimeWeavers |=== | Runtime Environment| `LoadTimeWeaver` implementation -| Running in Oracle's - http://www.oracle.com/technetwork/middleware/weblogic/overview/index-085209.html[WebLogic] -| `WebLogicLoadTimeWeaver` - -| Running in Oracle's http://glassfish.dev.java.net/[GlassFish] -| `GlassFishLoadTimeWeaver` - | Running in http://tomcat.apache.org/[Apache Tomcat] | `TomcatLoadTimeWeaver` +| Running in http://glassfish.dev.java.net/[GlassFish] (limited to EAR deployments) +| `GlassFishLoadTimeWeaver` + | Running in Red Hat's http://www.jboss.org/jbossas/[JBoss AS] or http://www.wildfly.org/[WildFly] | `JBossLoadTimeWeaver` | Running in IBM's http://www-01.ibm.com/software/webservers/appserv/was/[WebSphere] | `WebSphereLoadTimeWeaver` -| JVM started with Spring `InstrumentationSavingAgent` (`java - -javaagent:path/to/spring-instrument.jar`) +| Running in Oracle's + http://www.oracle.com/technetwork/middleware/weblogic/overview/index-085209.html[WebLogic] +| `WebLogicLoadTimeWeaver` + +| JVM started with Spring `InstrumentationSavingAgent` + (`java -javaagent:path/to/spring-instrument.jar`) | `InstrumentationLoadTimeWeaver` -| Fallback, expecting the underlying ClassLoader to follow common conventions (for example - applicable to `TomcatInstrumentableClassLoader` and http://www.caucho.com/[Resin]) +| Fallback, expecting the underlying ClassLoader to follow common conventions + (namely `addTransformer` and optionally a `getThrowawayClassLoader` method) | `ReflectiveLoadTimeWeaver` |=== -Note that the table lists only the `LoadTimeWeavers` that are autodetected when you use the -`DefaultContextLoadTimeWeaver`. You can specify exactly which -`LoadTimeWeaver` implementation to use. +Note that the table lists only the `LoadTimeWeavers` that are autodetected when you +use the `DefaultContextLoadTimeWeaver`. You can specify exactly which `LoadTimeWeaver` +implementation to use. To specify a specific `LoadTimeWeaver` with Java configuration, implement the -`LoadTimeWeavingConfigurer` interface and override the `getLoadTimeWeaver()` method. The -following example specifies a `ReflectiveLoadTimeWeaver`: +`LoadTimeWeavingConfigurer` interface and override the `getLoadTimeWeaver()` method. +The following example specifies a `ReflectiveLoadTimeWeaver`: ==== [source,java,indent=0] @@ -3652,10 +3632,9 @@ the `org.aspectj.weaver.loadtime` package) class. See the class-level javadoc of `ClassPreProcessorAgentAdapter` class for further details, because the specifics of how the weaving is actually effected is beyond the scope of this document. -There is one final attribute of the configuration left to discuss: the -`aspectjWeaving` attribute (or `aspectj-weaving` if you use XML). This -attribute controls whether LTW is enabled or not. -It accepts one of three possible values, with the default value being +There is one final attribute of the configuration left to discuss: the `aspectjWeaving` +attribute (or `aspectj-weaving` if you use XML). This attribute controls whether LTW +is enabled or not. It accepts one of three possible values, with the default value being `autodetect` if the attribute is not present. The following table summarizes the three possible values: @@ -3686,71 +3665,17 @@ This last section contains any additional settings and configuration that you ne when you use Spring's LTW support in environments such as application servers and web containers. -[[aop-aj-ltw-environment-tomcat]] -===== Tomcat - -Historically, http://tomcat.apache.org/[Apache Tomcat]'s default class loader did not -support class transformation, which is why Spring provides an enhanced implementation -that addresses this need. Named `TomcatInstrumentableClassLoader`, the loader works on -Tomcat 6.0 and above. - -TIP: Do not define `TomcatInstrumentableClassLoader` on Tomcat 8.0 and higher. -Instead, let Spring automatically use Tomcat's new native `InstrumentableClassLoader` -facility through the `TomcatLoadTimeWeaver` strategy. - -If you still need to use `TomcatInstrumentableClassLoader`, you can register it -individually for each web application as follows: - -. Copy `org.springframework.instrument.tomcat.jar` into `$CATALINA_HOME/lib`, where - `$CATALINA_HOME` represents the root of the Tomcat installation -. Instruct Tomcat to use the custom class loader (instead of the default) by editing the - web application context file, as the following example shows: - -==== -[source,xml,indent=0] -[subs="verbatim,quotes"] ----- - - - ----- -==== - -Apache Tomcat 6.0+ supports several context locations: - -* Server configuration file: `$CATALINA_HOME/conf/server.xml` -* Default context configuration: `$CATALINA_HOME/conf/context.xml`, which affects all - deployed web applications -* A per-web application configuration, which can be deployed either on the server-side at - `$CATALINA_HOME/conf/[enginename]/[hostname]/[webapp]-context.xml` or embedded - inside the web-app archive at `META-INF/context.xml` +[[aop-aj-ltw-environments-tomcat-jboss-etc]] +===== Tomcat, JBoss, WebSphere, WebLogic -For efficiency, we recommend the embedded per-web application configuration style, because it -impacts only applications that use the custom class loader and does not require any -changes to the server configuration. See the Tomcat 6.0.x -http://tomcat.apache.org/tomcat-6.0-doc/config/context.html[documentation] for more -details about available context locations. +Tomcat, JBoss/WildFly, IBM WebSphere Application Server and Oracle WebLogic Server all +provide a general app `ClassLoader` that is capable of local instrumentation. Spring's +native LTW may leverage those ClassLoader implementations to provide AspectJ weaving. +You can simply enable load-time weaving, as <>. +Specifically, you do not need to modify the JVM launch script to add +`-javaagent:path/to/spring-instrument.jar`. -Alternatively, consider using the Spring-provided generic VM agent, to be specified -in Tomcat's launch script (described earlier in this section). This makes instrumentation available to all -deployed web applications, no matter the `ClassLoader` on which they happen to run. - -[[aop-aj-ltw-environments-weblogic-oc4j-resin-glassfish-jboss]] -===== WebLogic, WebSphere, Resin, GlassFish, and JBoss - -Recent versions of WebLogic Server (version 10 and above), IBM WebSphere Application -Server (version 7 and above), Resin (version 3.1 and above), and JBoss (version 6.x or above) provide a -`ClassLoader` that is capable of local instrumentation. Spring's native LTW leverages such -ClassLoader implementations to enable AspectJ weaving. You can enable LTW by activating -load-time weaving, as <>. Specifically, you do not need to modify the -launch script to add `-javaagent:path/to/spring-instrument.jar`. - -Note that the GlassFish instrumentation-capable `ClassLoader` is available only in its EAR -environment. For GlassFish web applications, follow the Tomcat setup instructions -<>. - -Note that, on JBoss 6.x, you need to disable the app server scanning to prevent it from +Note that on JBoss, you may need to disable the app server scanning to prevent it from loading the classes before the application actually starts. A quick workaround is to add to your artifact a file named `WEB-INF/jboss-scanning.xml` with the following content: @@ -3762,33 +3687,30 @@ to your artifact a file named `WEB-INF/jboss-scanning.xml` with the following co ---- ==== -[[aop-aj-ltw-environment-generic]] +[[aop-aj-ltw-environments-generic]] ===== Generic Java Applications -When class instrumentation is required in environments that do not support or are not -supported by the existing `LoadTimeWeaver` implementations, a JDK agent can be the only -solution. For such cases, Spring provides `InstrumentationLoadTimeWeaver`, which -requires a Spring-specific (but very general) VM agent, -`org.springframework.instrument-{version}.jar` (previously named `spring-agent.jar`). +When class instrumentation is required in environments that are not supported by +specific `LoadTimeWeaver` implementations, a JVM agent is the general solution. +For such cases, Spring provides `InstrumentationLoadTimeWeaver` which requires a +Spring-specific (but very general) JVM agent, `spring-instrument.jar`, autodetected +by common `@EnableLoadTimeWeaving` and `` setups. -To use it, you must start the virtual machine with the Spring agent by supplying the -following JVM options: +To use it, you must start the virtual machine with the Spring agent by supplying +the following JVM options: ==== [literal] [subs="verbatim,quotes"] ---- --javaagent:/path/to/org.springframework.instrument-{version}.jar +-javaagent:/path/to/spring-instrument.jar ---- ==== -Note that this requires modification of the VM launch script, which may prevent you from -using this in application server environments (depending on your operation policies). -Additionally, the JDK agent instruments the entire VM, which can be expensive. - -For performance reasons, we recommend that you use this configuration only if your target -environment (such as http://www.eclipse.org/jetty/[Jetty]) does not have (or does not -support) a dedicated LTW. +Note that this requires modification of the JVM launch script, which may prevent you +from using this in application server environments (depending on your server and your +operation policies). That said, for one-app-per-JVM deployments such as standalone +Spring Boot applications, you typically control the entire JVM setup in any case. From 216e4eeba4597a8df46428e7861afd9f1fcf3121 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 5 Mar 2019 13:08:34 +0100 Subject: [PATCH 5/6] General doc revision: configuration updates, consistent formatting etc --- src/docs/asciidoc/core.adoc | 16 +- src/docs/asciidoc/core/core-appendix.adoc | 142 ++-- src/docs/asciidoc/core/core-beans.adoc | 142 ++-- .../asciidoc/core/core-databuffer-codec.adoc | 7 +- src/docs/asciidoc/core/core-expressions.adoc | 31 +- src/docs/asciidoc/core/core-null-safety.adoc | 64 +- src/docs/asciidoc/core/core-resources.adoc | 8 +- src/docs/asciidoc/core/core-validation.adoc | 88 +- src/docs/asciidoc/data-access-appendix.adoc | 6 +- src/docs/asciidoc/data-access.adoc | 167 ++-- src/docs/asciidoc/index.adoc | 20 +- src/docs/asciidoc/integration-appendix.adoc | 8 +- src/docs/asciidoc/integration.adoc | 797 +++++++++--------- .../asciidoc/languages/dynamic-languages.adoc | 276 +++--- src/docs/asciidoc/languages/groovy.adoc | 2 +- src/docs/asciidoc/languages/kotlin.adoc | 145 ++-- src/docs/asciidoc/overview.adoc | 6 +- src/docs/asciidoc/testing-webtestclient.adoc | 27 +- src/docs/asciidoc/testing.adoc | 211 +++-- src/docs/asciidoc/web-reactive.adoc | 27 +- src/docs/asciidoc/web.adoc | 6 +- src/docs/asciidoc/web/integration.adoc | 89 +- src/docs/asciidoc/web/web-uris.adoc | 8 +- src/docs/asciidoc/web/webflux-cors.adoc | 14 +- src/docs/asciidoc/web/webflux-functional.adoc | 19 +- src/docs/asciidoc/web/webflux-view.adoc | 34 +- src/docs/asciidoc/web/webflux-webclient.adoc | 4 +- src/docs/asciidoc/web/webflux-websocket.adoc | 16 +- src/docs/asciidoc/web/webflux.adoc | 290 +++---- src/docs/asciidoc/web/webmvc-client.adoc | 6 +- src/docs/asciidoc/web/webmvc-cors.adoc | 18 +- src/docs/asciidoc/web/webmvc-test.adoc | 28 +- src/docs/asciidoc/web/webmvc-view.adoc | 44 +- src/docs/asciidoc/web/webmvc.adoc | 338 ++++---- src/docs/asciidoc/web/websocket.adoc | 75 +- 35 files changed, 1552 insertions(+), 1627 deletions(-) diff --git a/src/docs/asciidoc/core.adoc b/src/docs/asciidoc/core.adoc index cca7b745411..f2849ecbbfb 100644 --- a/src/docs/asciidoc/core.adoc +++ b/src/docs/asciidoc/core.adoc @@ -10,16 +10,16 @@ This part of the reference documentation covers all the technologies that are absolutely integral to the Spring Framework. -Foremost amongst these is the Spring Framework's Inversion of Control (IoC) container. A -thorough treatment of the Spring Framework's IoC container is closely followed by -comprehensive coverage of Spring's Aspect-Oriented Programming (AOP) technologies. The -Spring Framework has its own AOP framework, which is conceptually easy to understand -and which successfully addresses the 80% sweet spot of AOP requirements in Java -enterprise programming. +Foremost amongst these is the Spring Framework's Inversion of Control (IoC) container. +A thorough treatment of the Spring Framework's IoC container is closely followed by +comprehensive coverage of Spring's Aspect-Oriented Programming (AOP) technologies. +The Spring Framework has its own AOP framework, which is conceptually easy to +understand and which successfully addresses the 80% sweet spot of AOP requirements +in Java enterprise programming. Coverage of Spring's integration with AspectJ (currently the richest -- in terms of -features -- and certainly most mature AOP implementation in the Java enterprise space) is -also provided. +features -- and certainly most mature AOP implementation in the Java enterprise space) +is also provided. include::core/core-beans.adoc[leveloffset=+1] diff --git a/src/docs/asciidoc/core/core-appendix.adoc b/src/docs/asciidoc/core/core-appendix.adoc index f33484b9840..2909e4e9d0c 100644 --- a/src/docs/asciidoc/core/core-appendix.adoc +++ b/src/docs/asciidoc/core/core-appendix.adoc @@ -5,6 +5,7 @@ + [[xsd-schemas]] == XML Schemas @@ -38,7 +39,6 @@ correct schema so that the tags in the `util` namespace are available to you): ==== - [[xsd-schemas-util-constant]] ==== Using `` @@ -78,8 +78,6 @@ developer's intent ("`inject this constant value`"), and it reads better: ---- ==== - - [[xsd-schemas-util-frfb]] ===== Setting a Bean Property or Constructor Argument from a Field Value @@ -139,10 +137,9 @@ described in the API documentation for the class. Injecting enumeration values into beans as either property or constructor arguments is -easy to do in Spring. You do not actually have to do anything or know -anything about the Spring internals (or even about classes such as the -`FieldRetrievingFactoryBean`). The following example enumeration shows how easy injecting an -enum value is: +easy to do in Spring. You do not actually have to do anything or know anything about +the Spring internals (or even about classes such as the `FieldRetrievingFactoryBean`). +The following example enumeration shows how easy injecting an enum value is: ==== [source,java,indent=0] @@ -186,7 +183,6 @@ Now consider the following setter of type `PersistenceContextType` and the corre ==== - [[xsd-schemas-util-property-path]] ==== Using `` @@ -359,7 +355,6 @@ The following example uses a `util:properties` element to make a more concise re ==== - [[xsd-schemas-util-list]] ==== Using `` @@ -424,7 +419,6 @@ following configuration: If no `list-class` attribute is supplied, the container chooses a `List` implementation. - [[xsd-schemas-util-map]] ==== Using `` @@ -489,7 +483,6 @@ following configuration: If no `'map-class'` attribute is supplied, the container chooses a `Map` implementation. - [[xsd-schemas-util-set]] ==== Using `` @@ -612,69 +605,64 @@ available to you: ==== - [[xsd-schemas-context-pphc]] ==== Using `` This element activates the replacement of `${...}` placeholders, which are resolved against a -specified properties file (as a <>). This element is +specified properties file (as a <>). This element is a convenience mechanism that sets up a <> for you. If you need more control over the `PropertyPlaceholderConfigurer`, you can explicitly define one yourself. - [[xsd-schemas-context-ac]] ==== Using `` -This element activates the Spring infrastructure to detect annotations in bean -classes: +This element activates the Spring infrastructure to detect annotations in bean classes: -* Spring's <> and -<> -* JSR 250's `@PostConstruct`, -`@PreDestroy` and `@Resource` (if available) -* JPA's `@PersistenceContext` and -`@PersistenceUnit` (if available). +* Spring's <> model +* <> and `@Value` +* JSR-250's `@Resource`, `@PostConstruct` and `@PreDestroy` (if available) +* JPA's `@PersistenceContext` and `@PersistenceUnit` (if available) +* Spring's <> -Alternatively, you can choose to explicitly activate the -individual `BeanPostProcessors` for those annotations. +Alternatively, you can choose to explicitly activate the individual `BeanPostProcessors` +for those annotations. NOTE: This element does not activate processing of Spring's -<> annotation. You can use the -<`>> element for that purpose. - +<> annotation; +you can use the <`>> +element for that purpose. Similarly, Spring's +<> need to be explicitly +<> as well. [[xsd-schemas-context-component-scan]] ==== Using `` -This element is detailed in <>. - +This element is detailed in the section on <>. [[xsd-schemas-context-ltw]] ==== Using `` -This element is detailed in <>. - +This element is detailed in the section on <>. [[xsd-schemas-context-sc]] ==== Using `` -This element is detailed in <>. - +This element is detailed in the section on <>. [[xsd-schemas-context-mbe]] ==== Using `` -This element is detailed in <>. +This element is detailed in the section on <>. @@ -684,8 +672,8 @@ Configuring annotation based MBean export>>. Last but not least, we have the elements in the `beans` schema. These elements have been in Spring since the very dawn of the framework. Examples of the various elements in the `beans` schema are not shown here because they are quite comprehensively covered -in <> -(and, indeed, in that entire <>). +in <> +(and, indeed, in that entire <>). Note that you can add zero or more key-value pairs to `` XML definitions. What, if anything, is done with this extra metadata is totally up to your own custom @@ -716,9 +704,9 @@ as it stands). <1> This is the example `meta` element ==== -In the case of the preceding example, you could assume that there is some logic that -consumes the bean definition and sets up some caching infrastructure that uses the supplied -metadata. +In the case of the preceding example, you could assume that there is some logic that consumes +the bean definition and sets up some caching infrastructure that uses the supplied metadata. + @@ -738,11 +726,11 @@ Spring distribution, you should first read the appendix entitled <>. To create new XML configuration extensions: -. <> an XML schema to describe your custom element(s). -. <> a custom `NamespaceHandler` implementation. -. <> one or more `BeanDefinitionParser` implementations +. <> an XML schema to describe your custom element(s). +. <> a custom `NamespaceHandler` implementation. +. <> one or more `BeanDefinitionParser` implementations (this is where the real work is done). -. <> your new artifacts with Spring. +. <> your new artifacts with Spring. For a unified example, we create an XML extension (a custom XML element) that lets us configure objects of the type @@ -864,7 +852,7 @@ The `NamespaceHandler` interface features three methods: * `BeanDefinitionHolder decorate(Node, BeanDefinitionHolder, ParserContext)`: Called when Spring encounters an attribute or nested element of a different namespace. The decoration of one or more bean definitions is used (for example) with the - <>. + <>. We start by highlighting a simple example, without using decoration, after which we show decoration in a somewhat more advanced example. @@ -964,6 +952,7 @@ is the extraction and setting of the bean definition's unique identifier. [[xsd-custom-registration]] === Registering the Handler and the Schema + The coding is finished. All that remains to be done is to make the Spring XML parsing infrastructure aware of our custom element. We do so by registering our custom `namespaceHandler` and custom XSD file in two special-purpose properties files. These @@ -973,7 +962,6 @@ XML parsing infrastructure automatically picks up your new extension by consumin these special properties files, the formats of which are detailed in the next two sections. - [[xsd-custom-registration-spring-handlers]] ==== Writing `META-INF/spring.handlers` @@ -996,7 +984,6 @@ namespace extension and needs to exactly match exactly the value of the `targetN attribute, as specified in your custom XSD schema. - [[xsd-custom-registration-spring-schemas]] ==== Writing 'META-INF/spring.schemas' @@ -1067,7 +1054,6 @@ in a Spring XML configuration file: This section presents some more detailed examples of custom XML extensions. - [[xsd-custom-custom-nested]] ==== Nesting Custom Elements within Custom Elements @@ -1135,7 +1121,6 @@ The following listing shows the `Component` class: public void setName(String name) { this.name = name; } - } ---- ==== @@ -1183,16 +1168,15 @@ setter property for the `components` property. The following listing shows such public boolean isSingleton() { return true; } - } ---- ==== -This works nicely, but it exposes a lot of Spring plumbing to the -end user. What we are going to do is write a custom extension that hides away all of -this Spring plumbing. If we stick to <>, we start off by creating the XSD schema to define the structure of our -custom tag, as the following listing shows: +This works nicely, but it exposes a lot of Spring plumbing to the end user. What we are +going to do is write a custom extension that hides away all of this Spring plumbing. +If we stick to <>, we start off +by creating the XSD schema to define the structure of our custom tag, as the following +listing shows: ==== [source,xml,indent=0] @@ -1220,7 +1204,8 @@ custom tag, as the following listing shows: ---- ==== -Again following <>, we then create a custom `NamespaceHandler`: +Again following <>, +we then create a custom `NamespaceHandler`: ==== [source,java,indent=0] @@ -1235,14 +1220,13 @@ Again following <>, we th public void init() { registerBeanDefinitionParser("component", new ComponentBeanDefinitionParser()); } - } ---- ==== Next up is the custom `BeanDefinitionParser`. Remember that we are creating -`BeanDefinition` that describes a `ComponentFactoryBean`. The following listing shows our -custom `BeanDefinitionParser`: +a `BeanDefinition` that describes a `ComponentFactoryBean`. The following +listing shows our custom `BeanDefinitionParser` implementation: ==== [source,java,indent=0] @@ -1292,7 +1276,6 @@ custom `BeanDefinitionParser`: } factory.addPropertyValue("children", children); } - } ---- ==== @@ -1317,21 +1300,20 @@ http\://www.foo.com/schema/component/component.xsd=com/foo/component.xsd ==== - [[xsd-custom-custom-just-attributes]] ==== Custom Attributes on "`Normal`" Elements -Writing your own custom parser and the associated artifacts is not hard. However, it is sometimes -not the right thing to do. Consider a scenario where you need to add metadata to -already existing bean definitions. In this case, you certainly do not want to have to -write your own entire custom extension. Rather, you merely want to add an -additional attribute to the existing bean definition element. +Writing your own custom parser and the associated artifacts is not hard. However, +it is sometimes not the right thing to do. Consider a scenario where you need to +add metadata to already existing bean definitions. In this case, you certainly +do not want to have to write your own entire custom extension. Rather, you merely +want to add an additional attribute to the existing bean definition element. -By way of another example, suppose that you define a bean -definition for a service object that (unknown to it) accesses a clustered -http://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the named -JCache instance is eagerly started within the surrounding cluster. The following -listing shows such a definition: +By way of another example, suppose that you define a bean definition for a +service object that (unknown to it) accesses a clustered +http://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the +named JCache instance is eagerly started within the surrounding cluster. +The following listing shows such a definition: ==== [source,xml,indent=0] @@ -1367,13 +1349,12 @@ JCache-initializing `BeanDefinition`. The following listing shows our `JCacheIni public void initialize() { // lots of JCache API calls to initialize the named cache... } - } ---- ==== -Now we can move onto the custom extension. First, we need to author the XSD schema that describes the -custom attribute, as follows: +Now we can move onto the custom extension. First, we need to author +the XSD schema that describes the custom attribute, as follows: ==== [source,xml,indent=0] @@ -1413,9 +1394,9 @@ Next, we need to create the associated `NamespaceHandler`, as follows: ---- ==== -Next, we need to create the parser. Note that, in this case, because we are going to parse an XML -attribute, we write a `BeanDefinitionDecorator` rather than a `BeanDefinitionParser`. -The following listing shows our `BeanDefinitionDecorator`: +Next, we need to create the parser. Note that, in this case, because we are going to parse +an XML attribute, we write a `BeanDefinitionDecorator` rather than a `BeanDefinitionParser`. +The following listing shows our `BeanDefinitionDecorator` implementation: ==== [source,java,indent=0] @@ -1470,7 +1451,6 @@ The following listing shows our `BeanDefinitionDecorator`: } return beanName; } - } ---- ==== diff --git a/src/docs/asciidoc/core/core-beans.adoc b/src/docs/asciidoc/core/core-beans.adoc index dfcc1676c4a..728b1c47d01 100644 --- a/src/docs/asciidoc/core/core-beans.adoc +++ b/src/docs/asciidoc/core/core-beans.adoc @@ -104,13 +104,13 @@ Spring IoC container. NOTE: XML-based metadata is not the only allowed form of configuration metadata. The Spring IoC container itself is totally decoupled from the format in which this configuration metadata is actually written. These days, many developers choose -<> for their Spring applications. +<> for their Spring applications. For information about using other forms of metadata with the Spring container, see: * <>: Spring 2.5 introduced support for annotation-based configuration metadata. -* <>: Starting with Spring 3.0, many features +* <>: Starting with Spring 3.0, many features provided by the Spring JavaConfig project became part of the core Spring Framework. Thus, you can define beans external to your application classes by using Java rather than XML files. To use these new features, see the @@ -265,7 +265,7 @@ XML configuration file represents a logical layer or module in your architecture You can use the application context constructor to load bean definitions from all these XML fragments. This constructor takes multiple `Resource` locations, as was shown in the -<>. Alternatively, use one or more +<>. Alternatively, use one or more occurrences of the `` element to load bean definitions from another file or files. The following example shows how to do so: @@ -1024,8 +1024,8 @@ example shows: Keep in mind that, to make this work out of the box, your code must be compiled with the debug flag enabled so that Spring can look up the parameter name from the constructor. -If you cannot or do not want to compile your code with the debug flag, you can use -http://download.oracle.com/javase/6/docs/api/java/beans/ConstructorProperties.html[@ConstructorProperties] +If you cannot or do not want to compile your code with the debug flag, you can use the +http://download.oracle.com/javase/8/docs/api/java/beans/ConstructorProperties.html[@ConstructorProperties] JDK annotation to explicitly name your constructor arguments. The sample class would then have to look as follows: @@ -1096,7 +1096,7 @@ load an entire Spring IoC container instance. **** Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods -for optional dependencies. Note that use of the <> +for optional dependencies. Note that use of the <> annotation on a setter method can be used to make the property be a required dependency; however, constructor injection with programmatic validation of arguments is preferable. @@ -1189,7 +1189,7 @@ to being injected into the dependent bean. This means that, if bean A has a depe bean B, the Spring IoC container completely configures bean B prior to invoking the setter method on bean A. In other words, the bean is instantiated (if it is not a pre-instantiated singleton), its dependencies are set, and the relevant lifecycle -methods (such as a <> +methods (such as a <> or the <>) are invoked. @@ -1358,7 +1358,7 @@ do not discuss those details here. [[beans-factory-properties-detailed]] === Dependencies and Configuration in Detail -As mentioned in the <>, you can define bean +As mentioned in the <>, you can define bean properties and constructor arguments as references to other managed beans (collaborators) or as values defined inline. Spring's XML-based configuration metadata supports sub-element types within its `` and `` elements for this @@ -2195,11 +2195,11 @@ In the latter scenario, you have several options: * Abandon autowiring in favor of explicit wiring. * Avoid autowiring for a bean definition by setting its `autowire-candidate` attributes - to `false`, as described in the <>. + to `false`, as described in the <>. * Designate a single bean definition as the primary candidate by setting the `primary` attribute of its `` element to `true`. -* Implement the more fine-grained control available - with annotation-based configuration, as described in <>. +* Implement the more fine-grained control available with annotation-based configuration, + as described in <>. @@ -2304,7 +2304,7 @@ https://spring.io/blog/2004/08/06/method-injection/[this blog entry]. Lookup method injection is the ability of the container to override methods on container-managed beans and return the lookup result for another named bean in the container. The lookup typically involves a prototype bean, as in the scenario described -in <>. The Spring Framework +in <>. The Spring Framework implements this method injection by using bytecode generation from the CGLIB library to dynamically generate a subclass that overrides the method. @@ -3524,7 +3524,7 @@ configured with a different method name, then each configured method is executed order listed after this note. However, if the same method name is configured -- for example, `init()` for an initialization method -- for more than one of these lifecycle mechanisms, that method is executed once, as explained in the -<>. +<>. Multiple lifecycle mechanisms configured for the same bean, with different initialization methods, are called as follows: @@ -3789,7 +3789,7 @@ init-method. [[aware-list]] === Other `Aware` Interfaces -Besides `ApplicationContextAware` and `BeanNameAware` (discussed <>), +Besides `ApplicationContextAware` and `BeanNameAware` (discussed <>), Spring offers a wide range of `Aware` callback interfaces that let beans indicate to the container that they require a certain infrastructure dependency. As a general rule, the name indicates the dependency type. The following table summarizes the most important `Aware` interfaces: @@ -4459,7 +4459,7 @@ while others argue that annotated classes are no longer POJOs and, furthermore, configuration becomes decentralized and harder to control. No matter the choice, Spring can accommodate both styles and even mix them together. -It is worth pointing out that through its <> option, Spring lets +It is worth pointing out that through its <> option, Spring lets annotations be used in a non-invasive way, without touching the target components source code and that, in terms of tooling, all configuration styles are supported by the https://spring.io/tools/sts[Spring Tool Suite]. @@ -4864,7 +4864,7 @@ an `ApplicationContext` object: [NOTE] ==== -The `@Autowired`, `@Inject`, `@Resource`, and `@Value` annotations are handled by Spring +The `@Autowired`, `@Inject`, `@Value`, and `@Resource` annotations are handled by Spring `BeanPostProcessor` implementations. This means that you cannot apply these annotations within your own `BeanPostProcessor` or `BeanFactoryPostProcessor` types (if any). These types must be 'wired up' explicitly by using XML or a Spring `@Bean` method. @@ -5648,9 +5648,9 @@ supported as a marker for automatic exception translation in your persistence la === Using Meta-annotations and Composed Annotations Many of the annotations provided by Spring can be used as meta-annotations in your -own code. A meta-annotation is an annotation that can be applied to another -annotation. For example, the `@Service` annotation mentioned <> is meta-annotated with -`@Component`, as the following example shows: +own code. A meta-annotation is an annotation that can be applied to another annotation. +For example, the `@Service` annotation mentioned <> +is meta-annotated with `@Component`, as the following example shows: ==== [source,java,indent=0] @@ -5814,16 +5814,16 @@ TIP: The use of `` implicitly enables the functionality ==== The scanning of classpath packages requires the presence of corresponding directory entries in the classpath. When you build JARs with Ant, make sure that you do not -activate the files-only switch of the JAR task. Also, classpath directories may not -be exposed based on security policies in some environments -- for example, standalone apps on +activate the files-only switch of the JAR task. Also, classpath directories may not be +exposed based on security policies in some environments -- for example, standalone apps on JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests -- see http://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources). On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected. However, make sure that your component classes are exported in your `module-info` descriptors. If you expect Spring to invoke non-public members of your classes, make -sure that they are 'opened' (that is, that they use an `opens` declaration instead of an `exports` -declaration in your `module-info` descriptor). +sure that they are 'opened' (that is, that they use an `opens` declaration instead of an +`exports` declaration in your `module-info` descriptor). ==== Furthermore, the `AutowiredAnnotationBeanPostProcessor` and @@ -6855,7 +6855,7 @@ following example shows: ---- ==== -NOTE: Remember that `@Configuration` classes are <> +NOTE: Remember that `@Configuration` classes are <> with `@Component`, so they are candidates for component-scanning. In the preceding example, assuming that `AppConfig` is declared within the `com.acme` package (or any package underneath), it is picked up during the call to `scan()`. Upon `refresh()`, all its `@Bean` @@ -6935,8 +6935,8 @@ init-param): `@Bean` is a method-level annotation and a direct analog of the XML `` element. The annotation supports some of the attributes offered by ``, such as: -* <> -* <> +* <> +* <> * <> * `name`. @@ -7048,7 +7048,7 @@ parameter, as the following example shows: ==== The resolution mechanism is pretty much identical to constructor-based dependency -injection. See <> for more details. +injection. See <> for more details. [[beans-java-lifecycle-callbacks]] @@ -7056,17 +7056,17 @@ injection. See <> for more det Any classes defined with the `@Bean` annotation support the regular lifecycle callbacks and can use the `@PostConstruct` and `@PreDestroy` annotations from JSR-250. See -<> for further +<> for further details. -The regular Spring <> callbacks are fully supported as +The regular Spring <> callbacks are fully supported as well. If a bean implements `InitializingBean`, `DisposableBean`, or `Lifecycle`, their respective methods are called by the container. -The standard set of `*Aware` interfaces (such as <>, -<>, -<>, -<>, and so on) are also fully supported. +The standard set of `*Aware` interfaces (such as <>, +<>, +<>, +<>, and so on) are also fully supported. The `@Bean` annotation supports specifying arbitrary initialization and destruction callback methods, much like Spring XML's `init-method` and `destroy-method` attributes @@ -7176,7 +7176,7 @@ Spring includes the `@Scope` annotation so that you can specify the scope of a b You can specify that your beans defined with the `@Bean` annotation should have a specific scope. You can use any of the standard scopes specified in the -<> section. +<> section. The default scope is `singleton`, but you can override this with the `@Scope` annotation, as the following example shows: @@ -7201,14 +7201,15 @@ as the following example shows: ===== `@Scope` and `scoped-proxy` Spring offers a convenient way of working with scoped dependencies through -<>. The easiest way to create such -a proxy when using the XML configuration is the `` element. -Configuring your beans in Java with a `@Scope` annotation offers equivalent support with -the `proxyMode` attribute. The default is no proxy (`ScopedProxyMode.NO`), but you can -specify `ScopedProxyMode.TARGET_CLASS` or `ScopedProxyMode.INTERFACES`. +<>. The easiest way to create +such a proxy when using the XML configuration is the `` element. +Configuring your beans in Java with a `@Scope` annotation offers equivalent support +with the `proxyMode` attribute. The default is no proxy (`ScopedProxyMode.NO`), +but you can specify `ScopedProxyMode.TARGET_CLASS` or `ScopedProxyMode.INTERFACES`. If you port the scoped proxy example from the XML reference documentation (see -<>) to our `@Bean` using Java, it resembles the following: +<>) to our `@Bean` using Java, +it resembles the following: ==== [source,java,indent=0] @@ -7354,7 +7355,7 @@ by using plain `@Component` classes. [[beans-java-method-injection]] ==== Lookup Method Injection -As noted earlier, <> is an +As noted earlier, <> is an advanced feature that you should use rarely. It is useful in cases where a singleton-scoped bean has a dependency on a prototype-scoped bean. Using Java for this type of configuration provides a natural means for implementing this pattern. The @@ -7552,7 +7553,7 @@ issue, because no compiler is involved, and you can declare When using `@Configuration` classes, the Java compiler places constraints on the configuration model, in that references to other beans must be valid Java syntax. -Fortunately, solving this problem is simple. As <>, +Fortunately, solving this problem is simple. As <>, a `@Bean` method can have an arbitrary number of parameters that describe the bean dependencies. Consider the following more real-world scenario with several `@Configuration` classes, each depending on beans declared in the others: @@ -8030,8 +8031,8 @@ jdbc.password= The {api-spring-framework}/core/env/Environment.html[`Environment`] interface is an abstraction integrated in the container that models two key -aspects of the application environment: <> -and <>. +aspects of the application environment: <> +and <>. A profile is a named, logical group of bean definitions to be registered with the container only if the given profile is active. Beans may be assigned to a profile @@ -8174,7 +8175,7 @@ NOTE: You cannot mix the `&` and `|` operators without using parentheses. For ex `production & us-east | eu-central` is not a valid expression. It must be expressed as `production & (us-east | eu-central)`. -You can use `@Profile` as a <> for the purpose +You can use `@Profile` as a <> for the purpose of creating a custom composed annotation. The following example defines a custom `@Production` annotation that you can use as a drop-in replacement for `@Profile("production")`: @@ -8382,9 +8383,9 @@ In addition, you can also declaratively activate profiles through the `spring.profiles.active` property, which may be specified through system environment variables, JVM system properties, servlet context parameters in `web.xml`, or even as an entry in JNDI (see <>). In integration tests, active -profiles can be declared by using the `@ActiveProfiles` annotation in the `spring-test` module -(see <>). +profiles can be declared by using the `@ActiveProfiles` annotation in the `spring-test` +module (see <>). Note that profiles are not an "`either-or`" proposition. You can activate multiple profiles at once. Programmatically, you can provide multiple profile names to the @@ -8656,9 +8657,10 @@ Alternatively, for XML configuration, you can use the `context:load-time-weaver` Once configured for the `ApplicationContext`, any bean within that `ApplicationContext` may implement `LoadTimeWeaverAware`, thereby receiving a reference to the load-time weaver instance. This is particularly useful in combination with -<> where load-time weaving may be necessary -for JPA class transformation. -Consult the {api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`] +<> where load-time weaving may be +necessary for JPA class transformation. +Consult the +{api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`] javadoc for more detail. For more on AspectJ load-time weaving, see <>. @@ -8667,7 +8669,7 @@ javadoc for more detail. For more on AspectJ load-time weaving, see <>, the `org.springframework.beans.factory` +As discussed in the <>, the `org.springframework.beans.factory` package provides basic functionality for managing and manipulating beans, including in a programmatic way. The `org.springframework.context` package adds the {api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`] @@ -8919,7 +8921,7 @@ class and the `ApplicationListener` interface. If a bean that implements the Essentially, this is the standard Observer design pattern. TIP: As of Spring 4.2, the event infrastructure has been significantly improved and offers -an <> as well as the +an <> as well as the ability to publish any arbitrary event (that is, an object that does not necessarily extend from `ApplicationEvent`). When such an object is published, we wrap it in an event for you. @@ -9149,12 +9151,12 @@ following example shows how to do so: ---- ==== -It is also possible to add additional runtime filtering by using the `condition` attribute of the -annotation that defines a <> , which should match to actually -invoke the method for a particular event. +It is also possible to add additional runtime filtering by using the `condition` attribute +of the annotation that defines a <> , which should match +to actually invoke the method for a particular event. -The following example shows how our notifier can be rewritten to be invoked only if the `content` attribute -of the event is equal to `my-event`: +The following example shows how our notifier can be rewritten to be invoked only if the +`content` attribute of the event is equal to `my-event`: ==== [source,java,indent=0] @@ -9211,8 +9213,8 @@ method signature to return the event that should be published, as the following ---- ==== -NOTE: This feature is not supported for <>. +NOTE: This feature is not supported for +<>. This new method publishes a new `ListUpdateEvent` for every `BlackListEvent` handled by the method above. If you need to publish several events, you can return a `Collection` of events @@ -9223,8 +9225,8 @@ instead. ==== Asynchronous Listeners If you want a particular listener to process events asynchronously, you can reuse the -<>. The -following example shows how to do so: +<>. +The following example shows how to do so: ==== [source,java,indent=0] @@ -9243,8 +9245,9 @@ Be aware of the following limitations when using asynchronous events: * If the event listener throws an `Exception`, it is not propagated to the caller See `AsyncUncaughtExceptionHandler` for more details. * Such event listener cannot send replies. If you need to send another event as the - result of the processing, inject {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`ApplicationEventPublisher`] to send the event - manually. + result of the processing, inject + {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`ApplicationEventPublisher`] + to send the event manually. [[context-functionality-events-order]] @@ -9320,9 +9323,8 @@ an event. [[context-functionality-resources]] === Convenient Access to Low-level Resources -For optimal usage and understanding of application contexts, you should -familiarize yourself with Spring's `Resource` abstraction, as described in -<>. +For optimal usage and understanding of application contexts, you should familiarize +yourself with Spring's `Resource` abstraction, as described in <>. An application context is a `ResourceLoader`, which can be used to load `Resource` objects. A `Resource` is essentially a more feature rich version of the JDK `java.net.URL` class. @@ -9478,11 +9480,11 @@ by convention (that is, by bean name or by bean type -- in particular, post-proc while a plain `DefaultListableBeanFactory` is agnostic about any special beans. For many extended container features, such as annotation processing and AOP proxying, -the <> is essential. +the <> is essential. If you use only a plain `DefaultListableBeanFactory`, such post-processors do not get detected and activated by default. This situation could be confusing, because -nothing is actually wrong with your bean configuration. Rather, in such a scenario, the -container needs to be fully bootstrapped through additional setup. +nothing is actually wrong with your bean configuration. Rather, in such a scenario, +the container needs to be fully bootstrapped through additional setup. The following table lists features provided by the `BeanFactory` and `ApplicationContext` interfaces and implementations. diff --git a/src/docs/asciidoc/core/core-databuffer-codec.adoc b/src/docs/asciidoc/core/core-databuffer-codec.adoc index e23c07ebfdd..0084ee74425 100644 --- a/src/docs/asciidoc/core/core-databuffer-codec.adoc +++ b/src/docs/asciidoc/core/core-databuffer-codec.adoc @@ -10,7 +10,7 @@ APIs as follows: * <> abstracts the creation of a data buffer. * <> represents a byte buffer, which may be -<>. +<>. * <> offers utility methods for data buffers. * <> decode or encode streams data buffer streams into higher level objects. @@ -93,7 +93,6 @@ composite buffers, if that's supported by the underlying byte buffer API. - [[codecs]] == Codecs @@ -105,7 +104,7 @@ The `org.springframework.core.codec` package provides the following strategy int The `spring-core` module provides `byte[]`, `ByteBuffer`, `DataBuffer`, `Resource`, and `String` encoder and decoder implementations. The `spring-web` module adds Jackson JSON, Jackson Smile, JAXB2, Protocol Buffers and other encoders and decoders. See -<> in the WebFlux section. +<> in the WebFlux section. @@ -114,7 +113,7 @@ Jackson Smile, JAXB2, Protocol Buffers and other encoders and decoders. See == Using `DataBuffer` When working with data buffers, special care must be taken to ensure buffers are released -since they may be <>. We'll use codecs to illustrate +since they may be <>. We'll use codecs to illustrate how that works but the concepts apply more generally. Let's see what codecs must do internally to manage data buffers. diff --git a/src/docs/asciidoc/core/core-expressions.adoc b/src/docs/asciidoc/core/core-expressions.adoc index e420a02c738..bda06427683 100644 --- a/src/docs/asciidoc/core/core-expressions.adoc +++ b/src/docs/asciidoc/core/core-expressions.adoc @@ -10,8 +10,8 @@ While there are several other Java expression languages available -- OGNL, MVEL, EL, to name a few -- the Spring Expression Language was created to provide the Spring community with a single well supported expression language that can be used across all the products in the Spring portfolio. Its language features are driven by the -requirements of the projects in the Spring portfolio, including tooling requirements for -code completion support within the Eclipse-based Spring Tool Suite. That said, +requirements of the projects in the Spring portfolio, including tooling requirements +for code completion support within the Eclipse-based Spring Tool Suite. That said, SpEL is based on a technology-agnostic API that lets other expression language implementations be integrated, should the need arise. @@ -20,14 +20,14 @@ portfolio, it is not directly tied to Spring and can be used independently. To be self contained, many of the examples in this chapter use SpEL as if it were an independent expression language. This requires creating a few bootstrapping infrastructure classes, such as the parser. Most Spring users need not deal with -this infrastructure and can, instead, author only expression strings for evaluation. An -example of this typical use is the integration of SpEL into creating XML or annotation-based -bean definitions, as shown in <>. +this infrastructure and can, instead, author only expression strings for evaluation. +An example of this typical use is the integration of SpEL into creating XML or +annotation-based bean definitions, as shown in +<>. This chapter covers the features of the expression language, its API, and its language -syntax. In several places, `Inventor` and `Society` classes are used as the -target objects for expression evaluation. These class declarations and the data used to +syntax. In several places, `Inventor` and `Society` classes are used as the target +objects for expression evaluation. These class declarations and the data used to populate them are listed at the end of the chapter. The expression language supports the following functionality: @@ -60,7 +60,7 @@ The expression language supports the following functionality: This section introduces the simple use of SpEL interfaces and its expression language. The complete language reference can be found in -<>. +<>. The following code introduces the SpEL API to evaluate the literal string expression, `Hello World`. @@ -332,13 +332,14 @@ interpreter and only 3ms using the compiled version of the expression. [[expressions-compiler-configuration]] ==== Compiler Configuration -The compiler is not turned on by default, but you can turn it on in either of two different ways. -You can turn it on by using the parser configuration process (<>) -or by using a system property when SpEL usage is embedded inside another component. This section +The compiler is not turned on by default, but you can turn it on in either of two +different ways. You can turn it on by using the parser configuration process +(<>) or by using a system +property when SpEL usage is embedded inside another component. This section discusses both of these options. -The compiler can operate in one of three modes, which are captured -in the `org.springframework.expression.spel.SpelCompilerMode` enum. The modes are as follows: +The compiler can operate in one of three modes, which are captured in the +`org.springframework.expression.spel.SpelCompilerMode` enum. The modes are as follows: * `OFF` (default): The compiler is switched off. * `IMMEDIATE`: In immediate mode, the expressions are compiled as soon as possible. This @@ -641,7 +642,7 @@ By default, real numbers are parsed by using Double.parseDouble(). Navigating with property references is easy. To do so, use a period to indicate a nested property value. The instances of the `Inventor` class, `pupin` and `tesla`, were populated with -data listed in the <> section. +data listed in the <> section. To navigate "`down`" and get Tesla's year of birth and Pupin's city of birth, we use the following expressions: diff --git a/src/docs/asciidoc/core/core-null-safety.adoc b/src/docs/asciidoc/core/core-null-safety.adoc index 95b7ed82be3..07044b68503 100644 --- a/src/docs/asciidoc/core/core-null-safety.adoc +++ b/src/docs/asciidoc/core/core-null-safety.adoc @@ -1,29 +1,31 @@ -[[null-safety]] +[-[null-safety]] = Null-safety -Although Java does not let you express null-safety with its type system, Spring Framework -now provides the following annotations in the `org.springframework.lang` package to let you declare -nullability of APIs and fields: +Although Java does not let you express null-safety with its type system, the Spring Framework +now provides the following annotations in the `org.springframework.lang` package to let you +declare nullability of APIs and fields: -* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific parameter, -return value, or field cannot be `null` (not needed on parameter and return value -where `@NonNullApi` and `@NonNullFields` apply) . -* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a specific -parameter, return value, or field can be `null`. +* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a +specific parameter, return value, or field can be `null`. +* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific +parameter, return value, or field cannot be `null` (not needed on parameters / return values +and fields where `@NonNullApi` and `@NonNullFields` apply, respectively). * {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level -that declares non-null as the default behavior for parameters and return values. +that declares non-null as the default semantics for parameters and return values. * {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package -level that declares non-null as the default behavior for fields. +level that declares non-null as the default semantics for fields. -Spring Framework leverages itself these annotations, but they can also be used in any Spring based -Java project to declare null-safe APIs and optionally null-safe fields. Generic type arguments, -varargs and array elements nullability are not supported yet, but should be in an upcoming -release, see https://jira.spring.io/browse/SPR-15942[SPR-15942] for up-to-date information. -Nullability declaration are expected to be fine-tuned between Spring Framework release, -including minor ones. Nullability of types used inside method bodies is outside of the -scope of this feature. +The Spring Framework itself leverages these annotations, but they can also be used in any +Spring-based Java project to declare null-safe APIs and optionally null-safe fields. +Generic type arguments, varargs and array elements nullability are not supported yet but +should be in an upcoming release, see https://jira.spring.io/browse/SPR-15942[SPR-15942] +for up-to-date information. Nullability declarations are expected to be fine-tuned between +Spring Framework releases, including minor ones. Nullability of types used inside method +bodies is outside of the scope of this feature. -NOTE: Libraries like Reactor or Spring Data provide null-safe APIs that use this feature. +NOTE: Other common libraries such as Reactor and Spring Data provide null-safe APIs that +use a similar nullability arrangement, delivering a consistent overall experience for +Spring application developers. @@ -32,25 +34,23 @@ NOTE: Libraries like Reactor or Spring Data provide null-safe APIs that use this In addition to providing an explicit declaration for Spring Framework API nullability, these annotations can be used by an IDE (such as IDEA or Eclipse) to provide useful -warnings related to null-safety in order to avoid `NullPointerException` -at runtime. +warnings related to null-safety in order to avoid `NullPointerException` at runtime. They are also used to make Spring API null-safe in Kotlin projects, since Kotlin natively supports https://kotlinlang.org/docs/reference/null-safety.html[null-safety]. More details -are available in the <>. +are available in the <>. -== JSR 305 meta-annotations +== JSR-305 meta-annotations Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305] -annotations (a dormant but widely spread JSR). JSR 305 meta-annotations let tooling vendors -like IDEA or Kotlin provide null-safety support in a generic way, without having to hard-code -support for Spring annotations. - -It is not necessary nor recommended to add JSR 305 dependency in the project classpath to -take advantage of Spring null-safe API. Only projects such as -Spring-based libraries that use null-safety annotations in their codebase should add -`com.google.code.findbugs:jsr305:3.0.2` with `compileOnly` Gradle configuration or Maven -`provided` scope to avoid compile warnings. +annotations (a dormant but wide-spread JSR). JSR-305 meta-annotations let tooling vendors +like IDEA or Kotlin provide null-safety support in a generic way, without having to +hard-code support for Spring annotations. + +It is not necessary nor recommended to add a JSR-305 dependency to the project classpath to +take advantage of Spring null-safe API. Only projects such as Spring-based libraries that use +null-safety annotations in their codebase should add `com.google.code.findbugs:jsr305:3.0.2` +with `compileOnly` Gradle configuration or Maven `provided` scope to avoid compile warnings. diff --git a/src/docs/asciidoc/core/core-resources.adoc b/src/docs/asciidoc/core/core-resources.adoc index 4d5c651aa7a..4c9fcc1dbe1 100644 --- a/src/docs/asciidoc/core/core-resources.adoc +++ b/src/docs/asciidoc/core/core-resources.adoc @@ -351,10 +351,10 @@ interface if that is all you need. The code would be coupled only to the resourc interface (which can be considered a utility interface) and not to the whole Spring `ApplicationContext` interface. -As of Spring 2.5, you can rely upon autowiring of the `ResourceLoader` as an alternative -to implementing the `ResourceLoaderAware` interface. The "`traditional`" `constructor` and -`byType` autowiring modes (as described in <>) are now capable of -providing a dependency of type `ResourceLoader` for either a constructor argument or a +In application components, you may also rely upon autowiring of the `ResourceLoader` as +an alternative to implementing the `ResourceLoaderAware` interface. The "`traditional`" +`constructor` and `byType` autowiring modes (as described in <>) +are capable of providing a `ResourceLoader` for either a constructor argument or a setter method parameter, respectively. For more flexibility (including the ability to autowire fields and multiple parameter methods), consider using the annotation-based autowiring features. In that case, the `ResourceLoader` is autowired into a field, diff --git a/src/docs/asciidoc/core/core-validation.adoc b/src/docs/asciidoc/core/core-validation.adoc index 05bb896d470..8b749accf2e 100644 --- a/src/docs/asciidoc/core/core-validation.adoc +++ b/src/docs/asciidoc/core/core-validation.adoc @@ -20,18 +20,19 @@ directly. Because this is reference documentation, however, we felt that some ex might be in order. We explain the `BeanWrapper` in this chapter, since, if you are going to use it at all, you are most likely do so when trying to bind data to objects. -Spring's `DataBinder` and the lower-level `BeanWrapper` both use `PropertyEditorSupport` implementations to parse -and format property values. The `PropertyEditor` and `PropertyEditorSupport` interfaces are part of the JavaBeans -specification and are also explained in this chapter. Spring 3 introduced a -`core.convert` package that provides a general type conversion facility, as well as a -higher-level "`format`" package for formatting UI field values. You can use these packages -as simpler alternatives to `PropertyEditorSupport` implementations. They are also discussed in this -chapter. +Spring's `DataBinder` and the lower-level `BeanWrapper` both use `PropertyEditorSupport` +implementations to parse and format property values. The `PropertyEditor` and +`PropertyEditorSupport` types are part of the JavaBeans specification and are also +explained in this chapter. Spring 3 introduced a `core.convert` package that provides a +general type conversion facility, as well as a higher-level "`format`" package for +formatting UI field values. You can use these packages as simpler alternatives to +`PropertyEditorSupport` implementations. They are also discussed in this chapter. .JSR-303/JSR-349 Bean Validation **** -As of version 4.0, Spring Framework supports Bean Validation 1.0 (JSR-303) and Bean Validation 1.1 -(JSR-349) for setup support and adapting them to Spring's `Validator` interface. +As of version 4.0, Spring Framework supports Bean Validation 1.0 (JSR-303) and +Bean Validation 1.1 (JSR-349) for setup support and adapting them to Spring's +`Validator` interface. An application can choose to enable Bean Validation once globally, as described in <>, and use it exclusively for all validation needs. @@ -173,22 +174,21 @@ methods it offers can be found in the {api-spring-framework}validation/Errors.ht [[validation-conversion]] == Resolving Codes to Error Messages -We covered databinding and validation. This section covers outputting messages that correspond to -validation errors. In the example shown in the <>, -we rejected the `name` and `age` fields. If we want to output the error -messages by using a `MessageSource`, we can do so using the error code we provide when -rejecting the field ('name' and 'age' in this case). When you call (either directly, or -indirectly, by using, for example, the `ValidationUtils` class) `rejectValue` or one of the -other `reject` methods from the `Errors` interface, the underlying implementation -not only registers the code you passed in but also registers a number of additional error -codes. The `MessageCodesResolver` determines which error codes the `Errors` interface registers. -By default, the `DefaultMessageCodesResolver` is used, which (for example) not only -registers a message with the code you gave but also registers messages that include the field -name you passed to the reject method. So, if you reject a field by using -`rejectValue("age", "too.darn.old")`, apart from the `too.darn.old` code, Spring -also registers `too.darn.old.age` and `too.darn.old.age.int` (the first includes -the field name and the second includes the type of the field). This is done as a -convenience to aid developers when targeting error messages. +We covered databinding and validation. This section covers outputting messages that correspond +to validation errors. In the example shown in the <>, +we rejected the `name` and `age` fields. If we want to output the error messages by using a +`MessageSource`, we can do so using the error code we provide when rejecting the field +('name' and 'age' in this case). When you call (either directly, or indirectly, by using, +for example, the `ValidationUtils` class) `rejectValue` or one of the other `reject` methods +from the `Errors` interface, the underlying implementation not only registers the code you +passed in but also registers a number of additional error codes. The `MessageCodesResolver` +determines which error codes the `Errors` interface registers. By default, the +`DefaultMessageCodesResolver` is used, which (for example) not only registers a message +with the code you gave but also registers messages that include the field name you passed +to the reject method. So, if you reject a field by using `rejectValue("age", "too.darn.old")`, +apart from the `too.darn.old` code, Spring also registers `too.darn.old.age` and +`too.darn.old.age.int` (the first includes the field name and the second includes the type +of the field). This is done as a convenience to aid developers when targeting error messages. More information on the `MessageCodesResolver` and the default strategy can be found in the javadoc of @@ -259,8 +259,8 @@ object. The following table shows some examples of these conventions: (This next section is not vitally important to you if you do not plan to work with the `BeanWrapper` directly. If you use only the `DataBinder` and the `BeanFactory` -and their default implementations, you should skip ahead to the <>.) +and their default implementations, you should skip ahead to the +<>.) The following two example classes use the `BeanWrapper` to get and set properties: @@ -537,17 +537,17 @@ where it can be automatically detected and applied. Note that all bean factories and application contexts automatically use a number of built-in property editors, through their use a `BeanWrapper` to handle property conversions. The standard property editors that the `BeanWrapper` -registers are listed in <>. Additionally, -`ApplicationContexts` also override or add additional editors to handle +registers are listed in the <>. +Additionally, `ApplicationContexts` also override or add additional editors to handle resource lookups in a manner appropriate to the specific application context type. Standard JavaBeans `PropertyEditor` instances are used to convert property values -expressed as strings to the actual complex type of the property. -You can use `CustomEditorConfigurer`, a bean factory post-processor, to conveniently add +expressed as strings to the actual complex type of the property. You can use +`CustomEditorConfigurer`, a bean factory post-processor, to conveniently add support for additional `PropertyEditor` instances to an `ApplicationContext`. -Consider the following example, which defines a user class called `ExoticType` and another class called `DependsOnExoticType`, which needs -`ExoticType` set as a property: +Consider the following example, which defines a user class called `ExoticType` and +another class called `DependsOnExoticType`, which needs `ExoticType` set as a property: ==== [source,java,indent=0] @@ -629,14 +629,15 @@ Finally, the following example shows how to use `CustomEditorConfigurer` to regi Another mechanism for registering property editors with the Spring container is to create and use a `PropertyEditorRegistrar`. This interface is particularly useful when -you need to use the same set of property editors in several different situations. You can write -a corresponding registrar and reuse it in each case. `PropertyEditorRegistrar` instances work -in conjunction with an interface called `PropertyEditorRegistry`, an interface that is -implemented by the Spring `BeanWrapper` (and `DataBinder`). `PropertyEditorRegistrar` instances -are particularly convenient when used in conjunction with `CustomEditorConfigurer` -(described <>), which exposes a -property called `setPropertyEditorRegistrars(..)`. `PropertyEditorRegistrar` instances added to a -`CustomEditorConfigurer` in this fashion can easily be shared with `DataBinder` and +you need to use the same set of property editors in several different situations. +You can write a corresponding registrar and reuse it in each case. +`PropertyEditorRegistrar` instances work in conjunction with an interface called +`PropertyEditorRegistry`, an interface that is implemented by the Spring `BeanWrapper` +(and `DataBinder`). `PropertyEditorRegistrar` instances are particularly convenient +when used in conjunction with `CustomEditorConfigurer` (described +<>), which exposes a property +called `setPropertyEditorRegistrars(..)`. `PropertyEditorRegistrar` instances added +to a `CustomEditorConfigurer` in this fashion can easily be shared with `DataBinder` and Spring MVC controllers. Furthermore, it avoids the need for synchronization on custom editors: A `PropertyEditorRegistrar` is expected to create fresh `PropertyEditor` instances for each bean creation attempt. @@ -687,7 +688,7 @@ The next example shows how to configure a `CustomEditorConfigurer` and inject an ==== Finally (and in a bit of a departure from the focus of this chapter for those of you -using <>), using `PropertyEditorRegistrars` in +using <>), using `PropertyEditorRegistrars` in conjunction with data-binding `Controllers` (such as `SimpleFormController`) can be very convenient. The following example uses a `PropertyEditorRegistrar` in the implementation of an `initBinder(..)` method: @@ -1002,8 +1003,7 @@ It is also common to use a `ConversionService` within a Spring MVC application. <> in the Spring MVC chapter. In certain situations, you may wish to apply formatting during conversion. See -<> for details on using -`FormattingConversionServiceFactoryBean`. +<> for details on using `FormattingConversionServiceFactoryBean`. diff --git a/src/docs/asciidoc/data-access-appendix.adoc b/src/docs/asciidoc/data-access-appendix.adoc index f9aaaff0402..bf8e61d851f 100644 --- a/src/docs/asciidoc/data-access-appendix.adoc +++ b/src/docs/asciidoc/data-access-appendix.adoc @@ -18,7 +18,7 @@ This part of the appendix lists XML schemas for data access, including the follo The `tx` tags deal with configuring all of those beans in Spring's comprehensive support for transactions. These tags are covered in the chapter entitled -<>. +<>. TIP: We strongly encourage you to look at the `'spring-tx.xsd'` file that ships with the Spring distribution. This file contains the XML Schema for Spring's transaction @@ -67,8 +67,8 @@ to you. The `jdbc` elements let you quickly configure an embedded database or initialize an existing data source. These elements are documented in -<> and -<>, respectively. +<> and +<>, respectively. To use the elements in the `jdbc` schema, you need to have the following preamble at the top of your Spring XML configuration file. The text in the following snippet references diff --git a/src/docs/asciidoc/data-access.adoc b/src/docs/asciidoc/data-access.adoc index 51147d17704..9583e6ea1b4 100644 --- a/src/docs/asciidoc/data-access.adoc +++ b/src/docs/asciidoc/data-access.adoc @@ -26,33 +26,34 @@ management that delivers the following benefits: * A consistent programming model across different transaction APIs, such as Java Transaction API (JTA), JDBC, Hibernate, and the Java Persistence API (JPA). -* Support for <>. -* A simpler API for <> transaction management than - complex transaction APIs, such as JTA. +* Support for <>. +* A simpler API for <> transaction management + than complex transaction APIs, such as JTA. * Excellent integration with Spring's data access abstractions. The following sections describe the Spring Framework's transaction features and technologies: -* <> describes why you would use the Spring Framework's transaction abstraction instead of EJB Container-Managed Transactions (CMT) or choosing to drive local transactions through a proprietary API, such as Hibernate. -* <> +* <> outlines the core classes and describes how to configure and obtain `DataSource` instances from a variety of sources. -* <> describes +* <> describes how the application code ensures that resources are created, reused, and cleaned up properly. -* <> describes support for +* <> describes support for declarative transaction management. -* <> covers support for +* <> covers support for programmatic (that is, explicitly coded) transaction management. -* <> describes how you could use application +* <> describes how you could use application events within a transaction. -(The chapter also includes discussions of best practices, <>, and <>.) +The chapter also includes discussions of best practices, +<>, +and <>. @@ -169,7 +170,7 @@ strategy. A transaction strategy is defined by the ==== This is primarily a service provider interface (SPI), although you can use it -<> from your application code. Because +<> from your application code. Because `PlatformTransactionManager` is an interface, it can be easily mocked or stubbed as necessary. It is not tied to a lookup strategy, such as JNDI. `PlatformTransactionManager` implementations are defined like any other object (or bean) @@ -311,8 +312,8 @@ The `JtaTransactionManager` does not need to know about the `DataSource` (or any specific resources) because it uses the container's global transaction management infrastructure. -NOTE: The preceding definition of the `dataSource` bean uses the `` tag from the -`jee` namespace. For more information see +NOTE: The preceding definition of the `dataSource` bean uses the `` tag +from the `jee` namespace. For more information see <>. You can also use easily Hibernate local transactions, as shown in the following @@ -322,9 +323,9 @@ which your application code can use to obtain Hibernate `Session` instances. The `DataSource` bean definition is similar to the local JDBC example shown previously and, thus, is not shown in the following example. -NOTE: If the `DataSource` (used by any non-JTA transaction manager) is looked up through JNDI and -managed by a Java EE container, it should be non-transactional, because the Spring -Framework (rather than the Java EE container) manages the transactions. +NOTE: If the `DataSource` (used by any non-JTA transaction manager) is looked up through +JNDI and managed by a Java EE container, it should be non-transactional, because the +Spring Framework (rather than the Java EE container) manages the transactions. The `txManager` bean in this case is of the `HibernateTransactionManager` type. In the same way as the `DataSourceTransactionManager` needs a reference to the `DataSource`, @@ -486,7 +487,7 @@ necessary. The differences between the two types of transaction management are: * You can apply the Spring Framework declarative transaction management to any class, not merely special classes such as EJBs. * The Spring Framework offers declarative - <>, a feature with no EJB + <>, a feature with no EJB equivalent. Both programmatic and declarative support for rollback rules is provided. * The Spring Framework lets you customize transactional behavior by using AOP. For example, you can insert custom behavior in the case of transaction rollback. You @@ -498,16 +499,6 @@ necessary. The differences between the two types of transaction management are: recommend that you use EJB. However, consider carefully before using such a feature, because, normally, one does not want transactions to span remote calls. -.Where is TransactionProxyFactoryBean? -**** -Declarative transaction configuration in versions of Spring 2.0 and above differs -considerably from previous versions of Spring. The main difference is that there is no -longer any need to configure `TransactionProxyFactoryBean` beans. - -The pre-Spring 2.0 configuration style is still 100% valid configuration. Think of the -new `` as defining `TransactionProxyFactoryBean` beans on your behalf. -**** - The concept of rollback rules is important. They let you specify which exceptions (and throwables) should cause automatic rollback. You can specify this declaratively, in configuration, not in Java code. So, although you can still call `setRollbackOnly()` on @@ -536,7 +527,7 @@ transaction infrastructure in the event of transaction-related issues. The most important concepts to grasp with regard to the Spring Framework's declarative transaction support are that this support is enabled -<> and that the transactional +<> and that the transactional advice is driven by metadata (currently XML- or annotation-based). The combination of AOP with transactional metadata yields an AOP proxy that uses a `TransactionInterceptor` in conjunction with an appropriate `PlatformTransactionManager` implementation to drive @@ -693,13 +684,14 @@ attribute explicitly, as in the preceding example. The `` definition ensures that the transactional advice defined by the `txAdvice` bean executes at the appropriate points in the program. First, you define a -pointcut that matches the execution of any operation defined in the `FooService` -interface ( `fooServiceOperation`). Then you associate the pointcut with the `txAdvice` -by using an advisor. The result indicates that, at the execution of a `fooServiceOperation`, +pointcut that matches the execution of any operation defined in the `FooService` interface +(`fooServiceOperation`). Then you associate the pointcut with the `txAdvice` by using an +advisor. The result indicates that, at the execution of a `fooServiceOperation`, the advice defined by `txAdvice` is run. The expression defined within the `` element is an AspectJ pointcut -expression. See <> for more details on pointcut expressions in Spring. +expression. See <> for more details on pointcut +expressions in Spring. A common requirement is to make an entire service layer transactional. The best way to do this is to change the pointcut expression to match any operation in your @@ -716,18 +708,18 @@ service layer. The following example shows how to do so: ---- ==== -NOTE: In the preceding example, it is assumed that all your service interfaces are defined in the -`x.y.service` package. See <> for more details. +NOTE: In the preceding example, it is assumed that all your service interfaces are defined +in the `x.y.service` package. See <> for more details. Now that we have analyzed the configuration, you may be asking yourself, "`What does all this configuration actually do?`" The configuration shown earlier is used to create a transactional proxy around the object that is created from the `fooService` bean definition. The proxy is configured with -the transactional advice so that, when an appropriate method is invoked on the -proxy, a transaction is started, suspended, marked as read-only, and so on, depending -on the transaction configuration associated with that method. Consider the following -program that test drives the configuration shown earlier: +the transactional advice so that, when an appropriate method is invoked on the proxy, +a transaction is started, suspended, marked as read-only, and so on, depending on the +transaction configuration associated with that method. Consider the following program +that test drives the configuration shown earlier: ==== [source,java,indent=0] @@ -1007,7 +999,7 @@ transactional settings: This section summarizes the various transactional settings that you can specify by using the `` tag. The default `` settings are: -* The <> is `REQUIRED.` +* The <> is `REQUIRED.` * The isolation level is `DEFAULT.` * The transaction is read-write. * The transaction timeout defaults to the default timeout of the underlying transaction @@ -1225,7 +1217,7 @@ modified) to turn `@Transactional` into runtime behavior on any kind of method. for classes annotated with the `@Transactional` annotation. If the `proxy-target-class` attribute is set to `true`, class-based proxies are created. If `proxy-target-class` is `false` or if the attribute is omitted, then standard JDK - interface-based proxies are created. (See <> + interface-based proxies are created. (See <> for a detailed examination of the different proxy types.) | `order` @@ -1233,7 +1225,7 @@ modified) to turn `@Transactional` into runtime behavior on any kind of method. | `Ordered.LOWEST_PRECEDENCE` | Defines the order of the transaction advice that is applied to beans annotated with `@Transactional`. (For more information about the rules related to ordering of AOP - advice, see <>.) + advice, see <>.) No specified ordering means that the AOP subsystem determines the order of the advice. |=== @@ -1404,7 +1396,7 @@ specifically qualified `PlatformTransactionManager` bean is found. ===== Custom Shortcut Annotations If you find you repeatedly use the same attributes with `@Transactional` on many different -methods, <> lets you +methods, <> lets you define custom shortcut annotations for your specific use cases. For example, consider the following annotation definitions: @@ -2588,7 +2580,7 @@ The following example invokes a stored procedure: ---- ==== -More sophisticated stored procedure support is <>. +More sophisticated stored procedure support is <>. [[jdbc-JdbcTemplate-idioms]] ===== `JdbcTemplate` Best Practices @@ -2600,7 +2592,7 @@ The `JdbcTemplate` is stateful, in that it maintains a reference to a `DataSourc this state is not conversational state. A common practice when using the `JdbcTemplate` class (and the associated -<> class) is to +<> class) is to configure a `DataSource` in your Spring configuration file and then dependency-inject that shared `DataSource` bean into your DAO classes. The `JdbcTemplate` is created in the setter for the `DataSource`. This leads to DAOs that resemble the following: @@ -3911,7 +3903,7 @@ returned `out` parameters. Earlier in this chapter, we described how parameters are deduced from metadata, but you can declare them explicitly if you wish. You can do so by creating and configuring `SimpleJdbcCall` with the `declareParameters` method, which takes a variable number of `SqlParameter` objects -as input. See the <> for details on how to define an `SqlParameter`. +as input. See the <> for details on how to define an `SqlParameter`. NOTE: Explicit declarations are necessary if the database you use is not a Spring-supported database. Currently, Spring supports metadata lookup of stored procedure calls for the @@ -4901,12 +4893,12 @@ call the `setType(EmbeddedDatabaseType)` method with `EmbeddedDatabaseType.DERBY Embedded databases provide a lightweight way to test data access code. The next example is a data access integration test template that uses an embedded database. Using such a template -can be useful for one-offs when the embedded database does not need to be -reused across test classes. However, if you wish to create an embedded database that is -shared within a test suite, consider using the <> and configuring the embedded database as a bean in the Spring -`ApplicationContext` as described in <> and -<>. The following listing shows the test template: +can be useful for one-offs when the embedded database does not need to be reused across test +classes. However, if you wish to create an embedded database that is shared within a test suite, +consider using the <> and +configuring the embedded database as a bean in the Spring `ApplicationContext` as described +in <> and <>. The following listing +shows the test template: ==== [source,java,indent=0] @@ -5202,14 +5194,13 @@ The benefits of using the Spring Framework to create your ORM DAOs include: aspect-oriented programming (AOP) style method interceptor either through the `@Transactional` annotation or by explicitly configuring the transaction AOP advice in an XML configuration file. In both cases, transaction semantics and exception handling - (rollback and so on) are handled for you. As discussed in - <>, you can also swap various - transaction managers, without affecting your ORM-related code. For example, you can - swap between local transactions and JTA, with the same full services (such as - declarative transactions) available in both scenarios. Additionally, JDBC-related code - can fully integrate transactionally with the code you use to do ORM. This is useful - for data access that is not suitable for ORM (such as batch processing and BLOB - streaming) but that still needs to share common transactions with ORM operations. + (rollback and so on) are handled for you. As discussed in <>, + you can also swap various transaction managers, without affecting your ORM-related code. + For example, you can swap between local transactions and JTA, with the same full services + (such as declarative transactions) available in both scenarios. Additionally, + JDBC-related code can fully integrate transactionally with the code you use to do ORM. + This is useful for data access that is not suitable for ORM (such as batch processing and + BLOB streaming) but that still needs to share common transactions with ORM operations. TIP: For more comprehensive ORM support, including support for alternative database technologies such as MongoDB, you might want to check out the @@ -5222,8 +5213,8 @@ Data with JPA] guide from https://spring.io provides a great introduction. [[orm-general]] === General ORM Integration Considerations -This section highlights considerations that apply to all ORM technologies. The -<> section provides more details and also show these features and +This section highlights considerations that apply to all ORM technologies. +The <> section provides more details and also show these features and configurations in a concrete context. The major goal of Spring's ORM integration is clear application layering (with any data @@ -5252,10 +5243,11 @@ interceptors for the ORM technologies. The infrastructure provides proper resource handling and appropriate conversion of specific API exceptions to an unchecked infrastructure exception hierarchy. Spring introduces a DAO exception hierarchy, applicable to any data access strategy. For direct -JDBC, the `JdbcTemplate` class mentioned in a <> provides connection -handling and proper conversion of `SQLException` to the `DataAccessException` hierarchy, -including translation of database-specific SQL error codes to meaningful exception -classes. For ORM technologies, see the <> for how to get the same exception +JDBC, the `JdbcTemplate` class mentioned in a <> +provides connection handling and proper conversion of `SQLException` to the +`DataAccessException` hierarchy, including translation of database-specific SQL error +codes to meaningful exception classes. For ORM technologies, see the +<> for how to get the same exception translation benefits. When it comes to transaction management, the `JdbcTemplate` class hooks in to the Spring @@ -5342,7 +5334,7 @@ To avoid tying application objects to hard-coded resource lookups, you can defin resources (such as a JDBC `DataSource` or a Hibernate `SessionFactory`) as beans in the Spring container. Application objects that need to access resources receive references to such predefined instances through bean references, as illustrated in the DAO -definition in the <>. +definition in the <>. The following excerpt from an XML application context definition shows how to set up a JDBC `DataSource` and a Hibernate `SessionFactory` on top of it: @@ -5410,7 +5402,7 @@ property. On the programmatic `LocalSessionFactoryBuilder`, there is an overload As of Spring Framework 5.1, such a native Hibernate setup can also expose a JPA `EntityManagerFactory` for standard JPA interaction next to native Hibernate access. -See <> for details. +See <> for details. ==== @@ -5898,7 +5890,7 @@ NOTE: If you want to specifically configure a Hibernate setup, an immediate alte to go with Hibernate 5.2 or 5.3 and set up a native Hibernate `LocalSessionFactoryBean` instead of a plain JPA `LocalContainerEntityManagerFactoryBean`, letting it interact with JPA access code as well as native Hibernate access code. -See <> for details. +See <> for details. The `LocalContainerEntityManagerFactoryBean` gives full control over `EntityManagerFactory` configuration and is appropriate for environments where @@ -5984,18 +5976,17 @@ Spring provides a number of `LoadTimeWeaver` implementations for various environ letting `ClassTransformer` instances be applied only for each class loader and not for each VM. -See <> in the AOP chapter for +See the <> in the AOP chapter for more insight regarding the `LoadTimeWeaver` implementations and their setup, either -generic or customized to various platforms (such as Tomcat, WebLogic, GlassFish, -Resin, and JBoss). +generic or customized to various platforms (such as Tomcat, JBoss and WebSphere). -As described in <>, you can configure a context-wide -`LoadTimeWeaver` by using the `@EnableLoadTimeWeaving` annotation of the -`context:load-time-weaver` XML element. Such a global weaver is automatically picked up by all JPA -`LocalContainerEntityManagerFactoryBean` instances. The following example shows the preferred way of -setting up a load-time weaver, delivering auto-detection of the platform (WebLogic, -GlassFish, Tomcat, Resin, JBoss, or VM agent) and automatic propagation of the weaver to -all weaver-aware beans: +As described in <>, you can configure +a context-wide `LoadTimeWeaver` by using the `@EnableLoadTimeWeaving` annotation of the +`context:load-time-weaver` XML element. Such a global weaver is automatically picked u +by all JPA `LocalContainerEntityManagerFactoryBean` instances. The following example +shows the preferred way of setting up a load-time weaver, delivering auto-detection +of the platform (e.g. Tomcat's weaving-capable class loader or Spring's JVM agent) +and automatic propagation of the weaver to all weaver-aware beans: ==== [source,xml,indent=0] @@ -6237,8 +6228,8 @@ Even though the new DAO implementation uses method-level injection of an `EntityManager` instead of an `EntityManagerFactory`, no change is required in the application context XML, due to annotation usage. -The main advantage of this DAO style is that it depends only on the Java Persistence API. No -import of any Spring class is required. Moreover, as the JPA annotations are understood, +The main advantage of this DAO style is that it depends only on the Java Persistence API. +No import of any Spring class is required. Moreover, as the JPA annotations are understood, the injections are applied automatically by the Spring container. This is appealing from a non-invasiveness perspective and can feel more natural to JPA developers. @@ -6246,8 +6237,8 @@ a non-invasiveness perspective and can feel more natural to JPA developers. [[orm-jpa-tx]] ==== Spring-driven JPA transactions -NOTE: We strongly encourage you to read <>, if you have not already done -so, to get more detailed coverage of Spring's declarative transaction support. +NOTE: We strongly encourage you to read <>, if you have not +already done so, to get more detailed coverage of Spring's declarative transaction support. The recommended strategy for JPA is local transactions through JPA's native transaction support. Spring's `JpaTransactionManager` provides many capabilities known from local @@ -6258,13 +6249,13 @@ Spring JPA also lets a configured `JpaTransactionManager` expose a JPA transacti to JDBC access code that accesses the same `DataSource`, provided that the registered `JpaDialect` supports retrieval of the underlying JDBC `Connection`. Spring provides dialects for the EclipseLink and Hibernate JPA implementations. -See the <> for details on the `JpaDialect` mechanism. +See the <> for details on the `JpaDialect` mechanism. NOTE: As an immediate alternative, Spring's native `HibernateTransactionManager` is capable of interacting with JPA access code as of Spring Framework 5.1 and Hibernate 5.2/5.3, adapting to several Hibernate specifics and providing JDBC interaction. This makes particular sense in combination with `LocalSessionFactoryBean` setup. -See <> for details. +See <> for details. [[orm-jpa-dialect]] @@ -6361,7 +6352,7 @@ seamlessly integrating with `@Bean` style configuration (no `FactoryBean` involv ==== `LocalSessionFactoryBean` and `LocalSessionFactoryBuilder` support background bootstrapping, just as the JPA `LocalContainerEntityManagerFactoryBean` does. -See <> for an introduction. +See <> for an introduction. On `LocalSessionFactoryBean`, this is available through the `bootstrapExecutor` property. On the programmatic `LocalSessionFactoryBuilder`, an overloaded @@ -6430,8 +6421,8 @@ These runtime exceptions wrap the original exception so that no information is l [[oxm-marshaller-unmarshaller]] === `Marshaller` and `Unmarshaller` -As stated in the <>, a marshaller serializes an object to XML, and an -unmarshaller deserializes XML stream to an object. This section describes +As stated in the <>, a marshaller serializes an object +to XML, and an unmarshaller deserializes XML stream to an object. This section describes the two Spring interfaces used for this purpose. diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc index c0a5e8d4ee4..175afc8518b 100644 --- a/src/docs/asciidoc/index.adoc +++ b/src/docs/asciidoc/index.adoc @@ -3,23 +3,23 @@ :api-spring-framework: {doc-root}/spring-framework/docs/{spring-version}/javadoc-api/org/springframework **** -_What's New_, _Upgrade Notes_, _Supported Versions_, and other topics, independent of -release cadence, are maintained externaly on the project's +_What's New_, _Upgrade Notes_, _Supported Versions_, and other topics, +independent of release cadence, are maintained externaly on the project's https://github.com/spring-projects/spring-framework/wiki[*Github Wiki*]. **** [horizontal] -<> :: history, design philosophy,feedback, +<> :: history, design philosophy,feedback, getting started. -<> :: IoC container, Events, Resources, i18n, Validation, +<> :: IoC container, Events, Resources, i18n, Validation, Data Binding, Type Conversion, SpEL, AOP. -<> :: Mock objects, TestContext framework, +<> :: Mock objects, TestContext framework, Spring MVC Test, WebTestClient. -<> :: Transactions, DAO support, JDBC, +<> :: Transactions, DAO support, JDBC, ORM, Marshalling XML. -<> :: Spring MVC, WebSocket, SockJS, STOMP messaging. -<> :: Spring WebFlux, +<> :: Spring MVC, WebSocket, SockJS, STOMP messaging. +<> :: Spring WebFlux, WebClient, WebSocket. -<> :: Remoting, JMS, JCA, JMX, Email, +<> :: Remoting, JMS, JCA, JMX, Email, Tasks, Scheduling, Cache. -<> :: Kotlin, Groovy, Dynamic languages. +<> :: Kotlin, Groovy, Dynamic languages. diff --git a/src/docs/asciidoc/integration-appendix.adoc b/src/docs/asciidoc/integration-appendix.adoc index 12079dc62fd..9f2883dc3be 100644 --- a/src/docs/asciidoc/integration-appendix.adoc +++ b/src/docs/asciidoc/integration-appendix.adoc @@ -311,8 +311,8 @@ SessionBean with `jee`: === The `jms` Schema The `jms` elements deal with configuring JMS-related beans, such as Spring's -<>. These elements are detailed in the -section of the <> entitled <>. These elements are detailed in the +section of the <> entitled <>. See that chapter for full details on this support and the `jms` elements themselves. @@ -352,8 +352,8 @@ This element is detailed in You can use the `cache` elements to enable support for Spring's `@CacheEvict`, `@CachePut`, and `@Caching` annotations. It it also supports declarative XML-based caching. See -<> and -<> for details. +<> and +<> for details. To use the elements in the `cache` schema, you need to have the following preamble at the top of your Spring XML configuration file. The text in the following snippet references diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index 6ce8b51cc3e..be27bbf953f 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -18,9 +18,9 @@ a number of Java EE (and related) technologies. [[remoting]] == Remoting and Web Services with Spring -Spring features integration classes for remoting support with various technologies. The -remoting support eases the development of remote-enabled services, implemented by your -usual (Spring) POJOs. Currently, Spring supports the following remoting technologies: +Spring features integration classes for remoting support with various technologies. +The remoting support eases the development of remote-enabled services, implemented by +your usual POJOs. Currently, Spring supports the following remoting technologies: * *Remote Method Invocation (RMI)*: Through the use of `RmiProxyFactoryBean` and `RmiServiceExporter`, Spring supports both traditional RMI (with `java.rmi.Remote` @@ -57,7 +57,6 @@ model and corresponding services: public void setName(String name) { this.name = name; } - } ---- @@ -69,7 +68,6 @@ model and corresponding services: public void insertAccount(Account account); public List getAccounts(String name); - } ---- @@ -86,7 +84,6 @@ model and corresponding services: public List getAccounts(String name) { // do something... } - } ---- ==== @@ -176,7 +173,6 @@ as the following example shows: } // additional methods using the accountService - } ---- ==== @@ -208,17 +204,17 @@ transparently creates an invoker and remotely enables the account service throug [[remoting-caucho-protocols]] === Using Hessian to Remotely Call Services through HTTP -Hessian offers a binary HTTP-based remoting protocol. It is developed by Caucho, and you can find more -information about Hessian itself at http://www.caucho.com[]. +Hessian offers a binary HTTP-based remoting protocol. It is developed by Caucho, +and you can find more information about Hessian itself at http://www.caucho.com[]. [[remoting-caucho-protocols-hessian]] ==== Wiring up `DispatcherServlet` for Hessian Hessian communicates through HTTP and does so by using a custom servlet. By using Spring's -`DispatcherServlet` principles (see <>), we can wire -up such a servlet to expose your services. First, we have to create a new servlet in -our application, as shown in the following excerpt from `web.xml`: +`DispatcherServlet` principles (see <>), we can wire up such a +servlet to expose your services. First, we have to create a new servlet in our application, +as shown in the following excerpt from `web.xml`: ==== [source,xml,indent=0] @@ -426,7 +422,7 @@ dispatcher's application context, as the following example shows: ==== Such an exporter definition is exposed through the `DispatcherServlet` instance's standard -mapping facilities, as explained in <>. +mapping facilities, as explained in <>. Alternatively, you can create an `HttpInvokerServiceExporter` in your root application context (for example, in `'WEB-INF/applicationContext.xml'`), as the following example shows: @@ -535,7 +531,7 @@ shows our class that extends `SpringBeanAutowiringSupport`: * the @Autowired annotation) is the simplest JAX-WS compliant way. * * This is the class registered with the server-side JAX-WS implementation. - * In the case of a Java EE 5 server, this would simply be defined as a servlet + * In the case of a Java EE server, this would simply be defined as a servlet * in web.xml, with the server detecting that this is a JAX-WS endpoint and reacting * accordingly. The servlet name usually needs to match the specified WS service name. * @@ -559,15 +555,14 @@ shows our class that extends `SpringBeanAutowiringSupport`: public Account[] getAccounts(String name) { return biz.getAccounts(name); } - } ---- ==== Our `AccountServiceEndpoint` needs to run in the same web application as the Spring context to allow for access to Spring's facilities. This is the case by default in Java -EE 5 environments, using the standard contract for JAX-WS servlet endpoint deployment. -See the various Java EE 5 web service tutorials for details. +EE environments, using the standard contract for JAX-WS servlet endpoint deployment. +See the various Java EE web service tutorials for details. [[remoting-web-services-jaxws-export-standalone]] @@ -580,11 +575,11 @@ application context and exports them through the default JAX-WS server (the JDK server). In this scenario, the endpoint instances are defined and managed as Spring beans -themselves. They are registered with the JAX-WS engine, but their lifecycle is -up to the Spring application context. This means that you can apply Spring functionality (such as explicit -dependency injection) to the endpoint instances. -Annotation-driven injection through `@Autowired` works as well. -The following example shows how to define these beans: +themselves. They are registered with the JAX-WS engine, but their lifecycle is up to +the Spring application context. This means that you can apply Spring functionality +(such as explicit dependency injection) to the endpoint instances. Annotation-driven +injection through `@Autowired` works as well. The following example shows how to +define these beans: ==== [source,xml,indent=0] @@ -634,21 +629,20 @@ and Spring's `@Autowired` configuration annotation is still honored): [[remoting-web-services-jaxws-export-ri]] ==== Exporting Web Services by Using JAX-WS RI's Spring Support -Oracle's JAX-WS RI, developed as part of the GlassFish project, ships Spring support as -part of its JAX-WS Commons project. This allows for defining JAX-WS endpoints as -Spring-managed beans, similar to the standalone mode discussed in the <> -- +Oracle's JAX-WS RI, developed as part of the GlassFish project, ships Spring support +as part of its JAX-WS Commons project. This allows for defining JAX-WS endpoints as +Spring-managed beans, similar to the standalone mode discussed in the +<> -- but this time in a Servlet environment. -NOTE: This is not portable in a Java EE 5 -environment. It is mainly intended for non-EE environments, such as Tomcat, that embed the -JAX-WS RI as part of the web application. +NOTE: This is not portable in a Java EE environment. It is mainly intended for non-EE +environments, such as Tomcat, that embed the JAX-WS RI as part of the web application. -The differences from the standard style of exporting servlet-based endpoints are that the -lifecycle of the endpoint instances themselves are managed by Spring and that -there is only one JAX-WS servlet defined in `web.xml`. With the standard Java EE 5 -style (as shown earlier), you have one servlet definition per service endpoint, -with each endpoint typically delegating to Spring beans (through the use of -`@Autowired`, as shown earlier). +The differences from the standard style of exporting servlet-based endpoints are that +the lifecycle of the endpoint instances themselves are managed by Spring and that there +is only one JAX-WS servlet defined in `web.xml`. With the standard Java EE style (as +shown earlier), you have one servlet definition per service endpoint, with each endpoint +typically delegating to Spring beans (through the use of `@Autowired`, as shown earlier). See https://jax-ws-commons.java.net/spring/[https://jax-ws-commons.java.net/spring/] for details on setup and usage style. @@ -660,8 +654,9 @@ for details on setup and usage style. Spring provides two factory beans to create JAX-WS web service proxies, namely `LocalJaxWsServiceFactoryBean` and `JaxWsPortProxyFactoryBean`. The former can return only a JAX-WS service class for us to work with. The latter is the full-fledged -version that can return a proxy that implements our business service interface. In the following -example, we use `JaxWsPortProxyFactoryBean` to create a proxy for the `AccountService` endpoint (again): +version that can return a proxy that implements our business service interface. +In the following example, we use `JaxWsPortProxyFactoryBean` to create a proxy for the +`AccountService` endpoint (again): ==== [source,xml,indent=0] @@ -683,8 +678,9 @@ create the JAX-WS Service. `namespaceUri` corresponds to the `targetNamespace` i .wsdl file. `serviceName` corresponds to the service name in the .wsdl file. `portName` corresponds to the port name in the .wsdl file. -Accessing the web service is easy, as we have a bean factory for it that -exposes it as an interface called `AccountService`. The following example shows how we can wire this up in Spring: +Accessing the web service is easy, as we have a bean factory for it that exposes it as +an interface called `AccountService`. The following example shows how we can wire this +up in Spring: ==== [source,xml,indent=0] @@ -731,12 +727,11 @@ accordingly first. Check the JAX-WS documentation for details on those requireme === Exposing Services through JMS You can also expose services transparently by using JMS as the underlying communication -protocol. The JMS remoting support in the Spring Framework is pretty basic. -It sends and receives on the `same thread` and in the same non-transactional -`Session`. As a result, throughput is implementation-dependent. Note that these -single-threaded and non-transactional constraints apply only to Spring's JMS -remoting support. See <> for information on Spring's rich support for JMS-based -messaging. +protocol. The JMS remoting support in the Spring Framework is pretty basic. It sends +and receives on the `same thread` and in the same non-transactional `Session`. +As a result, throughput is implementation-dependent. Note that these single-threaded +and non-transactional constraints apply only to Spring's JMS remoting support. +See <> for information on Spring's rich support for JMS-based messaging. The following interface is used on both the server and the client sides: @@ -840,7 +835,7 @@ On the server, you need to expose the service object that uses the public class Server { public static void main(String[] args) throws Exception { - new ClassPathXmlApplicationContext(new String[]{"com/foo/server.xml", "com/foo/jms.xml"}); + new ClassPathXmlApplicationContext("com/foo/server.xml", "com/foo/jms.xml"); } } ---- @@ -851,10 +846,10 @@ On the server, you need to expose the service object that uses the ==== Client-side Configuration The client merely needs to create a client-side proxy that implements the agreed-upon -interface ( `CheckingAccountService`). +interface (`CheckingAccountService`). -The following example defines beans that you can inject into other client-side objects (and the -proxy takes care of forwarding the call to the server-side object via JMS): +The following example defines beans that you can inject into other client-side objects +(and the proxy takes care of forwarding the call to the server-side object via JMS): ==== [source,xml,indent=0] @@ -887,8 +882,7 @@ proxy takes care of forwarding the call to the server-side object via JMS): public class Client { public static void main(String[] args) throws Exception { - ApplicationContext ctx = new ClassPathXmlApplicationContext( - new String[] {"com/foo/client.xml", "com/foo/jms.xml"}); + ApplicationContext ctx = new ClassPathXmlApplicationContext("com/foo/client.xml", "com/foo/jms.xml"); CheckingAccountService service = (CheckingAccountService) ctx.getBean("checkingAccountService"); service.cancelAccount(new Long(10)); } @@ -973,7 +967,7 @@ The Spring Framework provides two choices for making calls to REST endpoints: * <>: The original Spring REST client with a synchronous, template method API. -* <>: a non-blocking, reactive alternative +* <>: a non-blocking, reactive alternative that supports both synchronous and asynchronous as well as streaming scenarios. NOTE: As of 5.0, the non-blocking, reactive `WebClient` offers a modern alternative to the @@ -1111,12 +1105,11 @@ Keep in mind URI templates are automatically encoded, as the following example s ---- ==== -You can use the `uriTemplateHandler` property of `RestTemplate` to customize how URIs are -encoded. Alternatively, you can prepare a `java.net.URI` and pass it into one of the `RestTemplate` -methods that accepts a `URI`. +You can use the `uriTemplateHandler` property of `RestTemplate` to customize how URIs +are encoded. Alternatively, you can prepare a `java.net.URI` and pass it into one of +the `RestTemplate` methods that accepts a `URI`. -For more details on working with and encoding URIs, see -<>. +For more details on working with and encoding URIs, see <>. [[rest-template-headers]] ===== Headers @@ -1178,13 +1171,13 @@ then helps to populate the `Accept` header. If necessary, you can use the `excha methods to provide the `Accept` header explicitly. By default, `RestTemplate` registers all built-in -<>, depending on classpath checks that help +<>, depending on classpath checks that help to determine what optional conversion libraries are present. You can also set the message converters to use explicitly. [[rest-message-conversion]] ===== Message Conversion -[.small]#<># +[.small]#<># The `spring-web` module contains the `HttpMessageConverter` contract for reading and writing the body of HTTP requests and responses through `InputStream` and `OutputStream`. @@ -1194,7 +1187,7 @@ on the server side (for example, in Spring MVC REST controllers). Concrete implementations for the main media (MIME) types are provided in the framework and are, by default, registered with the `RestTemplate` on the client side and with `RequestMethodHandlerAdapter` on the server side (see -<>). +<>). The implementations of `HttpMessageConverter` are described in the following sections. For all converters, a default media type is used, but you can override it by setting the @@ -1327,8 +1320,8 @@ set the `Content-Type` to `multipart/form-data`. This is always the case when yo [[rest-async-resttemplate]] ==== Using `AsyncRestTemplate` (Deprecated) -The `AsyncRestTemplate` is deprecated. For all use cases where you might consider using `AsyncRestTemplate`, -use the <> instead. +The `AsyncRestTemplate` is deprecated. For all use cases where you might consider using +`AsyncRestTemplate`, use the <> instead. @@ -1339,8 +1332,8 @@ use the <> instead. As a lightweight container, Spring is often considered an EJB replacement. We do believe that for many, if not most, applications and use cases, Spring, as a container, combined with its rich supporting functionality in the area of transactions, ORM and JDBC access, -is a better choice than implementing equivalent functionality through an EJB container and -EJBs. +is a better choice than implementing equivalent functionality through an EJB container +and EJBs. However, it is important to note that using Spring does not prevent you from using EJBs. In fact, Spring makes it much easier to access EJBs and implement EJBs and functionality @@ -1779,10 +1772,9 @@ operations that do not refer to a specific destination. One of the most common uses of JMS messages in the EJB world is to drive message-driven beans (MDBs). Spring offers a solution to create message-driven POJOs (MDPs) in a way -that does not tie a user to an EJB container. (See <> -for detailed coverage of Spring's MDP support.) Since Spring Framework 4.1, endpoint -methods can be annotated with `@JmsListener` -- see <> for more -details. +that does not tie a user to an EJB container. (See <> for detailed +coverage of Spring's MDP support.) Since Spring Framework 4.1, endpoint methods can be +annotated with `@JmsListener` -- see <> for more details. A message listener container is used to receive messages from a JMS message queue and drive the `MessageListener` that is injected into it. The listener container is @@ -1797,28 +1789,28 @@ boilerplate JMS infrastructure concerns to the framework. There are two standard JMS message listener containers packaged with Spring, each with its specialized feature set. -* <> -* <> +* <> +* <> [[jms-mdp-simple]] ===== Using `SimpleMessageListenerContainer` -This message listener container is the simpler of the two standard flavors. It creates a -fixed number of JMS sessions and consumers at startup, registers the listener by using the -standard JMS `MessageConsumer.setMessageListener()` method, and leaves it up the JMS +This message listener container is the simpler of the two standard flavors. It creates +a fixed number of JMS sessions and consumers at startup, registers the listener by using +the standard JMS `MessageConsumer.setMessageListener()` method, and leaves it up the JMS provider to perform listener callbacks. This variant does not allow for dynamic adaption to runtime demands or for participation in externally managed transactions. Compatibility-wise, it stays very close to the spirit of the standalone JMS specification, but is generally not compatible with Java EE's JMS restrictions. NOTE: While `SimpleMessageListenerContainer` does not allow for participation in externally -managed transactions, it does support native JMS transactions. To enable this feature, you can switch the -`sessionTransacted` flag to `true` or, in the XML namespace, set the `acknowledge` attribute -to `transacted`. Exceptions thrown from your listener then lead to a rollback, with -the message getting redelivered. Alternatively, consider using `CLIENT_ACKNOWLEDGE` mode, -which provides redelivery in case of an exception as well but does not use transacted -`Session` instances and, therefore, does not include any other `Session` operations (such as sending -response messages) in the transaction protocol. +managed transactions, it does support native JMS transactions. To enable this feature, +you can switch the `sessionTransacted` flag to `true` or, in the XML namespace, set the +`acknowledge` attribute to `transacted`. Exceptions thrown from your listener then lead +to a rollback, with the message getting redelivered. Alternatively, consider using +`CLIENT_ACKNOWLEDGE` mode, which provides redelivery in case of an exception as well but +does not use transacted `Session` instances and, therefore, does not include any other +`Session` operations (such as sending response messages) in the transaction protocol. IMPORTANT: The default `AUTO_ACKNOWLEDGE` mode does not provide proper reliability guarantees. Messages can get lost when listener execution fails (since the provider automatically @@ -1832,11 +1824,11 @@ reliability needs (for example, for reliable queue handling and durable topic su This message listener container is used in most cases. In contrast to `SimpleMessageListenerContainer`, this container variant allows for dynamic adaptation -to runtime demands and is able to participate in externally managed transactions. Each -received message is registered with an XA transaction when configured with a -`JtaTransactionManager`. As a result, processing may take advantage of XA transaction semantics. -This listener container strikes a good balance between low requirements on the JMS -provider, advanced functionality (such as participation in externally managed +to runtime demands and is able to participate in externally managed transactions. +Each received message is registered with an XA transaction when configured with a +`JtaTransactionManager`. As a result, processing may take advantage of XA transaction +semantics. This listener container strikes a good balance between low requirements on +the JMS provider, advanced functionality (such as participation in externally managed transactions), and compatibility with Java EE environments. You can customize the cache level of the container. Note that, when no caching is enabled, @@ -1849,19 +1841,19 @@ a simple `BackOff` implementation retries every five seconds. You can specify a custom `BackOff` implementation for more fine-grained recovery options. See api-spring-framework/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example. -NOTE: Like its sibling (<>), `DefaultMessageListenerContainer` -supports native JMS transactions and allows for customizing the acknowledgment mode. -If feasible for your -scenario, This is strongly recommended over externally managed transactions -- that is, if you can live with occasional duplicate messages in case of the -JVM dying. Custom duplicate message detection steps in your business logic can cover -such situations -- for example, in the form of a business entity existence check or a protocol -table check. Any such arrangements are significantly more efficient than the -alternative: wrapping your entire processing with an XA transaction (through configuring -your `DefaultMessageListenerContainer` with an `JtaTransactionManager`) to cover the +NOTE: Like its sibling (<>), +`DefaultMessageListenerContainer` supports native JMS transactions and allows for +customizing the acknowledgment mode. If feasible for your scenario, This is strongly +recommended over externally managed transactions -- that is, if you can live with +occasional duplicate messages in case of the JVM dying. Custom duplicate message +detection steps in your business logic can cover such situations -- for example, +in the form of a business entity existence check or a protocol table check. +Any such arrangements are significantly more efficient than the alternative: +wrapping your entire processing with an XA transaction (through configuring your +`DefaultMessageListenerContainer` with an `JtaTransactionManager`) to cover the reception of the JMS message as well as the execution of the business logic in your message listener (including database operations etc). - IMPORTANT: The default `AUTO_ACKNOWLEDGE` mode does not provide proper reliability guarantees. Messages can get lost when listener execution fails (since the provider automatically acknowledges each message after listener invocation, with no exceptions to be propagated to @@ -1875,14 +1867,15 @@ reliability needs (for example, for reliable queue handling and durable topic su Spring provides a `JmsTransactionManager` that manages transactions for a single JMS `ConnectionFactory`. This lets JMS applications leverage the managed-transaction -features of Spring, as described in <>. +features of Spring, as described in +<>. The `JmsTransactionManager` performs local resource transactions, binding a JMS Connection/Session pair from the specified `ConnectionFactory` to the thread. `JmsTemplate` automatically detects such transactional resources and operates on them accordingly. -In a Java EE environment, the `ConnectionFactory` pools Connection and Session instances, so -those resources are efficiently reused across transactions. In a standalone environment, +In a Java EE environment, the `ConnectionFactory` pools Connection and Session instances, +so those resources are efficiently reused across transactions. In a standalone environment, using Spring's `SingleConnectionFactory` result in a shared JMS `Connection`, with each transaction having its own independent `Session`. Alternatively, consider the use of a provider-specific pooling adapter, such as ActiveMQ's `PooledConnectionFactory` @@ -2065,20 +2058,19 @@ potentially be blocked indefinitely. The `receiveTimeout` property specifies how the receiver should wait before giving up waiting for a message. -[[jms-asynchronousMessageReception]] +[[jms-receiving-async]] ==== Asynchronous reception: Message-Driven POJOs NOTE: Spring also supports annotated-listener endpoints through the use of the `@JmsListener` -annotation and provides an open infrastructure to register endpoints programmatically. This -is, by far, the most convenient way to setup an asynchronous receiver. See -<> for more details. +annotation and provides an open infrastructure to register endpoints programmatically. +This is, by far, the most convenient way to setup an asynchronous receiver. +See <> for more details. In a fashion similar to a Message-Driven Bean (MDB) in the EJB world, the Message-Driven POJO (MDP) acts as a receiver for JMS messages. The one restriction (but see -<>) on an MDP is that it must -implement the `javax.jms.MessageListener` interface. Note that, if -your POJO receives messages on multiple threads, it is important to -ensure that your implementation is thread-safe. +<>) on an MDP is that it must implement +the `javax.jms.MessageListener` interface. Note that, if your POJO receives messages +on multiple threads, it is important to ensure that your implementation is thread-safe. The following example shows a simple implementation of an MDP: @@ -2572,7 +2564,7 @@ container factory. See the javadoc of classes that implement {api-spring-framework}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`] for details and examples. -If you prefer <>, you can use the `` +If you prefer <>, you can use the `` element, as the following example shows: ==== @@ -2717,7 +2709,7 @@ annotate the payload with `@Valid` and configure the necessary validator, as the [[jms-annotated-response]] ==== Response Management -The existing support in <> +The existing support in <> already lets your method have a non-`void` return type. When that is the case, the result of the invocation is encapsulated in a `javax.jms.Message`, sent either in the destination specified in the `JMSReplyTo` header of the original message or in the default destination configured on @@ -2838,8 +2830,8 @@ namespace elements, you need to reference the JMS schema, as the following examp The namespace consists of three top-level elements: ``, `` and ``. `` enables the use of <>. `` and `` -define shared listener container configuration and can contain `` child elements. The -following example shows a basic configuration for two listeners: +define shared listener container configuration and can contain `` child elements. +The following example shows a basic configuration for two listeners: ==== [source,xml,indent=0] @@ -2858,8 +2850,8 @@ following example shows a basic configuration for two listeners: The preceding example is equivalent to creating two distinct listener container bean definitions and two distinct `MessageListenerAdapter` bean definitions, as shown in <>. In addition to the attributes shown -in the preceding example, the `listener` element can contain several optional ones. The following table -describes all of the available attributes: +in the preceding example, the `listener` element can contain several optional ones. +The following table describes all of the available attributes: [[jms-namespace-listener-tbl]] .Attributes of the JMS element @@ -3127,14 +3119,13 @@ The following table describes the available configuration options for the JCA va [[jmx]] == JMX -The JMX (Java Management Extensions) support in Spring provides features that let you easily and transparently -integrate your Spring application into a JMX infrastructure. +The JMX (Java Management Extensions) support in Spring provides features that let you +easily and transparently integrate your Spring application into a JMX infrastructure. .JMX? **** -This chapter is not an introduction to JMX. It does not try to explain -why you might want to use JMX. If -you are new to JMX, see <> at the end of this chapter. +This chapter is not an introduction to JMX. It does not try to explain why you might want +to use JMX. If you are new to JMX, see <> at the end of this chapter. **** Specifically, Spring's JMX support provides four core features: @@ -3242,11 +3233,12 @@ the export happens or disable automatic registration by setting the `autoStartup [[jmx-exporting-mbeanserver]] ==== Creating an MBeanServer -The configuration shown in the <> assumes that the application is running in an environment that -has one (and only one) `MBeanServer` already running. In this case, Spring tries -to locate the running `MBeanServer` and register your beans with that server (if any). -This behavior is useful when your application runs inside a container (such as -Tomcat or IBM WebSphere) that has its own `MBeanServer`. +The configuration shown in the <> assumes that the +application is running in an environment that has one (and only one) `MBeanServer` +already running. In this case, Spring tries to locate the running `MBeanServer` and +register your beans with that server (if any). This behavior is useful when your +application runs inside a container (such as Tomcat or IBM WebSphere) that has its +own `MBeanServer`. However, this approach is of no use in a standalone environment or when running inside a container that does not provide an `MBeanServer`. To address this, you can create an @@ -3323,7 +3315,7 @@ be used, as the following example shows: For platforms or cases where the existing `MBeanServer` has a dynamic (or unknown) `agentId` that is retrieved through lookup methods, you should use -<>, +<>, as the following example shows: ==== @@ -3375,8 +3367,8 @@ property to `true`, as the following example shows: ---- ==== -In the preceding example, the bean called `spring:mbean=true` is already a valid JMX MBean and is -automatically registered by Spring. By default, a bean that is autodetected for JMX +In the preceding example, the bean called `spring:mbean=true` is already a valid JMX MBean +and is automatically registered by Spring. By default, a bean that is autodetected for JMX registration has its bean name used as the `ObjectName`. You can override this behavior, as detailed in <>. @@ -3457,12 +3449,13 @@ behavior to the `REPLACE_EXISTING` behavior: [[jmx-interface]] === Controlling the Management Interface of Your Beans -In the example in the <>, you had little control over the management interface of your -bean. All of the `public` properties and methods of each exported bean were exposed -as JMX attributes and operations, respectively. To exercise finer-grained control over -exactly which properties and methods of your exported beans are actually exposed as JMX -attributes and operations, Spring JMX provides a comprehensive and extensible mechanism -for controlling the management interfaces of your beans. +In the example in the <>, +you had little control over the management interface of your bean. All of the `public` +properties and methods of each exported bean were exposed as JMX attributes and +operations, respectively. To exercise finer-grained control over exactly which +properties and methods of your exported beans are actually exposed as JMX attributes +and operations, Spring JMX provides a comprehensive and extensible mechanism for +controlling the management interfaces of your beans. [[jmx-interface-assembler]] @@ -3473,23 +3466,23 @@ Behind the scenes, the `MBeanExporter` delegates to an implementation of the responsible for defining the management interface of each bean that is exposed. The default implementation, `org.springframework.jmx.export.assembler.SimpleReflectiveMBeanInfoAssembler`, -defines a management interface that exposes all public properties and methods (as you -saw in the examples in the preceding sections). Spring provides two additional implementations of the -`MBeanInfoAssembler` interface that let you control the generated management -interface by using either source-level metadata or any arbitrary interface. +defines a management interface that exposes all public properties and methods +(as you saw in the examples in the preceding sections). Spring provides two +additional implementations of the `MBeanInfoAssembler` interface that let you +control the generated management interface by using either source-level metadata +or any arbitrary interface. [[jmx-interface-metadata]] ==== Using Source-level Metadata: Java Annotations -By using the `MetadataMBeanInfoAssembler`, you can define the management interfaces for your -beans by using source-level metadata. The reading of metadata is encapsulated by the -`org.springframework.jmx.export.metadata.JmxAttributeSource` interface. Spring JMX -provides a default implementation that uses Java annotations, namely -`org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource`. You must configure the -`MetadataMBeanInfoAssembler` with an implementation instance of -the `JmxAttributeSource` interface for it to function correctly (there is no -default). +By using the `MetadataMBeanInfoAssembler`, you can define the management interfaces +for your beans by using source-level metadata. The reading of metadata is encapsulated +by the `org.springframework.jmx.export.metadata.JmxAttributeSource` interface. +Spring JMX provides a default implementation that uses Java annotations, namely +`org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource`. +You must configure the `MetadataMBeanInfoAssembler` with an implementation instance of +the `JmxAttributeSource` interface for it to function correctly (there is no default). To mark a bean for export to JMX, you should annotate the bean class with the `ManagedResource` annotation. You must mark each method you wish to expose as an operation @@ -3567,21 +3560,20 @@ used in <>: ---- ==== -In the preceding example, you can see that the `JmxTestBean` class is marked with the `ManagedResource` -annotation and that this `ManagedResource` annotation is configured with a set of -properties. These properties can be used to configure various aspects of the MBean that -is generated by the `MBeanExporter` and are explained in greater detail later in -<>. +In the preceding example, you can see that the `JmxTestBean` class is marked with the +`ManagedResource` annotation and that this `ManagedResource` annotation is configured +with a set of properties. These properties can be used to configure various aspects +of the MBean that is generated by the `MBeanExporter` and are explained in greater +detail later in <>. -Both the `age` and `name` properties are annotated with the -`ManagedAttribute` annotation, but, in the case of the `age` property, only the getter is -marked. This causes both of these properties to be included in the management -interface as attributes, but the `age` attribute is read-only. +Both the `age` and `name` properties are annotated with the `ManagedAttribute` +annotation, but, in the case of the `age` property, only the getter is marked. +This causes both of these properties to be included in the management interface +as attributes, but the `age` attribute is read-only. -Finally, the `add(int, int)` method is marked with the -`ManagedOperation` attribute, whereas the `dontExposeMe()` method is not. This causes -the management interface to contain only one operation (`add(int, int)`) when you use the -`MetadataMBeanInfoAssembler`. +Finally, the `add(int, int)` method is marked with the `ManagedOperation` attribute, +whereas the `dontExposeMe()` method is not. This causes the management interface to +contain only one operation (`add(int, int)`) when you use the `MetadataMBeanInfoAssembler`. The following configuration shows how you can configure the `MBeanExporter` to use the `MetadataMBeanInfoAssembler`: @@ -3753,10 +3745,10 @@ bean name as the `ObjectName`, which results in a configuration similar to the f ---- ==== -Notice that, in the preceding configuration, no beans are passed to the `MBeanExporter`. However, -the `JmxTestBean` is still registered, since it is marked with the `ManagedResource` -attribute and the `MetadataMBeanInfoAssembler` detects this and votes to include it. The -only problem with this approach is that the name of the `JmxTestBean` now has business +Notice that, in the preceding configuration, no beans are passed to the `MBeanExporter`. +However, the `JmxTestBean` is still registered, since it is marked with the `ManagedResource` +attribute and the `MetadataMBeanInfoAssembler` detects this and votes to include it. +The only problem with this approach is that the name of the `JmxTestBean` now has business meaning. You can address this issue by changing the default behavior for `ObjectName` creation as defined in <>. @@ -4016,7 +4008,7 @@ example, the generated `ObjectName` for the following bean would be [[jmx-context-mbeanexport]] ==== Configuring Annotation-based MBean Export -If you prefer to use <> to define +If you prefer to use <> to define your management interfaces, a convenience subclass of `MBeanExporter` is available: `AnnotationMBeanExporter`. When defining an instance of this subclass, you no longer need the `namingStrategy`, `assembler`, and `attributeSource` configuration, @@ -4639,10 +4631,10 @@ The aim of the Spring CCI support is to provide classes to access a CCI connecto typical Spring style, using the Spring Framework's general resource and transaction management facilities. -NOTE: The client side of connectors does not alway use CCI. Some connectors expose their own -APIs, providing a JCA resource adapter to use the system contracts of a Java EE -container (connection pooling, global transactions, and security). Spring does not offer -special support for such connector-specific APIs. +NOTE: The client side of connectors does not always use CCI. Some connectors expose their own +APIs, providing a JCA resource adapter to use the system contracts of a Java EE container +(connection pooling, global transactions, and security). Spring does not offer special +support for such connector-specific APIs. @@ -4839,8 +4831,8 @@ You can use an intermediary `ConnectionSpecConnectionFactoryAdapter` that the [[cci-using]] === Using Spring's CCI Access Support -This section describes how to use Spring's support for CCI to achieve various purposes. It -includes the following topics: +This section describes how to use Spring's support for CCI to achieve various purposes. +It includes the following topics: * <> * <> @@ -4855,14 +4847,13 @@ includes the following topics: ==== Record Conversion One of the aims of Spring's JCA CCI support is to provide convenient facilities for -manipulating CCI records. You can specify the strategy to create records and -extract datas from records, for use with Spring's `CciTemplate`. The -interfaces described in this section configure the strategy to use input and output records if you do not want +manipulating CCI records. You can specify the strategy to create records and extract +data from records, for use with Spring's `CciTemplate`. The interfaces described in +this section configure the strategy to use input and output records if you do not want to work with records directly in your application. -To create an input `Record`, you can use a dedicated implementation -of the `RecordCreator` interface. The following listing shows the `RecordCreator` -interface definition: +To create an input `Record`, you can use a dedicated implementation of the `RecordCreator` +interface. The following listing shows the `RecordCreator` interface definition: ==== [source,java,indent=0] @@ -4998,9 +4989,10 @@ With the first approach, the following methods (which directly correspond to tho ---- ==== -With the second approach, we need to specify the record creation and record extraction -strategies as arguments. The interfaces used are those describe in the <>. The following listing shows the corresponding `CciTemplate` methods: +With the second approach, we need to specify the record creation and record +extraction strategies as arguments. The interfaces used are those describe in the +<>. The following +listing shows the corresponding `CciTemplate` methods: ==== [source,java,indent=0] @@ -5094,14 +5086,14 @@ The following example shows how to use `CciDaoSupport`: ==== Automatic Output Record Generation If the connector you use supports only the `Interaction.execute(..)` method with input and -output records as parameters (that is, it requires the desired output record to be -passed in instead of returning an appropriate output record), you can set the -`outputRecordCreator` property of the `CciTemplate` to automatically generate an output -record to be filled by the JCA connector when the response is received. This record is -then returned to the caller of the template. - -This property holds an implementation of the <>, to be used for -that purpose. You must directly specify the `outputRecordCreator` property on +output records as parameters (that is, it requires the desired output record to be passed +in instead of returning an appropriate output record), you can set the `outputRecordCreator` +property of the `CciTemplate` to automatically generate an output record to be filled by +the JCA connector when the response is received. This record is then returned to the caller +of the template. + +This property holds an implementation of the <>, +to be used for that purpose. You must directly specify the `outputRecordCreator` property on the `CciTemplate`. The following example shows how to do so: ==== @@ -5112,8 +5104,9 @@ the `CciTemplate`. The following example shows how to do so: ---- ==== -Alternatively (and we recommend this approach), in the Spring configuration, if the `CciTemplate` is configured as a -dedicated bean instance, you can define beans in the following fashion: +Alternatively (and we recommend this approach), in the Spring configuration, if the +`CciTemplate` is configured as a dedicated bean instance, you can define beans in the +following fashion: ==== [source,xml,indent=0] @@ -5392,14 +5385,13 @@ the following example: The `org.springframework.jca.cci.object` package contains support classes that let you access the EIS in a different style: through reusable operation objects, analogous to -Spring's JDBC operation objects (see the <>). -This usually encapsulates the CCI API. An application-level input object is passed to -the operation object, so it can construct the input record and then convert the -received record data to an application-level output object and return it. +Spring's JDBC operation objects (see the <>). This usually encapsulates the CCI API. An application-level +input object is passed to the operation object, so it can construct the input record and +then convert the received record data to an application-level output object and return it. -NOTE: This approach is internally based on the `CciTemplate` class and the -`RecordCreator` or `RecordExtractor` interfaces, reusing the machinery of Spring's -core CCI support. +NOTE: This approach is internally based on the `CciTemplate` class and the `RecordCreator` +or `RecordExtractor` interfaces, reusing the machinery of Spring's core CCI support. [[cci-object-mapping-record]] @@ -5410,9 +5402,8 @@ represents a specific, pre-configured operation as an object. It provides two te methods to specify how to convert an input object to an input record and how to convert an output record to an output object (record mapping): -* `createInputRecord(..)`: To specify how to convert an input object to an input `Record` -* `extractOutputData(..)`: To specify how to extract an output object from an output - `Record` +* `createInputRecord(..)`: to specify how to convert an input object to an input `Record` +* `extractOutputData(..)`: to specify how to extract an output object from an output `Record` The following listing shows the signatures of these methods: @@ -5513,9 +5504,9 @@ listing shows the relevant method signatures: ==== Automatic Output Record Generation As every `MappingRecordOperation` subclass is based on CciTemplate internally, the same -way to automatically generate output records as with `CciTemplate` is available. Every -operation object provides a corresponding `setOutputRecordCreator(..)` method. For -further information, see <>. +way to automatically generate output records as with `CciTemplate` is available. +Every operation object provides a corresponding `setOutputRecordCreator(..)` method. +For further information, see <>. [[cci-object-summary]] @@ -5833,7 +5824,7 @@ the actual execution strategy. You can switch between `JtaTransactionManager` an `CciLocalTransactionManager` as needed, keeping your transaction demarcation as-is. For more information on Spring's transaction facilities, see -<>. +<>. @@ -6030,9 +6021,9 @@ callback interface. In the following example, the `mailSender` property is of ty ---- ==== -NOTE: The mail code is a crosscutting concern and could well be a candidate for refactoring -into a <>, which then could be executed at appropriate -joinpoints on the `OrderManager` target. +NOTE: The mail code is a crosscutting concern and could well be a candidate for +refactoring into a <>, which then could +be executed at appropriate joinpoints on the `OrderManager` target. The Spring Framework's mail support ships with the standard JavaMail implementation. See the relevant javadoc for more information. @@ -6044,8 +6035,8 @@ See the relevant javadoc for more information. A class that comes in pretty handy when dealing with JavaMail messages is `org.springframework.mail.javamail.MimeMessageHelper`, which shields you from -having to use the verbose JavaMail API. Using the `MimeMessageHelper`, it is pretty easy -to create a `MimeMessage`, as the following example shows: +having to use the verbose JavaMail API. Using the `MimeMessageHelper`, it is +pretty easy to create a `MimeMessage`, as the following example shows: ==== [source,java,indent=0] @@ -6688,8 +6679,8 @@ in combination with a custom pointcut. ==== Executor Qualification with `@Async` By default, when specifying `@Async` on a method, the executor that is used is the -one <>, i.e. -the "`annotation-driven`" element if you are using XML or your `AsyncConfigurer` +one <>, +i.e. the "`annotation-driven`" element if you are using XML or your `AsyncConfigurer` implementation, if any. However, you can use the `value` attribute of the `@Async` annotation when you need to indicate that an executor other than the default should be used when executing a given method. The following example shows how to do so: @@ -6780,15 +6771,16 @@ The following creates a `ThreadPoolTaskExecutor` instance: ---- ==== -As with the scheduler shown in the <>, the value provided for the `id` attribute is used as -the prefix for thread names within the pool. As far as the pool size is concerned, the -`executor` element supports more configuration options than the `scheduler` element. For -one thing, the thread pool for a `ThreadPoolTaskExecutor` is itself more configurable. -Rather than only a single size, an executor's thread pool can have different values for -the core and the max size. If you provide a single value, the executor -has a fixed-size thread pool (the core and max sizes are the same). However, the -`executor` element's `pool-size` attribute also accepts a range in the form of `min-max`. -The following example sets a minimum value of `5` and a maximum value of `25`: +As with the scheduler shown in the <>, +the value provided for the `id` attribute is used as the prefix for thread names within +the pool. As far as the pool size is concerned, the `executor` element supports more +configuration options than the `scheduler` element. For one thing, the thread pool for +a `ThreadPoolTaskExecutor` is itself more configurable. Rather than only a single size, +an executor's thread pool can have different values for the core and the max size. +If you provide a single value, the executor has a fixed-size thread pool (the core and +max sizes are the same). However, the `executor` element's `pool-size` attribute also +accepts a range in the form of `min-max`. The following example sets a minimum value of +`5` and a maximum value of `25`: ==== [source,xml,indent=0] @@ -6805,13 +6797,13 @@ In the preceding configuration, a `queue-capacity` value has also been provided. The configuration of the thread pool should also be considered in light of the executor's queue capacity. For the full description of the relationship between pool size and queue capacity, see the documentation for -https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`]. +https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`]. The main idea is that, when a task is submitted, the executor first tries to use a -free thread if the number of active threads is currently less than the core size. If the -core size has been reached, the task is added to the queue, as long as its +free thread if the number of active threads is currently less than the core size. +If the core size has been reached, the task is added to the queue, as long as its capacity has not yet been reached. Only then, if the queue's capacity has been -reached, does the executor create a new thread beyond the core size. If the max size has -also been reached, then the executor rejects the task. +reached, does the executor create a new thread beyond the core size. If the max size +has also been reached, then the executor rejects the task. By default, the queue is unbounded, but this is rarely the desired configuration, because it can lead to `OutOfMemoryErrors` if enough tasks are added to that queue while @@ -6821,20 +6813,19 @@ thread beyond the core size, a queue must have a finite capacity for the thread grow beyond the core size (this is why a fixed-size pool is the only sensible case when using an unbounded queue). -Consider the -case, as mentioned above, when a task is rejected. By default, when a task is rejected, -a thread pool executor throws a `TaskRejectedException`. However, the rejection -policy is actually configurable. The exception is thrown when using the default -rejection policy, which is the `AbortPolicy` implementation. For applications where some -tasks can be skipped under heavy load, you can instead configure either `DiscardPolicy` or -`DiscardOldestPolicy`. Another option that works well for -applications that need to throttle the submitted tasks under heavy load is the -`CallerRunsPolicy`. Instead of throwing an exception or discarding tasks, that policy -forces the thread that is calling the submit method to run the task itself. -The idea is that such a caller is busy while running that task and not able to -submit other tasks immediately. Therefore, it provides a simple way to throttle the -incoming load while maintaining the limits of the thread pool and queue. Typically, this -allows the executor to "`catch up`" on the tasks it is handling and thereby frees up some +Consider the case, as mentioned above, when a task is rejected. By default, when a +task is rejected, a thread pool executor throws a `TaskRejectedException`. However, +the rejection policy is actually configurable. The exception is thrown when using +the default rejection policy, which is the `AbortPolicy` implementation. +For applications where some tasks can be skipped under heavy load, you can instead +configure either `DiscardPolicy` or `DiscardOldestPolicy`. Another option that works +well for applications that need to throttle the submitted tasks under heavy load is +the `CallerRunsPolicy`. Instead of throwing an exception or discarding tasks, +that policy forces the thread that is calling the submit method to run the task itself. +The idea is that such a caller is busy while running that task and not able to submit +other tasks immediately. Therefore, it provides a simple way to throttle the incoming +load while maintaining the limits of the thread pool and queue. Typically, this allows +the executor to "`catch up`" on the tasks it is handling and thereby frees up some capacity on the queue, in the pool, or both. You can choose any of these options from an enumeration of values available for the `rejection-policy` attribute on the `executor` element. @@ -7127,12 +7118,12 @@ javadoc for more information. [[cache]] == Cache Abstraction -Since version 3.1, the Spring Framework provides support for transparently adding caching -to an existing Spring application. Similar to the <> -support, the caching abstraction allows consistent use of various caching solutions with minimal -impact on the code. +Since version 3.1, the Spring Framework provides support for transparently adding caching to +an existing Spring application. Similar to the <> +support, the caching abstraction allows consistent use of various caching solutions with +minimal impact on the code. -As from Spring 4.1, the cache abstraction has been significantly improved with the +As from Spring 4.1, the cache abstraction has been significantly extended with the support of <> and more customization options. @@ -7143,17 +7134,17 @@ support of <> and more customization options. .Cache vs Buffer **** -The terms, "`buffer`" and "`cache,`" tend to be used interchangeably. Note, however, that they -represent different things. Traditionally, a buffer is used as an intermediate temporary -store for data between a fast and a slow entity. As one party would has to wait for -the other (which affects performance), the buffer alleviates this by allowing entire blocks of -data to move at once rather then in small chunks. The data is written and read only once -from the buffer. Furthermore, the buffers are visible to at least one party that is -aware of it. +The terms, "`buffer`" and "`cache,`" tend to be used interchangeably. Note, however, +that they represent different things. Traditionally, a buffer is used as an intermediate +temporary store for data between a fast and a slow entity. As one party would has to wait +for the other (which affects performance), the buffer alleviates this by allowing entire +blocks of data to move at once rather then in small chunks. The data is written and read +only once from the buffer. Furthermore, the buffers are visible to at least one party +that is aware of it. A cache, on the other hand, is, by definition, hidden, and neither party is aware that -caching occurs. It also improves performance but does so by letting the same data -be read multiple times in a fast fashion. +caching occurs. It also improves performance but does so by letting the same data be +read multiple times in a fast fashion. You can find a further explanation of the differences between a buffer and a cache http://en.wikipedia.org/wiki/Cache_(computing)#The_difference_between_buffer_and_cache[here]. @@ -7184,27 +7175,26 @@ the caching logic but does not provide the actual data store. This abstraction i materialized by the `org.springframework.cache.Cache` and `org.springframework.cache.CacheManager` interfaces. -Spring provides <> of that abstraction: -JDK `java.util.concurrent.ConcurrentMap` based caches, -http://ehcache.org/[Ehcache 2.x], Gemfire cache, -https://github.com/ben-manes/caffeine/wiki[Caffeine], and JSR-107 compliant -caches (such as Ehcache 3.x). See <> for more information on plugging in -other cache stores and providers. +Spring provides <> of that abstraction: +JDK `java.util.concurrent.ConcurrentMap` based caches, http://ehcache.org/[Ehcache 2.x], +Gemfire cache, https://github.com/ben-manes/caffeine/wiki[Caffeine], and JSR-107 +compliant caches (such as Ehcache 3.x). See <> for more information on +plugging in other cache stores and providers. -IMPORTANT: The caching abstraction has no special handling for multi-threaded and multi-process -environments, as such features are handled by the cache implementation. . +IMPORTANT: The caching abstraction has no special handling for multi-threaded and +multi-process environments, as such features are handled by the cache implementation. . If you have a multi-process environment (that is, an application deployed on several nodes), -you need to configure your cache provider accordingly. Depending on your use cases, -a copy of the same data on several nodes can be enough. However, if you change the data during +you need to configure your cache provider accordingly. Depending on your use cases, a copy +of the same data on several nodes can be enough. However, if you change the data during the course of the application, you may need to enable other propagation mechanisms. Caching a particular item is a direct equivalent of the typical get-if-not-found-then- -proceed-and-put-eventually code blocks found with programmatic cache interaction. No locks -are applied, and several threads may try to load the same item concurrently. The same applies -to eviction. If several threads are trying to update or evict data concurrently, you may -use stale data. Certain cache providers offer advanced features in that area. See -the documentation of your cache provider for more details. +proceed-and-put-eventually code blocks found with programmatic cache interaction. +No locks are applied, and several threads may try to load the same item concurrently. +The same applies to eviction. If several threads are trying to update or evict data +concurrently, you may use stale data. Certain cache providers offer advanced features +in that area. See the documentation of your cache provider for more details. To use the cache abstraction, you need to take care of two aspects: @@ -7317,17 +7307,17 @@ At first glance, while the two `boolean` arguments influence the way the book is they are no use for the cache. Furthermore, what if only one of the two is important while the other is not? -For such cases, the `@Cacheable` annotation lets you specify how the key is -generated through its `key` attribute. You can use <> to -pick the arguments of interest (or their nested properties), perform operations, or even +For such cases, the `@Cacheable` annotation lets you specify how the key is generated +through its `key` attribute. You can use <> to pick the +arguments of interest (or their nested properties), perform operations, or even invoke arbitrary methods without having to write any code or implement any interface. This is the recommended approach over the -<>, since methods tend to be +<>, since methods tend to be quite different in signatures as the code base grows. While the default strategy might work for some methods, it rarely works for all methods. The following examples ise various SpEL declarations (if you are not familiar with SpEL, -do yourself a favor and read <>): +do yourself a favor and read <>): ==== [source,java,indent=0] @@ -7393,10 +7383,10 @@ set the `cacheManager` to use for each operation, as the following example shows ==== You can also replace the `CacheResolver` entirely in a fashion similar to that of -replacing <>. The -resolution is requested for every cache operation, letting -the implementation actually resolve the caches to use based on -runtime arguments. The following example shows how to specify a `CacheResolver`: +replacing <>. The resolution is +requested for every cache operation, letting the implementation actually resolve +the caches to use based on runtime arguments. The following example shows how to +specify a `CacheResolver`: ==== [source,java,indent=0] @@ -7502,11 +7492,10 @@ should use the safe navigation operator. [[cache-spel-context]] ===== Available Caching SpEL Evaluation Context -Each `SpEL` expression evaluates against a dedicated -<>. In addition to the built-in parameters, the -framework provides dedicated caching-related metadata, such as the argument names. The following -table describes the items made available to the context so that you can use them for key and -conditional computations: +Each `SpEL` expression evaluates against a dedicated <>. +In addition to the built-in parameters, the framework provides dedicated caching-related +metadata, such as the argument names. The following table describes the items made +available to the context so that you can use them for key and conditional computations: [[cache-spel-context-tbl]] .Cache SpEL available metadata @@ -7674,12 +7663,12 @@ comes into play. The following examples uses `@CacheConfig` to set the name of t <1> Using `@CacheConfig` to set the name of the cache. ==== -`@CacheConfig` is a class-level annotation that allows sharing the cache names, the custom -`KeyGenerator`, the custom `CacheManager`, and the custom `CacheResolver`. Placing -this annotation on the class does not turn on any caching operation. +`@CacheConfig` is a class-level annotation that allows sharing the cache names, +the custom `KeyGenerator`, the custom `CacheManager`, and the custom `CacheResolver`. +Placing this annotation on the class does not turn on any caching operation. -An operation-level customization always overrides a customization set on `@CacheConfig`. Therefore, this -gives three levels of customizations for each cache operation: +An operation-level customization always overrides a customization set on `@CacheConfig`. +Therefore, this gives three levels of customizations for each cache operation: * Globally configured, available for `CacheManager`, `KeyGenerator`. * At the class level, using `@CacheConfig`. @@ -7790,7 +7779,7 @@ required to implement `CachingConfigurer`, see the classes annotated with the `@Cacheable` or `@CacheEvict` annotations. If the `proxy-target-class` attribute is set to `true`, class-based proxies are created. If `proxy-target-class` is `false` or if the attribute is omitted, standard JDK - interface-based proxies are created. (See <> + interface-based proxies are created. (See <> for a detailed examination of the different proxy types.) | `order` @@ -7798,42 +7787,41 @@ required to implement `CachingConfigurer`, see the | Ordered.LOWEST_PRECEDENCE | Defines the order of the cache advice that is applied to beans annotated with `@Cacheable` or `@CacheEvict`. (For more information about the rules related to - ordering AOP advice, see <>.) + ordering AOP advice, see <>.) No specified ordering means that the AOP subsystem determines the order of the advice. |=== NOTE: `` looks for `@Cacheable/@CachePut/@CacheEvict/@Caching` -only on beans in the same application context in which it is defined. This means that, if you put -`` in a `WebApplicationContext` for a `DispatcherServlet`, it -checks for beans only in your controllers, not your services. -See <> for more information. +only on beans in the same application context in which it is defined. This means that, +if you put `` in a `WebApplicationContext` for a +`DispatcherServlet`, it checks for beans only in your controllers, not your services. +See <> for more information. .Method visibility and cache annotations **** When you use proxies, you should apply the cache annotations only to methods with public visibility. If you do annotate protected, private, or package-visible methods with these annotations, no error is raised, but the annotated method does not exhibit -the configured caching settings. Consider using AspectJ (see the rest of this section) if you need to -annotate non-public methods, as it changes the bytecode itself. +the configured caching settings. Consider using AspectJ (see the rest of this section) +if you need to annotate non-public methods, as it changes the bytecode itself. **** TIP: Spring recommends that you only annotate concrete classes (and methods of concrete -classes) with the `@Cache{asterisk}` annotation, as opposed to annotating interfaces. You -certainly can place the `@Cache{asterisk}` annotation on an interface (or an interface method), -but this works only as you would expect it to if you use interface-based proxies. -The fact that Java annotations are not inherited from interfaces means that, if you -use class-based proxies (`proxy-target-class="true"`) or the weaving-based aspect -(`mode="aspectj"`), the caching settings are not recognized by the proxying and -weaving infrastructure, and the object is not wrapped in a caching proxy, which -would be decidedly bad. +classes) with the `@Cache{asterisk}` annotation, as opposed to annotating interfaces. +You certainly can place the `@Cache{asterisk}` annotation on an interface (or an interface +method), but this works only as you would expect it to if you use interface-based proxies. +The fact that Java annotations are not inherited from interfaces means that, if you use +class-based proxies (`proxy-target-class="true"`) or the weaving-based aspect +(`mode="aspectj"`), the caching settings are not recognized by the proxying and weaving +infrastructure, and the object is not wrapped in a caching proxy. NOTE: In proxy mode (the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation (in effect, a method within the target object that calls another method of the target object) does not lead to actual caching at runtime even if the invoked method is marked with `@Cacheable`. Consider -using the `aspectj` mode in this case. Also, the proxy must be fully initialized to provide -the expected behavior, so you should not rely on this feature in your initialization -code (that is, `@PostConstruct`). +using the `aspectj` mode in this case. Also, the proxy must be fully initialized to +provide the expected behavior, so you should not rely on this feature in your +initialization code (that is, `@PostConstruct`). [[cache-annotation-stereotype]] @@ -7844,19 +7832,20 @@ code (that is, `@PostConstruct`). This feature works only with the proxy-based approach but can be enabled with a bit of extra effort by using AspectJ. -The `spring-aspects` module defines an aspect for the standard annotations only. If you -have defined your own annotations, you also need to define an aspect for those. Check -`AnnotationCacheAspect` for an example. +The `spring-aspects` module defines an aspect for the standard annotations only. +If you have defined your own annotations, you also need to define an aspect for +those. Check `AnnotationCacheAspect` for an example. **** The caching abstraction lets you use your own annotations to identify what method -triggers cache population or eviction. This is quite handy as a template mechanism, as it -eliminates the need to duplicate cache annotation declarations, which is especially useful if the -key or condition are specified or if the foreign imports (`org.springframework`) are -not allowed in your code base. Similarly to the rest of the -<> annotations, you can use `@Cacheable`, `@CachePut`, -`@CacheEvict`, and `@CacheConfig` as <> -(that is, annotations that can annotate other annotations). In the following example, we replace a common +triggers cache population or eviction. This is quite handy as a template mechanism, +as it eliminates the need to duplicate cache annotation declarations, which is +especially useful if the key or condition are specified or if the foreign imports +(`org.springframework`) are not allowed in your code base. Similarly to the rest +of the <> annotations, you can +use `@Cacheable`, `@CachePut`, `@CacheEvict`, and `@CacheConfig` as +<> (that is, annotations that +can annotate other annotations). In the following example, we replace a common `@Cacheable` declaration with our own custom annotation: ==== @@ -7871,8 +7860,8 @@ not allowed in your code base. Similarly to the rest of the ---- ==== -In the preceding example, we have defined our own `SlowService` annotation, which itself is annotated with -`@Cacheable`. Now we can replace the following code: +In the preceding example, we have defined our own `SlowService` annotation, +which itself is annotated with `@Cacheable`. Now we can replace the following code: ==== [source,java,indent=0] @@ -7883,8 +7872,8 @@ In the preceding example, we have defined our own `SlowService` annotation, whic ---- ==== -The following example shows the custom annotation with which we can replace the preceding -code: +The following example shows the custom annotation with which we can replace the +preceding code: ==== [source,java,indent=0] @@ -7897,22 +7886,22 @@ code: Even though `@SlowService` is not a Spring annotation, the container automatically picks up its declaration at runtime and understands its meaning. Note that, as mentioned -<>, annotation-driven behavior needs to be enabled. +<>, annotation-driven behavior needs to be enabled. [[cache-jsr-107]] === JCache (JSR-107) Annotations -Since version 4.1, the caching abstraction fully supports the JCache -standard annotations: `@CacheResult`, `@CachePut`, `@CacheRemove`, and -`@CacheRemoveAll` as well as the `@CacheDefaults`, `@CacheKey`, and `@CacheValue` -companions. You can use these annotations without migrating your -cache store to JSR-107. The internal implementation uses Spring's caching abstraction -and provides default `CacheResolver` and `KeyGenerator` implementations that are -compliant with the specification. In other words, if you are already using Spring's -caching abstraction, you can switch to these standard annotations without changing -your cache storage (or configuration, for that matter). +Since version 4.1, Spring's caching abstraction fully supports the JCache standard +annotations: `@CacheResult`, `@CachePut`, `@CacheRemove`, and `@CacheRemoveAll` +as well as the `@CacheDefaults`, `@CacheKey`, and `@CacheValue` companions. +You can use these annotations even without migrating your cache store to JSR-107. +The internal implementation uses Spring's caching abstraction and provides default +`CacheResolver` and `KeyGenerator` implementations that are compliant with the +specification. In other words, if you are already using Spring's caching abstraction, +you can switch to these standard annotations without changing your cache storage +(or configuration, for that matter). [[cache-jsr-107-summary]] @@ -7935,8 +7924,8 @@ counterpart: | `@CachePut` | `@CachePut` | While Spring updates the cache with the result of the method invocation, JCache - requires that it be passed it as an argument that is annotated with `@CacheValue`. Due - to this difference, JCache allows updating the cache before or after the + requires that it be passed it as an argument that is annotated with `@CacheValue`. + Due to this difference, JCache allows updating the cache before or after the actual method invocation. | `@CacheEvict` @@ -7955,13 +7944,13 @@ counterpart: JCache has the notion of `javax.cache.annotation.CacheResolver`, which is identical to the Spring's `CacheResolver` interface, except that JCache supports only a single -cache. By default, a simple implementation retrieves the cache to use based on -the name declared on the annotation. It should be noted that, if no cache name -is specified on the annotation, a default is automatically generated. See the -javadoc of `@CacheResult#cacheName()` for more information. +cache. By default, a simple implementation retrieves the cache to use based on the +name declared on the annotation. It should be noted that, if no cache name is +specified on the annotation, a default is automatically generated. See the javadoc +of `@CacheResult#cacheName()` for more information. -`CacheResolver` instances are retrieved by a `CacheResolverFactory`. It is -possible to customize the factory for each cache operation, as the following example shows: +`CacheResolver` instances are retrieved by a `CacheResolverFactory`. It is possible +to customize the factory for each cache operation, as the following example shows: ==== [source,java,indent=0] @@ -7973,16 +7962,16 @@ possible to customize the factory for each cache operation, as the following exa <1> Customizing the factory for this operation. ==== -NOTE: For all referenced classes, Spring tries to locate a bean with the given type. If -more than one match exists, a new instance is created and can use the regular +NOTE: For all referenced classes, Spring tries to locate a bean with the given type. +If more than one match exists, a new instance is created and can use the regular bean lifecycle callbacks, such as dependency injection. Keys are generated by a `javax.cache.annotation.CacheKeyGenerator` that serves the same purpose as Spring's `KeyGenerator`. By default, all method arguments are taken into account, unless at least one parameter is annotated with `@CacheKey`. This is -similar to Spring's <>. For instance, the following are identical operations, one using Spring's -abstraction and the other using JCache: +similar to Spring's <>. For instance, the following are identical operations, one using +Spring's abstraction and the other using JCache: ==== [source,java,indent=0] @@ -7996,16 +7985,16 @@ abstraction and the other using JCache: ---- ==== -You can also specify the `CacheKeyResolver` on the operation, similar -to how you can specify the `CacheResolverFactory`. +You can also specify the `CacheKeyResolver` on the operation, similar to how you can +specify the `CacheResolverFactory`. JCache can manage exceptions thrown by annotated methods. This can prevent an update of the cache, but it can also cache the exception as an indicator of the failure instead of -calling the method again. Assume that `InvalidIsbnNotFoundException` is thrown if -the structure of the ISBN is invalid. This is a permanent failure (no book could ever be -retrieved with such a parameter). The following caches the exception so that further calls -with the same, invalid, ISBN throw the cached exception directly instead of invoking -the method again: +calling the method again. Assume that `InvalidIsbnNotFoundException` is thrown if the +structure of the ISBN is invalid. This is a permanent failure (no book could ever be +retrieved with such a parameter). The following caches the exception so that further +calls with the same, invalid, ISBN throw the cached exception directly instead of +invoking the method again: ==== [source,java,indent=0] @@ -8018,29 +8007,30 @@ the method again: ==== -==== Enabling JSR-107 support +==== Enabling JSR-107 Support You need do nothing specific to enable the JSR-107 support alongside Spring's declarative annotation support. Both `@EnableCaching` and the `cache:annotation-driven` element automatically enable the JCache support -if both the JSR-107 API and the `spring-context-support` module are present in -the classpath. +if both the JSR-107 API and the `spring-context-support` module are present +in the classpath. -NOTE: Depending on your use case, the choice is basically yours. You can even mix -and match services by using the JSR-107 API on some and using Spring's own -annotations on others. However, if these services impact the same -caches, you should use a consistent and identical key generation implementation. +NOTE: Depending on your use case, the choice is basically yours. You can even +mix and match services by using the JSR-107 API on some and using Spring's own +annotations on others. However, if these services impact the same caches, +you should use a consistent and identical key generation implementation. [[cache-declarative-xml]] === Declarative XML-based Caching -If annotations are not an option (perhaps due to having no access to the sources or no external code), you can -use XML for declarative caching. So, instead of annotating the methods for caching, you can -specify the target method and the caching directives externally (similar to the -declarative transaction management <>). -The example from the previous section can be translated into the following example: +If annotations are not an option (perhaps due to having no access to the sources +or no external code), you can use XML for declarative caching. So, instead of +annotating the methods for caching, you can specify the target method and the +caching directives externally (similar to the declarative transaction management +<>). The example +from the previous section can be translated into the following example: ==== [source,xml,indent=0] @@ -8067,26 +8057,25 @@ The example from the previous section can be translated into the following examp ==== In the preceding configuration, the `bookService` is made cacheable. The caching semantics -to apply are encapsulated in the `cache:advice` definition, which causes the -`findBooks` method to be used for putting data into the cache and the `loadBooks` method for -evicting data. Both definitions work against the `books` cache. +to apply are encapsulated in the `cache:advice` definition, which causes the `findBooks` +method to be used for putting data into the cache and the `loadBooks` method for evicting +data. Both definitions work against the `books` cache. The `aop:config` definition applies the cache advice to the appropriate points in the program by using the AspectJ pointcut expression (more information is available in -<>). -In the preceding example, all methods from the `BookService` are considered and -the cache advice is applied to them. +<>). In the preceding example, +all methods from the `BookService` are considered and the cache advice is applied to them. The declarative XML caching supports all of the annotation-based model, so moving between -the two should be fairly easy. Furthermore, both can be used inside the same -application. The XML-based approach does not touch the target code. However, it is -inherently more verbose. When dealing with classes that have overloaded methods that are -targeted for caching, identifying the proper methods does take an extra effort, since the -`method` argument is not a good discriminator. In these cases, you can use the AspectJ pointcut -to cherry pick the target methods and apply the appropriate caching -functionality. However, through XML, it is easier to apply package or group or interface-wide -caching (again, due to the AspectJ pointcut) and to create template-like definitions (as -we did in the preceding example by defining the target cache through the `cache:definitions` +the two should be fairly easy. Furthermore, both can be used inside the same application. +The XML-based approach does not touch the target code. However, it is inherently more +verbose. When dealing with classes that have overloaded methods that are targeted for +caching, identifying the proper methods does take an extra effort, since the `method` +argument is not a good discriminator. In these cases, you can use the AspectJ pointcut +to cherry pick the target methods and apply the appropriate caching functionality. +However, through XML, it is easier to apply package or group or interface-wide caching +(again, due to the AspectJ pointcut) and to create template-like definitions (as we did +in the preceding example by defining the target cache through the `cache:definitions` `cache` attribute). @@ -8094,9 +8083,9 @@ we did in the preceding example by defining the target cache through the `cache: [[cache-store-configuration]] === Configuring the Cache Storage -The cache abstraction provides several storage integration options. To use -them, you need to declare an appropriate `CacheManager` (an entity that -controls and manages `Cache` instances and that can be used to retrieve these for storage). +The cache abstraction provides several storage integration options. To use them, you need +to declare an appropriate `CacheManager` (an entity that controls and manages `Cache` +instances and that can be used to retrieve these for storage). [[cache-store-configuration-jdk]] @@ -8120,14 +8109,14 @@ as a backing `Cache` store. The following example shows how to configure two cac ---- -The preceding snippet uses the `SimpleCacheManager` to create a `CacheManager` for the two -nested `ConcurrentMapCache` instances named `default` and `books`. Note that the +The preceding snippet uses the `SimpleCacheManager` to create a `CacheManager` for the +two nested `ConcurrentMapCache` instances named `default` and `books`. Note that the names are configured directly for each cache. As the cache is created by the application, it is bound to its lifecycle, making it -suitable for basic use cases, tests, or simple applications. The cache scales well and is -very fast, but it does not provide any management, persistence capabilities, or -eviction contracts. +suitable for basic use cases, tests, or simple applications. The cache scales well +and is very fast, but it does not provide any management, persistence capabilities, +or eviction contracts. [[cache-store-configuration-ehcache]] @@ -8152,9 +8141,9 @@ example shows how to do so: ---- ==== -This setup bootstraps the ehcache library inside the Spring IoC (through the `ehcache` bean), which -is then wired into the dedicated `CacheManager` implementation. Note that the entire -ehcache-specific configuration is read from `ehcache.xml`. +This setup bootstraps the ehcache library inside the Spring IoC (through the `ehcache` +bean), which is then wired into the dedicated `CacheManager` implementation. Note that +the entire Ehcache-specific configuration is read from `ehcache.xml`. [[cache-store-configuration-caffeine]] @@ -8193,9 +8182,9 @@ are made available by the manager. The following example shows how to do so: ---- ==== -The Caffeine `CacheManager` also supports custom `Caffeine` and `CacheLoader`. See -the https://github.com/ben-manes/caffeine/wiki[Caffeine documentation] for more -information about those. +The Caffeine `CacheManager` also supports custom `Caffeine` and `CacheLoader`. +See the https://github.com/ben-manes/caffeine/wiki[Caffeine documentation] +for more information about those. [[cache-store-configuration-gemfire]] @@ -8203,8 +8192,8 @@ information about those. GemFire is a memory-oriented, disk-backed, elastically scalable, continuously available, active (with built-in pattern-based subscription notifications), globally replicated -database and provides fully-featured edge caching. For further information on how to use -GemFire as a `CacheManager` (and more), see the +database and provides fully-featured edge caching. For further information on how to +use GemFire as a `CacheManager` (and more), see the {doc-spring-gemfire}/html/[Spring Data GemFire reference documentation]. @@ -8214,8 +8203,8 @@ GemFire as a `CacheManager` (and more), see the Spring's caching abstraction can also use JSR-107-compliant caches. The JCache implementation is located in the `org.springframework.cache.jcache` package. -Again, to use it, you need to declare the appropriate `CacheManager`. The following -example shows how to do so: +Again, to use it, you need to declare the appropriate `CacheManager`. +The following example shows how to do so: ==== [source,xml,indent=0] @@ -8259,11 +8248,11 @@ The following example shows how to do so: ==== The `CompositeCacheManager` in the preceding chains multiple `CacheManager` instances and, -through the `fallbackToNoOpCache` flag, adds a no-op cache for all the -definitions not handled by the configured cache managers. That is, every cache -definition not found in either `jdkCache` or `gemfireCache` (configured earlier in the example) is -handled by the no-op cache, which does not store any information, causing the target -method to be executed every time. +through the `fallbackToNoOpCache` flag, adds a no-op cache for all the definitions not +handled by the configured cache managers. That is, every cache definition not found in +either `jdkCache` or `gemfireCache` (configured earlier in the example) is handled by +the no-op cache, which does not store any information, causing the target method to be +executed every time. @@ -8272,12 +8261,12 @@ method to be executed every time. Clearly, there are plenty of caching products out there that you can use as a backing store. To plug them in, you need to provide a `CacheManager` and a `Cache` implementation, -since, unfortunately, there is no available standard that we can use instead. This may -sound harder than it is, since, in practice, the classes tend to be simple +since, unfortunately, there is no available standard that we can use instead. +This may sound harder than it is, since, in practice, the classes tend to be simple http://en.wikipedia.org/wiki/Adapter_pattern[adapters] that map the caching abstraction -framework on top of the storage API, as the `ehcache` classes do. Most -`CacheManager` classes can use the classes in the `org.springframework.cache.support` -package, (such as `AbstractCacheManager`, which takes care of the boiler-plate code, +framework on top of the storage API, as the `ehcache` classes do. Most `CacheManager` +classes can use the classes in the `org.springframework.cache.support` package +(such as `AbstractCacheManager` which takes care of the boiler-plate code, leaving only the actual mapping to be completed). We hope that, in time, the libraries that provide integration with Spring can fill in this small configuration gap. @@ -8288,10 +8277,10 @@ that provide integration with Spring can fill in this small configuration gap. Directly through your cache provider. The cache abstraction is an abstraction, not a cache implementation. The solution you use might support various data -policies and different topologies that other solutions do not support (for example, the JDK -`ConcurrentHashMap` -- exposing that in the cache abstraction would be useless -because there would no backing support). Such functionality should be controlled directly -through the backing cache (when configuring it) or through its native API. +policies and different topologies that other solutions do not support (for example, +the JDK `ConcurrentHashMap` -- exposing that in the cache abstraction would be useless +because there would no backing support). Such functionality should be controlled +directly through the backing cache (when configuring it) or through its native API. diff --git a/src/docs/asciidoc/languages/dynamic-languages.adoc b/src/docs/asciidoc/languages/dynamic-languages.adoc index c2544c02f19..ebad1c630f5 100644 --- a/src/docs/asciidoc/languages/dynamic-languages.adoc +++ b/src/docs/asciidoc/languages/dynamic-languages.adoc @@ -1,29 +1,20 @@ [[dynamic-language]] = Dynamic Language Support -Spring 2.0 introduced comprehensive support for using classes and objects that have been -defined by using a dynamic language (such as JRuby) with Spring. This support lets you -write any number of classes in a supported dynamic language and have the Spring +Spring provides comprehensive support for using classes and objects that have been +defined by using a dynamic language (such as Groovy) with Spring. This support lets +you write any number of classes in a supported dynamic language and have the Spring container transparently instantiate, configure, and dependency inject the resulting objects. -Spring currently supports the following dynamic languages: +Spring's scripting support primarily targets Groovy and BeanShell. Beyond those +specifically supported languages, the JSR-223 scripting mechanism is supported +for integration with any JSR-223 capable language provider (as of Spring 4.2), +e.g. JRuby. -* JRuby 1.5+ -* Groovy 1.8+ -* BeanShell 2.0 +You can find fully working examples of where this dynamic language support can be +immediately useful in <>. -.Why only these languages? -**** -We chose to support these languages because: - -* The languages have a lot of traction in the Java enterprise community. -* No requests were made for other languages at the time that this support was added -* The Spring developers were most familiar with them. -**** - -You can find fully working examples of where this dynamic language support can be immediately useful -in <>. @@ -37,9 +28,9 @@ language for this first bean is Groovy. (The basis of this example was taken fro Spring test suite. If you want to see equivalent examples in any of the other supported languages, take a look at the source code). -The next example shows the `Messenger` interface, which the Groovy bean is going to implement. -Note that this interface is defined in plain Java. Dependent objects that are -injected with a reference to the `Messenger` do not know that the underlying +The next example shows the `Messenger` interface, which the Groovy bean is going to +implement. Note that this interface is defined in plain Java. Dependent objects that +are injected with a reference to the `Messenger` do not know that the underlying implementation is a Groovy script. The following listing shows the `Messenger` interface: ==== @@ -51,7 +42,6 @@ implementation is a Groovy script. The following listing shows the `Messenger` i public interface Messenger { String getMessage(); - } ---- ==== @@ -75,7 +65,6 @@ The following example defines a class that has a dependency on the `Messenger` i public void processBooking() { // use the injected Messenger object... } - } ---- ==== @@ -96,7 +85,6 @@ The following example implements the `Messenger` interface in Groovy: class GroovyMessenger implements Messenger { String message - } ---- ==== @@ -111,7 +99,7 @@ implementation is supported, but you have to manage the plumbing of the Spring i to do so. For more information on schema-based configuration, see <>. +XML Schema-based Configuration>>. ==== Finally, the following example shows the bean definitions that effect the injection of the @@ -143,14 +131,14 @@ Groovy-defined `Messenger` implementation into an instance of the ---- ==== -The `bookingService` bean (a `DefaultBookingService`) can now use its private -`messenger` member variable as normal, because the `Messenger` instance that was injected -into it is a `Messenger` instance. There is nothing special going on here -- just -plain Java and plain Groovy. +The `bookingService` bean (a `DefaultBookingService`) can now use its private `messenger` +member variable as normal, because the `Messenger` instance that was injected into it is +a `Messenger` instance. There is nothing special going on here -- just plain Java and +plain Groovy. Hopefully, the preceding XML snippet is self-explanatory, but do not worry unduly if it is not. -Keep reading for the in-depth detail on the whys and wherefores of the preceding -configuration. +Keep reading for the in-depth detail on the whys and wherefores of the preceding configuration. + @@ -160,11 +148,11 @@ configuration. This section describes exactly how you define Spring-managed beans in any of the supported dynamic languages. -Note that this chapter does not attempt to explain the syntax and idioms of the -supported dynamic languages. For example, if you want to use Groovy to write certain of -the classes in your application, we assume that you already know Groovy. If -you need further details about the dynamic languages themselves, see -<> at the end of this chapter. +Note that this chapter does not attempt to explain the syntax and idioms of the supported +dynamic languages. For example, if you want to use Groovy to write certain of the classes +in your application, we assume that you already know Groovy. If you need further details +about the dynamic languages themselves, see <> at the end of +this chapter. @@ -191,45 +179,43 @@ Spring's dynamic language support does make some (small) assumptions about the c of your dynamic language source files. - [[dynamic-language-beans-concepts-xml-language-element]] ==== The element -The final step in the list in the <> involves defining dynamic-language-backed bean definitions, one for each -bean that you want to configure (this is no different from normal JavaBean -configuration). However, instead of specifying the fully qualified classname of the -class that is to be instantiated and configured by the container, you can use the -`` element to define the dynamic language-backed bean. +The final step in the list in the <> +involves defining dynamic-language-backed bean definitions, one for each bean that you +want to configure (this is no different from normal JavaBean configuration). However, +instead of specifying the fully qualified classname of the class that is to be +instantiated and configured by the container, you can use the `` +element to define the dynamic language-backed bean. Each of the supported languages has a corresponding `` element: * `` (Groovy) * `` (BeanShell) -* `` (JSR-223) +* `` (JSR-223, e.g. with JRuby) The exact attributes and child elements that are available for configuration depends on exactly which language the bean has been defined in (the language-specific sections later in this chapter detail this). - [[dynamic-language-refreshable-beans]] ==== Refreshable Beans -One of the (and perhaps the single) most compelling value adds of the dynamic language support -in Spring is the "`refreshable bean`" feature. +One of the (and perhaps the single) most compelling value adds of the dynamic language +support in Spring is the "`refreshable bean`" feature. A refreshable bean is a dynamic-language-backed bean. With a small amount of configuration, a dynamic-language-backed bean can monitor changes in its underlying source file resource and then reload itself when the dynamic language source file is -changed (for example, when you edit and save changes to the file on the -file system). +changed (for example, when you edit and save changes to the file on the file system). -This lets you deploy any number of dynamic language source files as part of -an application, configure the Spring container to create beans backed by dynamic +This lets you deploy any number of dynamic language source files as part of an +application, configure the Spring container to create beans backed by dynamic language source files (using the mechanisms described in this chapter), and (later, -as requirements change or some other external factor comes into play) edit a -dynamic language source file and have any change they make be reflected in the bean that is +as requirements change or some other external factor comes into play) edit a dynamic +language source file and have any change they make be reflected in the bean that is backed by the changed dynamic language source file. There is no need to shut down a running application (or redeploy in the case of a web application). The dynamic-language-backed bean so amended picks up the new state and logic from the @@ -238,11 +224,11 @@ changed dynamic language source file. NOTE: This feature is off by default. Now we can take a look at an example to see how easy it is to start using refreshable -beans. To turn on the refreshable beans feature, you have to specify exactly -one additional attribute on the `` element of your bean definition. -So, if we stick with <> from earlier in this -chapter, the following example shows what we would change in the Spring XML configuration to effect -refreshable beans: +beans. To turn on the refreshable beans feature, you have to specify exactly one +additional attribute on the `` element of your bean definition. So, +if we stick with <> from earlier in +this chapter, the following example shows what we would change in the Spring XML +configuration to effect refreshable beans: ==== [source,xml,indent=0] @@ -267,17 +253,17 @@ refreshable beans: That really is all you have to do. The `refresh-check-delay` attribute defined on the `messenger` bean definition is the number of milliseconds after which the bean is -refreshed with any changes made to the underlying dynamic language source file. You can -turn off the refresh behavior by assigning a negative value to the +refreshed with any changes made to the underlying dynamic language source file. +You can turn off the refresh behavior by assigning a negative value to the `refresh-check-delay` attribute. Remember that, by default, the refresh behavior is disabled. If you do not want the refresh behavior, do not define the attribute. -If we then run the following application, we can exercise the refreshable feature (Please -do excuse the "`jumping-through-hoops-to-pause-the-execution`" shenanigans in this -next slice of code.) The `System.in.read()` call is only there so that the execution of -the program pauses while you (the developer in this scenario) go off and edit the underlying dynamic language -source file so that the refresh triggers on the dynamic-language-backed bean when -the program resumes execution. +If we then run the following application, we can exercise the refreshable feature. +(Please excuse the "`jumping-through-hoops-to-pause-the-execution`" shenanigans +in this next slice of code.) The `System.in.read()` call is only there so that the +execution of the program pauses while you (the developer in this scenario) go off +and edit the underlying dynamic language source file so that the refresh triggers +on the dynamic-language-backed bean when the program resumes execution. The following listing shows this sample application: @@ -303,10 +289,11 @@ The following listing shows this sample application: ---- ==== -Assume then, for the purposes of this example, that all calls to the -`getMessage()` method of `Messenger` implementations have to be changed such that the -message is surrounded by quotation marks. The following listing shows the changes that you (the developer) should make to the -`Messenger.groovy` source file when the execution of the program is paused: +Assume then, for the purposes of this example, that all calls to the `getMessage()` +method of `Messenger` implementations have to be changed such that the message is +surrounded by quotation marks. The following listing shows the changes that you +(the developer) should make to the `Messenger.groovy` source file when the +execution of the program is paused: ==== [source,java,indent=0] @@ -330,15 +317,14 @@ message is surrounded by quotation marks. The following listing shows the change ---- ==== -When the program runs, the output before the input pause will be `I Can Do The -Frug`. After the change to the source file is made and saved and the program resumes -execution, the result of calling the `getMessage()` method on the -dynamic-language-backed `Messenger` implementation is `'I Can Do The Frug'` -(notice the inclusion of the additional quotation marks). +When the program runs, the output before the input pause will be `I Can Do The Frug`. +After the change to the source file is made and saved and the program resumes execution, +the result of calling the `getMessage()` method on the dynamic-language-backed +`Messenger` implementation is `'I Can Do The Frug'` (notice the inclusion of the +additional quotation marks). -Changes to a script do not trigger a refresh if -the changes occur within the window of the `refresh-check-delay` value. -Changes to the script are not actually picked up until +Changes to a script do not trigger a refresh if the changes occur within the window of +the `refresh-check-delay` value. Changes to the script are not actually picked up until a method is called on the dynamic-language-backed bean. It is only when a method is called on a dynamic-language-backed bean that it checks to see if its underlying script source has changed. Any exceptions that relate to refreshing the script (such as @@ -353,7 +339,6 @@ that checks the last modified date of a dynamic language source file that exists file system). - [[dynamic-language-beans-inline]] ==== Inline Dynamic Language Source Files @@ -392,7 +377,6 @@ work using inline source. (See <> for suc example.) - [[dynamic-language-beans-ctor-injection]] ==== Understanding Constructor Injection in the Context of Dynamic-language-backed Beans @@ -425,7 +409,6 @@ does not work: String message String anotherMessage - } ---- @@ -456,17 +439,6 @@ injection is the injection style favored by the overwhelming majority of develop This section describes how to use beans defined in Groovy in Spring. -.The Groovy library dependencies -**** - -The Groovy scripting support in Spring requires the following libraries to be on the -classpath of your application: - -* `groovy-1.8.jar` -* `asm-3.2.jar` -* `antlr-2.7.7.jar` -**** - The Groovy homepage includes the following description: "`Groovy is an agile dynamic language for the Java 2 Platform that has many of the @@ -474,7 +446,7 @@ features that people like so much in languages like Python, Ruby and Smalltalk, them available to Java developers using a Java-like syntax.`" If you have read this chapter straight from the top, you have already -<> of a Groovy-dynamic-language-backed +<> of a Groovy-dynamic-language-backed bean. Now consider another example (again using an example from the Spring test suite): ==== @@ -486,7 +458,6 @@ bean. Now consider another example (again using an example from the Spring test public interface Calculator { int add(int x, int y); - } ---- ==== @@ -505,7 +476,6 @@ The following example implements the `Calculator` interface in Groovy: int add(int x, int y) { x + y } - } ---- ==== @@ -546,15 +516,13 @@ Finally, the following small application exercises the preceding configuration: ==== The resulting output from running the above program is (unsurprisingly) `10`. -(For more interesting examples, -see the dynamic language showcase project for a more complex example or see the examples -<> later in this chapter). - -You must not define more than one class per Groovy source file. -While this is perfectly legal in Groovy, it is (arguably) a bad practice. In the -interests of a consistent approach, you should (in the opinion of the Spring team) respect -the standard Java conventions of one (public) class per source file. +(For more interesting examples, see the dynamic language showcase project for a more +complex example or see the examples <> later in this chapter). +You must not define more than one class per Groovy source file. While this is perfectly +legal in Groovy, it is (arguably) a bad practice. In the interests of a consistent +approach, you should (in the opinion of the Spring team) respect the standard Java +conventions of one (public) class per source file. [[dynamic-language-beans-groovy-customizer]] @@ -577,11 +545,11 @@ shows the `GroovyObjectCustomizer` interface definition: ---- ==== -The Spring Framework instantiates an instance of your Groovy-backed bean and -then passes the created `GroovyObject` to the specified `GroovyObjectCustomizer` (if one +The Spring Framework instantiates an instance of your Groovy-backed bean and then +passes the created `GroovyObject` to the specified `GroovyObjectCustomizer` (if one has been defined). You can do whatever you like with the supplied `GroovyObject` -reference. We expect that most people want to set a custom `MetaClass` with this callback, -and the following example shows how to do so: +reference. We expect that most people want to set a custom `MetaClass` with this +callback, and the following example shows how to do so: ==== [source,java,indent=0] @@ -607,8 +575,8 @@ and the following example shows how to do so: A full discussion of meta-programming in Groovy is beyond the scope of the Spring reference manual. See the relevant section of the Groovy reference manual or do a -search online. Plenty of articles address this topic. Actually, making use -of a `GroovyObjectCustomizer` is easy if you use the Spring namespace support, as the +search online. Plenty of articles address this topic. Actually, making use of a +`GroovyObjectCustomizer` is easy if you use the Spring namespace support, as the following example shows: ==== @@ -655,15 +623,6 @@ in the same place as Spring's `GroovyObjectCustomizer`. This section describes how to use BeanShell beans in Spring. -.The BeanShell library dependencies -**** - -The BeanShell scripting support in Spring requires the following libraries to be on the -classpath of your application: - -* `bsh-2.0b4.jar` -**** - The BeanShell homepage includes the following description: {JB} "`BeanShell is a small, free, embeddable Java source interpreter with dynamic language @@ -673,12 +632,12 @@ closures like those in Perl and JavaScript.`" In contrast to Groovy, BeanShell-backed bean definitions require some (small) additional configuration. The implementation of the BeanShell dynamic language support in Spring is -interesting, because Spring creates a JDK dynamic proxy -that implements all of the interfaces that are specified in the `script-interfaces` -attribute value of the `` element (this is why you must supply at least -one interface in the value of the attribute, and, consequently, program to interfaces -when you use BeanShell-backed beans). This means that every method call on a -BeanShell-backed object goes through the JDK dynamic proxy invocation mechanism. +interesting, because Spring creates a JDK dynamic proxy that implements all of the +interfaces that are specified in the `script-interfaces` attribute value of the +`` element (this is why you must supply at least one interface in the value +of the attribute, and, consequently, program to interfaces when you use BeanShell-backed +beans). This means that every method call on a BeanShell-backed object goes through the +JDK dynamic proxy invocation mechanism. Now we can show a fully working example of using a BeanShell-based bean that implements the `Messenger` interface that was defined earlier in this chapter. We again show the @@ -693,13 +652,12 @@ definition of the `Messenger` interface: public interface Messenger { String getMessage(); - } ---- ==== -The following example shows the BeanShell "`implementation`" (we use the term loosely here) of the -`Messenger` interface: +The following example shows the BeanShell "`implementation`" (we use the term loosely here) +of the `Messenger` interface: ==== [source,java,indent=0] @@ -717,8 +675,8 @@ The following example shows the BeanShell "`implementation`" (we use the term lo ---- ==== -The following example shows the Spring XML that defines an "`instance`" of the above "`class`" (again, -we use these terms very loosely here): +The following example shows the Spring XML that defines an "`instance`" of the above +"`class`" (again, we use these terms very loosely here): ==== [source,xml,indent=0] @@ -737,12 +695,13 @@ BeanShell-based beans. + [[dynamic-language-scenarios]] == Scenarios The possible scenarios where defining Spring managed beans in a scripting language would -be beneficial are many and varied. This section describes two possible use -cases for the dynamic language support in Spring. +be beneficial are many and varied. This section describes two possible use cases for the +dynamic language support in Spring. @@ -796,7 +755,6 @@ by using the Groovy dynamic language: HttpServletResponse httpServletResponse) { return new ModelAndView("tell", "fortune", this.fortuneService.tellFortune()) } - } ---- @@ -826,13 +784,12 @@ validation logic by editing and saving a simple text file. Any such changes is (depending on the configuration) automatically reflected in the execution of a running application and would not require the restart of an application. -NOTE: To effect the automatic "`pickup`" of any changes to -dynamic-language-backed beans, you have to enable the 'refreshable beans' -feature. See <> for a full and detailed treatment of -this feature. +NOTE: To effect the automatic "`pickup`" of any changes to dynamic-language-backed +beans, you have to enable the 'refreshable beans' feature. See +<> for a full and detailed treatment of this feature. -The following example shows a Spring `org.springframework.validation.Validator` implemented -by using the Groovy dynamic language (see <> for a discussion of the `Validator` interface): @@ -856,13 +813,13 @@ Validation using Spring’s Validator interface>> for a discussion of the } errors.reject("whitespace", "Cannot be composed wholly of whitespace.") } - } ---- ==== + [[dynamic-language-final-notes]] == Additional Details @@ -876,14 +833,12 @@ This last section contains some additional details related to the dynamic langua You can use the Spring AOP framework to advise scripted beans. The Spring AOP framework actually is unaware that a bean that is being advised might be a scripted bean, so all of the AOP use cases and functionality that you use (or aim to use) -work with scripted beans. -When you advise scripted beans, you cannot use class-based proxies. You must -use <>. +work with scripted beans. When you advise scripted beans, you cannot use class-based +proxies. You must use <>. -You are not limited to advising scripted beans. You can also write -aspects themselves in a supported dynamic language and use such beans to advise other -Spring beans. This really would be an advanced use of the dynamic language support -though. +You are not limited to advising scripted beans. You can also write aspects themselves +in a supported dynamic language and use such beans to advise other Spring beans. +This really would be an advanced use of the dynamic language support though. @@ -893,11 +848,11 @@ though. In case it is not immediately obvious, scripted beans can be scoped in the same way as any other bean. The `scope` attribute on the various `` elements lets you control the scope of the underlying scripted bean, as it does with a regular -bean. (The default scope is <>, as it is -with "`regular`" beans.) +bean. (The default scope is <>, +as it is with "`regular`" beans.) The following example uses the `scope` attribute to define a Groovy bean scoped as -a <>: +a <>: ==== [source,xml,indent=0] @@ -922,26 +877,24 @@ a <>: ---- ==== -See <> in <> +See <> in <> for a full discussion of the scoping support in the Spring Framework. - [[xsd-schemas-lang]] === The `lang` XML schema -The `lang` elements in Spring XML configuration deal with exposing objects that have been written -in a dynamic language (such as JRuby or Groovy) as beans in the Spring container. +The `lang` elements in Spring XML configuration deal with exposing objects that have been +written in a dynamic language (such as Groovy or BeanShell) as beans in the Spring container. These elements (and the dynamic language support) are comprehensively covered in -<>. -See that chapter for full details on this support and the `lang` elements. +<>. See that chapter +for full details on this support and the `lang` elements. -To use the elements in the `lang` schema, you need to have -the following preamble at the top of your Spring XML configuration file. The text in the -following snippet references the correct schema so that the tags in the `lang` namespace -are available to you: +To use the elements in the `lang` schema, you need to have the following preamble at the +top of your Spring XML configuration file. The text in the following snippet references +the correct schema so that the tags in the `lang` namespace are available to you: ==== [source,xml,indent=0] @@ -962,12 +915,13 @@ are available to you: + [[dynamic-language-resources]] == Further Resources -The following links go to further resources about the various dynamic languages described in -this chapter: +The following links go to further resources about the various dynamic languages referenced +in this chapter: -* The http://jruby.org/[JRuby] homepage * The http://www.groovy-lang.org/[Groovy] homepage * The http://www.beanshell.org/[BeanShell] homepage +* The http://jruby.org/[JRuby] homepage diff --git a/src/docs/asciidoc/languages/groovy.adoc b/src/docs/asciidoc/languages/groovy.adoc index d274f61211e..1fd0d3c9242 100644 --- a/src/docs/asciidoc/languages/groovy.adoc +++ b/src/docs/asciidoc/languages/groovy.adoc @@ -7,7 +7,7 @@ existing Java application. The Spring Framework provides a dedicated `ApplicationContext` that supports a Groovy-based Bean Definition DSL. For more details, see -<>. +<>. Further support for Groovy, including beans written in Groovy, refreshable script beans, and more is available in <>. diff --git a/src/docs/asciidoc/languages/kotlin.adoc b/src/docs/asciidoc/languages/kotlin.adoc index aea6ad77540..9f90109e2f9 100644 --- a/src/docs/asciidoc/languages/kotlin.adoc +++ b/src/docs/asciidoc/languages/kotlin.adoc @@ -1,26 +1,27 @@ [[kotlin]] = Kotlin -https://kotlinlang.org[Kotlin] is a statically typed language that targets the JVM (and other platforms), -which allows writing concise and elegant code while providing very good -https://kotlinlang.org/docs/reference/java-interop.html[interoperability] with -existing libraries written in Java. +https://kotlinlang.org[Kotlin] is a statically typed language that targets the JVM +(and other platforms), which allows writing concise and elegant code while providing +very good https://kotlinlang.org/docs/reference/java-interop.html[interoperability] +with existing libraries written in Java. The Spring Framework provides first-class support for Kotlin that lets developers write Kotlin applications almost as if the Spring Framework were a native Kotlin framework. The easiest way to learn about Spring and Kotlin is to follow -https://spring.io/guides/tutorials/spring-boot-kotlin/[this comprehensive tutorial]. Feel -free to join the #spring channel of http://slack.kotlinlang.org/[Kotlin Slack] or ask a -question with `spring` and `kotlin` as tags on +https://spring.io/guides/tutorials/spring-boot-kotlin/[this comprehensive tutorial]. +Feel free to join the #spring channel of http://slack.kotlinlang.org/[Kotlin Slack] +or ask a question with `spring` and `kotlin` as tags on https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] if you need support. + [[kotlin-requirements]] == Requirements -The Spring Framework supports Kotlin 1.1+ and requires +Spring Framework 5.1 supports Kotlin 1.1+ and requires https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-stdlib[`kotlin-stdlib`] (or one of its variants, such as https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-stdlib-jre8[`kotlin-stdlib-jre8`] for Kotlin 1.1 or https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-stdlib-jdk8[`kotlin-stdlib-jdk8`] for Kotlin 1.2+) @@ -30,6 +31,7 @@ https://start.spring.io/#!language=kotlin[start.spring.io]. + [[kotlin-extensions]] == Extensions @@ -79,6 +81,7 @@ for shorter syntax. + [[kotlin-null-safety]] == Null-safety @@ -90,7 +93,7 @@ declarations and expressing "`value or no value`" semantics without paying the c http://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null-safety].) Although Java does not let you express null-safety in its type-system, the Spring Framework -provides <> +provides <> via tooling-friendly annotations declared in the `org.springframework.lang` package. By default, types from Java APIs used in Kotlin are recognized as https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types], @@ -116,6 +119,7 @@ for up-to-date information. + [[kotlin-classes-interfaces]] == Classes and Interfaces @@ -138,6 +142,7 @@ since the later requires a reference to the outer class. + [[kotlin-annotations]] == Annotations @@ -166,6 +171,7 @@ https://stackoverflow.com/a/35853200/1092077[this Stack Overflow response]. + [[kotlin-bean-definition-dsl]] == Bean Definition DSL @@ -263,6 +269,7 @@ for more details and up-to-date information. + [[kotlin-web]] == Web @@ -272,7 +279,7 @@ for more details and up-to-date information. Spring Framework now comes with a {doc-root}/spring-framework/docs/{spring-version}/kdoc-api/spring-framework/org.springframework.web.reactive.function.server/-router-function-dsl/[Kotlin routing DSL] -that lets you use the <> to write clean and idiomatic Kotlin code, +that lets you use the <> to write clean and idiomatic Kotlin code, as the following example shows: ==== @@ -348,27 +355,27 @@ See the https://github.com/sdeleuze/kotlin-script-templating[kotlin-script-templ project for more details. + + [[kotlin-spring-projects-in-kotlin]] == Spring Projects in Kotlin -This section provides some specific hints and recommendations worth -for developing Spring projects in Kotlin. +This section provides some specific hints and recommendations worth for developing Spring projects +in Kotlin. === Final by Default By default, https://discuss.kotlinlang.org/t/classes-final-by-default/166[all classes in Kotlin are `final`]. -The `open` modifier on a class is the opposite of Java's `final`: It allows others to -inherit from this class. This also applies to member functions, in that they need to be marked as `open` to -be overridden. - -While Kotlin's JVM-friendly design is generally frictionless with Spring, -this specific Kotlin feature can prevent the application from starting, if this fact is not taken into -consideration. This is because Spring beans -(such as `@Configuration` classes which need to be inherited at runtime for technical reasons) are normally proxied by CGLIB. -The workaround was to add an `open` keyword on each class and member -function of Spring beans that are proxied by CGLIB (such as `@Configuration` classes), which can +The `open` modifier on a class is the opposite of Java's `final`: It allows others to inherit from this +class. This also applies to member functions, in that they need to be marked as `open` to be overridden. + +While Kotlin's JVM-friendly design is generally frictionless with Spring, this specific Kotlin feature +can prevent the application from starting, if this fact is not taken into consideration. This is because +Spring beans (such as `@Configuration` classes which need to be inherited at runtime for technical +reasons) are normally proxied by CGLIB. The workaround was to add an `open` keyword on each class and +member function of Spring beans that are proxied by CGLIB (such as `@Configuration` classes), which can quickly become painful and is against the Kotlin principle of keeping code concise and predictable. Fortunately, Kotlin now provides a @@ -435,15 +442,16 @@ the https://kotlinlang.org/docs/reference/compiler-plugins.html#how-to-use-no-ar plugin. NOTE: As of the Kay release train, Spring Data supports Kotlin immutable class instances and -does not require the `kotlin-noarg` plugin if the module uses Spring Data object -mappings (such as MongoDB, Redis, Cassandra, and others). +does not require the `kotlin-noarg` plugin if the module uses Spring Data object mappings +(such as MongoDB, Redis, Cassandra, and others). === Injecting Dependencies -Our recommendation is to try and favor constructor injection with `val` read-only (and non-nullable when possible) -https://kotlinlang.org/docs/reference/properties.html[properties], as the following example shows: +Our recommendation is to try and favor constructor injection with `val` read-only (and +non-nullable when possible) https://kotlinlang.org/docs/reference/properties.html[properties], +as the following example shows: ==== [source,kotlin,indent=0] @@ -456,9 +464,9 @@ https://kotlinlang.org/docs/reference/properties.html[properties], as the follow ---- ==== -NOTE: As of Spring Framework 4.3, classes with a single constructor have their -parameters automatically autowired, that's why there is no need for an -explicit `@Autowired constructor` in the example shown above. +NOTE: As of Spring Framework 4.3, classes with a single constructor have their parameters +automatically autowired, that's why there is no need for an explicit `@Autowired constructor` +in the example shown above. If you really need to use field injection, you can use the `lateinit var` construct, as the following example shows: @@ -483,13 +491,14 @@ as the following example shows: === Injecting Configuration Properties In Java, you can inject configuration properties by using annotations (such as `@Value("${property}")`). -However, in Kotlin, `$` is a reserved character that is used for https://kotlinlang.org/docs/reference/idioms.html#string-interpolation[string interpolation]. +However, in Kotlin, `$` is a reserved character that is used for +https://kotlinlang.org/docs/reference/idioms.html#string-interpolation[string interpolation]. Therefore, if you wish to use the `@Value` annotation in Kotlin, you need to escape the `$` character by writing `@Value("\${property}")`. -As an alternative, you can customize the properties placeholder prefix by declaring -the following configuration beans: +As an alternative, you can customize the properties placeholder prefix by declaring the +following configuration beans: ==== [source,kotlin,indent=0] @@ -501,8 +510,8 @@ the following configuration beans: ---- ==== -You can customize existing code (such as Spring Boot actuators or `@LocalServerPort`) that uses the `${...}` syntax, -with configuration beans, as the following example shows: +You can customize existing code (such as Spring Boot actuators or `@LocalServerPort`) +that uses the `${...}` syntax, with configuration beans, as the following example shows: ==== [source,kotlin,indent=0] @@ -520,35 +529,38 @@ with configuration beans, as the following example shows: NOTE: If you use Spring Boot, you can use https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`] -instead of `@Value` annotations. However, currently, this only works with `lateinit` or nullable `var` -properties (we recommended the former), since immutable classes initialized by -constructors are not yet supported. -See these issues about https://github.com/spring-projects/spring-boot/issues/8762[`@ConfigurationProperties` binding for immutable POJOs] +instead of `@Value` annotations. However, currently, this only works with `lateinit` or +nullable `var` properties (we recommended the former), since immutable classes initialized +by constructors are not yet supported. See these issues about +https://github.com/spring-projects/spring-boot/issues/8762[`@ConfigurationProperties` binding for immutable POJOs] and https://github.com/spring-projects/spring-boot/issues/1254[`@ConfigurationProperties` binding on interfaces] for more details. + === Checked Exceptions -Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling] are pretty close, with the main -difference being that Kotlin treats all exceptions as unchecked exceptions. However, when using proxied objects -(for example classes or methods annotated with `@Transactional`), checked exceptions thrown will be wrapped by default in +Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling] +are pretty close, with the main difference being that Kotlin treats all exceptions as +unchecked exceptions. However, when using proxied objects (for example classes or methods +annotated with `@Transactional`), checked exceptions thrown will be wrapped by default in an `UndeclaredThrowableException`. -To get the original exception thrown like in Java, methods should be annotated with https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`] +To get the original exception thrown like in Java, methods should be annotated with +https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`] to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`). + === Annotation Array Attributes Kotlin annotations are mostly similar to Java annotations, but array attributes (which are extensively used in Spring) behave differently. As explained in -https://kotlinlang.org/docs/reference/annotations.html[Kotlin documentation] -you can omit the `value` attribute name, unlike other attributes, and -specify it as a `vararg` parameter. +https://kotlinlang.org/docs/reference/annotations.html[Kotlin documentation] you can omit +the `value` attribute name, unlike other attributes, and specify it as a `vararg` parameter. -To understand what that means, consider `@RequestMapping` (which is one -of the most widely used Spring annotations) as an example. This Java annotation is declared as follows: +To understand what that means, consider `@RequestMapping` (which is one of the most widely +used Spring annotations) as an example. This Java annotation is declared as follows: ==== [source,java,indent=0] @@ -569,8 +581,8 @@ of the most widely used Spring annotations) as an example. This Java annotation ==== The typical use case for `@RequestMapping` is to map a handler method to a specific path -and method. In Java, you can specify a single value for the -annotation array attribute, and it is automatically converted to an array. +and method. In Java, you can specify a single value for the annotation array attribute, +and it is automatically converted to an array. That is why one can write `@RequestMapping(value = "/toys", method = RequestMethod.GET)` or @@ -590,14 +602,16 @@ all HTTP methods will be matched, not only the `GET` one. === Testing -This section addresses testing with the combination of Kotlin and Spring Framework. The recommended testing framework -is https://junit.org/junit5/[JUnit 5], as well as https://mockk.io/[Mockk] for mocking. +This section addresses testing with the combination of Kotlin and Spring Framework. +The recommended testing framework is https://junit.org/junit5/[JUnit 5], as well as +https://mockk.io/[Mockk] for mocking. ==== Constructor injection -As described in the <>, JUnit 5 allows -constructor injection of beans which is pretty useful with Kotlin in order to use `val` instead of `lateinit var`. +As described in the <>, +JUnit 5 allows constructor injection of beans which is pretty useful with Kotlin +in order to use `val` instead of `lateinit var`. ==== @@ -632,12 +646,11 @@ class OrderServiceIntegrationTests @Autowired constructor( Kotlin lets you specify meaningful test function names between backticks (```). As of JUnit 5, Kotlin test classes can use the `@TestInstance(TestInstance.Lifecycle.PER_CLASS)` -annotation to enable a single instantiation of test classes, which allows the use of `@BeforeAll` and `@AfterAll` -annotations on non-static methods, which is a good fit for Kotlin. +annotation to enable a single instantiation of test classes, which allows the use of `@BeforeAll` +and `@AfterAll` annotations on non-static methods, which is a good fit for Kotlin. -You can also change the default behavior to `PER_CLASS` thanks to a -`junit-platform.properties` file with a -`junit.jupiter.testinstance.lifecycle.default = per_class` property. +You can also change the default behavior to `PER_CLASS` thanks to a `junit-platform.properties` +file with a `junit.jupiter.testinstance.lifecycle.default = per_class` property. The following example demonstrates `@BeforeAll` and `@AfterAll` annotations on non-static methods: @@ -674,7 +687,6 @@ class IntegrationTests { ==== - ==== Specification-like Tests You can create specification-like tests with JUnit 5 and Kotlin. @@ -707,18 +719,18 @@ class SpecificationLikeTests { ==== - [[kotlin-webtestclient-issue]] ==== `WebTestClient` Type Inference Issue in Kotlin Due to a https://youtrack.jetbrains.com/issue/KT-5464[type inference issue], you must -use the Kotlin `expectBody` extension (such as `.expectBody().isEqualTo("toys")`), since it -provides a workaround for the Kotlin issue with the Java API. +use the Kotlin `expectBody` extension (such as `.expectBody().isEqualTo("toys")`), +since it provides a workaround for the Kotlin issue with the Java API. See also the related https://jira.spring.io/browse/SPR-16057[SPR-16057] issue. + [[kotlin-getting-started]] == Getting Started @@ -726,16 +738,18 @@ The easiest way to learn how to build a Spring application with Kotlin is to fol https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial]. + === `start.spring.io` The easiest way to start a new Spring Framework 5 project in Kotlin is to create a new Spring Boot 2 project on https://start.spring.io/#!language=kotlin[start.spring.io]. + === Choosing the Web Flavor -Spring Framework now comes with two different web stacks: <> and -<>. +Spring Framework now comes with two different web stacks: <> and +<>. Spring WebFlux is recommended if you want to create applications that will deal with latency, long-lived connections, streaming scenarios or if you want to use the web functional @@ -746,6 +760,7 @@ MVC and its annotation-based programming model is the recommended choice. + [[kotlin-resources]] == Resources @@ -760,6 +775,7 @@ Kotlin and the Spring Framework: * https://kotlin.link/[Awesome Kotlin] + === Examples The following Github projects offer examples that you can learn from and possibly even extend: @@ -794,4 +810,3 @@ The following list categorizes the pending issues related to Spring and Kotlin s ** https://youtrack.jetbrains.com/issue/KT-14984[Impossible to pass not all SAM argument as function] ** https://youtrack.jetbrains.com/issue/KT-15125[Support JSR 223 bindings directly via script variables] ** https://youtrack.jetbrains.com/issue/KT-6653[Kotlin properties do not override Java-style getters and setters] - diff --git a/src/docs/asciidoc/overview.adoc b/src/docs/asciidoc/overview.adoc index 57cd3f9e26c..3c6b42237ea 100644 --- a/src/docs/asciidoc/overview.adoc +++ b/src/docs/asciidoc/overview.adoc @@ -7,8 +7,8 @@ Spring makes it easy to create Java enterprise applications. It provides everything you need to embrace the Java language in an enterprise environment, with support for Groovy and Kotlin as alternative languages on the JVM, and with the flexibility to create many -kinds of architectures depending on an application's needs. As of Spring Framework 5.0, -Spring requires JDK 8+ (Java SE 8+) and provides out-of-the-box support for JDK 9 already. +kinds of architectures depending on an application's needs. As of Spring Framework 5.1, +Spring requires JDK 8+ (Java SE 8+) and provides out-of-the-box support for JDK 11 LTS. Spring supports a wide range of application scenarios. In a large enterprise, applications often exist for a long time and have to run on a JDK and application server whose upgrade @@ -44,7 +44,7 @@ A note about modules: Spring's framework jars allow for deployment to JDK 9's mo "Automatic-Module-Name" manifest entries which define stable language-level module names ("spring.core", "spring.context" etc) independent from jar artifact names (the jars follow the same naming pattern with "-" instead of ".", e.g. "spring-core" and "spring-context"). -Of course, Spring's framework jars keep working fine on the classpath on both JDK 8 and 9. +Of course, Spring's framework jars keep working fine on the classpath on both JDK 8 and 9+. diff --git a/src/docs/asciidoc/testing-webtestclient.adoc b/src/docs/asciidoc/testing-webtestclient.adoc index c772dce04c6..e6418604a0e 100644 --- a/src/docs/asciidoc/testing-webtestclient.adoc +++ b/src/docs/asciidoc/testing-webtestclient.adoc @@ -4,10 +4,10 @@ `WebTestClient` is a thin shell around <>, using it to perform requests and exposing a dedicated, fluent API for verifying responses. `WebTestClient` binds to a WebFlux application by using a -<>, or it can test any +<>, or it can test any web server over an HTTP connection. -TIP: Kotlin users: See <> +TIP: Kotlin users: See <> related to use of the `WebTestClient`. @@ -35,8 +35,8 @@ The following example shows how to create a server setup to test one `@Controlle ---- ==== -The preceding example loads the <> and -registers the given controller. The resulting WebFlux application is tested +The preceding example loads the <> +and registers the given controller. The resulting WebFlux application is tested without an HTTP server by using mock request and response objects. There are more methods on the builder to customize the default WebFlux Java configuration. @@ -46,7 +46,7 @@ on the builder to customize the default WebFlux Java configuration. === Bind to Router Function The following example shows how to set up a server from a -<>: +<>: ==== [source,java,intent=0] @@ -94,11 +94,10 @@ some subset of it: <3> Create the `WebTestClient` ==== -Internally, the configuration is passed to `WebHttpHandlerBuilder` to set up -the request processing chain. See -<> for more details. The -resulting WebFlux application is tested without an HTTP server by using mock request -and response objects. +Internally, the configuration is passed to `WebHttpHandlerBuilder` to set up the request +processing chain. See <> for +more details. The resulting WebFlux application is tested without an HTTP server by +using mock request and response objects. @@ -142,7 +141,7 @@ are readily available following `bindToServer`. For all others, you need to use [[webtestclient-tests]] == Writing Tests -`WebTestClient` provides an API identical to <> +`WebTestClient` provides an API identical to <> up to the point of performing a request by using `exchange()`. What follows after `exchange()` is a chained API workflow to verify responses. @@ -326,8 +325,8 @@ from the `reactor-test` module to do that, as the following example shows: [[webtestclient-request-body]] === Request Body -When it comes to building requests, the `WebTestClient` offers an API identical to the -`WebClient`, and the implementation is mostly a simple pass-through. See -the <> for examples on +When it comes to building requests, the `WebTestClient` offers an API identical to +the `WebClient`, and the implementation is mostly a simple pass-through. See the +<> for examples on how to prepare a request with a body, including submitting form data, multipart requests, and more. diff --git a/src/docs/asciidoc/testing.adoc b/src/docs/asciidoc/testing.adoc index 4f427da6726..7fba45989e8 100644 --- a/src/docs/asciidoc/testing.adoc +++ b/src/docs/asciidoc/testing.adoc @@ -22,8 +22,8 @@ set up service locator registries and similar structures). == Introduction to Spring Testing Testing is an integral part of enterprise software development. This chapter focuses on -the value added by the IoC principle to <> and on the benefits -of the Spring Framework's support for <>. (A +the value added by the IoC principle to <> and on the benefits +of the Spring Framework's support for <>. (A thorough treatment of testing in the enterprise is beyond the scope of this reference manual.) @@ -36,12 +36,12 @@ manual.) Dependency injection should make your code less dependent on the container than it would be with traditional Java EE development. The POJOs that make up your application should be testable in JUnit or TestNG tests, with objects instantiated by using the `new` -operator, without Spring or any other container. You can use <> (in conjunction with other valuable testing techniques) to test your code in -isolation. If you follow the architecture recommendations for Spring, the resulting clean -layering and componentization of your codebase facilitate easier unit testing. For -example, you can test service layer objects by stubbing or mocking DAO or repository -interfaces, without needing to access persistent data while running unit tests. +operator, without Spring or any other container. You can use <> +(in conjunction with other valuable testing techniques) to test your code in isolation. +If you follow the architecture recommendations for Spring, the resulting clean layering +and componentization of your codebase facilitate easier unit testing. For example, +you can test service layer objects by stubbing or mocking DAO or repository interfaces, +without needing to access persistent data while running unit tests. True unit tests typically run extremely quickly, as there is no runtime infrastructure to set up. Emphasizing true unit tests as part of your development methodology can boost @@ -68,8 +68,8 @@ Spring includes a number of packages dedicated to mocking: The `org.springframework.mock.env` package contains mock implementations of the `Environment` and `PropertySource` abstractions (see -<> -and <>). +<> +and <>). `MockEnvironment` and `MockPropertySource` are useful for developing out-of-container tests for code that depends on environment-specific properties. @@ -177,8 +177,8 @@ TIP: To unit test your Spring MVC `Controller` classes as POJOs, use `ModelAndVi combined with `MockHttpServletRequest`, `MockHttpSession`, and so on from Spring's <>. For thorough integration testing of your Spring MVC and REST `Controller` classes in conjunction with your `WebApplicationContext` -configuration for Spring MVC, use the <> instead. +configuration for Spring MVC, use the +<> instead. @@ -212,17 +212,17 @@ Doing so lets you test things such as: The Spring Framework provides first-class support for integration testing in the `spring-test` module. The name of the actual JAR file might include the release version and might also be in the long `org.springframework.test` form, depending on where you get -it from (see the <> for -an explanation). This library includes the `org.springframework.test` package, which +it from (see the <> +for an explanation). This library includes the `org.springframework.test` package, which contains valuable classes for integration testing with a Spring container. This testing does not rely on an application server or other deployment environment. Such tests are slower to run than unit tests but much faster than the equivalent Selenium tests or remote tests that rely on deployment to an application server. -In Spring 2.5 and later, unit and integration testing support is provided in the form of -the annotation-driven <>. The -TestContext framework is agnostic of the actual testing framework in use, which allows -instrumentation of tests in various environments, including JUnit, TestNG, and others. +Unit and integration testing support is provided in the form of the annotation-driven +<>. The TestContext framework is +agnostic of the actual testing framework in use, which allows instrumentation of tests +in various environments, including JUnit, TestNG, and others. @@ -231,10 +231,10 @@ instrumentation of tests in various environments, including JUnit, TestNG, and o Spring's integration testing support has the following primary goals: -* To manage <> between tests. -* To provide <>. -* To provide <> appropriate to integration testing. -* To supply <> that assist +* To manage <> between tests. +* To provide <>. +* To provide <> appropriate to integration testing. +* To supply <> that assist developers in writing integration tests. The next few sections describe each goal and provide links to implementation and @@ -294,8 +294,8 @@ integration tests that test the following areas: * The logic of the `HibernateTitleRepository`: Does the configured instance of this class perform as anticipated? -See dependency injection of test fixtures with the <>. +See dependency injection of test fixtures with the +<>. [[testing-tx]] @@ -320,7 +320,7 @@ particular test to populate or modify the database), you can tell the TestContex framework to cause the transaction to commit instead of roll back by using the <> annotation. -See transaction management with the <>. +See transaction management with the <>. [[testing-support-classes]] @@ -337,12 +337,12 @@ which let you access: queries to confirm database state both before and after execution of database-related application code, and Spring ensures that such queries run in the scope of the same transaction as the application code. When used in conjunction with an ORM tool, be sure - to avoid <>. + to avoid <>. In addition, you may want to create your own custom, application-wide superclass with instance variables and methods specific to your project. -See support classes for the <>. +See support classes for the <>. @@ -364,15 +364,15 @@ methods. [TIP] ==== -<> -and <> +<> +and <> provide convenience methods that delegate to the aforementioned methods in `JdbcTestUtils`. The `spring-jdbc` module provides support for configuring and launching an embedded -database, which you can use in integration tests that interact with a database. For -details, see <> and <> and <>. ==== @@ -381,8 +381,8 @@ Logic with an Embedded Database>>. [[integration-testing-annotations]] === Annotations -This section covers annotations that you can use when you test Spring applications. It -includes the following topics: +This section covers annotations that you can use when you test Spring applications. +It includes the following topics: * <> * <> @@ -422,9 +422,8 @@ Spring's testing annotations include the following: `@BootstrapWith` is a class-level annotation that you can use to configure how the Spring TestContext Framework is bootstrapped. Specifically, you can use `@BootstrapWith` to -specify a custom `TestContextBootstrapper`. See the -<> section for further -details. +specify a custom `TestContextBootstrapper`. See the section on +<> for further details. [[spring-testing-annotation-contextconfiguration]] ===== `@ContextConfiguration` @@ -645,7 +644,7 @@ be active: NOTE: `@ActiveProfiles` provides support for inheriting active bean definition profiles declared by superclasses by default. You can also resolve active bean definition profiles programmatically by implementing a custom -<> +<> and registering it by using the `resolver` attribute of `@ActiveProfiles`. See <> and the @@ -1080,8 +1079,8 @@ you use test lifecycle callbacks from the underlying test framework instead of ==== Spring JUnit 4 Testing Annotations The following annotations are supported only when used in conjunction with the -<>, <>, or <>: +<>, <>, or <>: * <> * <> @@ -1214,8 +1213,8 @@ how to use the `@Repeat` annotation: ==== Spring JUnit Jupiter Testing Annotations The following annotations are supported only when used in conjunction with the -<> and JUnit Jupiter (that is, the -programming model in JUnit 5): +<> and JUnit Jupiter +(that is, the programming model in JUnit 5): * <> * <> @@ -1326,11 +1325,10 @@ within that class are automatically enabled by default as well. Expressions can be any of the following: -* <> (SpEL) expression. For example: +* <> (SpEL) expression. For example: `@EnabledIf("#{systemProperties['os.name'].toLowerCase().contains('mac')}")` -* Placeholder for a property available in the Spring - <>. For example: - `@EnabledIf("${smoke.tests.enabled}")` +* Placeholder for a property available in the Spring <>. + For example: `@EnabledIf("${smoke.tests.enabled}")` * Text literal. For example: `@EnabledIf("true")` Note, however, that a text literal that is not the result of dynamic resolution of a @@ -1365,11 +1363,10 @@ test methods within that class are automatically disabled as well. Expressions can be any of the following: -* <> (SpEL) expression. For example: +* <> (SpEL) expression. For example: `@DisabledIf("#{systemProperties['os.name'].toLowerCase().contains('mac')}")` -* Placeholder for a property available in the Spring - <>. For example: - `@DisabledIf("${smoke.tests.disabled}")` +* Placeholder for a property available in the Spring <>. + For example: `@DisabledIf("${smoke.tests.disabled}")` * Text literal. For example: `@DisabledIf("true")` Note, however, that a text literal that is not the result of dynamic resolution of a @@ -1398,11 +1395,11 @@ example, you can create a custom `@DisabledOnMac` annotation as follows: ==== Meta-Annotation Support for Testing You can use most test-related annotations as -<> to create custom composed +<> to create custom composed annotations and reduce configuration duplication across a test suite. You can use each of the following as a meta-annotation in conjunction with the -<>. +<>. * `@BootstrapWith` * `@ContextConfiguration` @@ -1599,10 +1596,10 @@ required to extend a particular class hierarchy, such as the `abstract` support The following section provides an overview of the internals of the TestContext framework. If you are interested only in using the framework and are not interested in extending it with your own custom listeners or custom loaders, feel free to go directly to the -configuration (<>, -<>, <>), <>, and -<> sections. +configuration (<>, +<>, <>), <>, and +<> sections. [[testcontext-key-abstractions]] @@ -1643,24 +1640,22 @@ responsible for managing a single `TestContext` and signaling events to each reg ===== `TestExecutionListener` -`TestExecutionListener` defines the API for reacting to test-execution events published -by the `TestContextManager` with which the listener is registered. See -<>. +`TestExecutionListener` defines the API for reacting to test-execution events published by +the `TestContextManager` with which the listener is registered. See <>. ===== Context Loaders -`ContextLoader` is a strategy interface that was introduced in Spring 2.5 for loading an -`ApplicationContext` for an integration test managed by the Spring TestContext Framework. -You should implement `SmartContextLoader` instead of this interface to provide support -for annotated classes, active bean definition profiles, test property sources, context -hierarchies, and `WebApplicationContext` support. +`ContextLoader` is a strategy interface for loading an `ApplicationContext` for an +integration test managed by the Spring TestContext Framework. You should implement +`SmartContextLoader` instead of this interface to provide support for annotated classes, +active bean definition profiles, test property sources, context hierarchies, and +`WebApplicationContext` support. `SmartContextLoader` is an extension of the `ContextLoader` interface introduced in -Spring 3.1. The `SmartContextLoader` SPI supersedes the `ContextLoader` SPI that was -introduced in Spring 2.5. Specifically, a `SmartContextLoader` can choose to process -resource locations, annotated classes, or context initializers. Furthermore, a -`SmartContextLoader` can set active bean definition profiles and test property sources in -the context that it loads. +Spring 3.1, superseding the original minimal `ContextLoader` SPI. Specifically, a +`SmartContextLoader` can choose to process resource locations, annotated classes, +or context initializers. Furthermore, a `SmartContextLoader` can set active bean +definition profiles and test property sources in the context that it loads. Spring provides the following implementations: @@ -1741,7 +1736,7 @@ by default, exactly in the following order: You can register custom `TestExecutionListener` implementations for a test class and its subclasses by using the `@TestExecutionListeners` annotation. -See <> and the javadoc for +See <> and the javadoc for {api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`] for details and examples. @@ -1766,7 +1761,7 @@ file. ===== Ordering `TestExecutionListener` Implementations When the TestContext framework discovers default `TestExecutionListener` implementations -through the <> +through the <> `SpringFactoriesLoader` mechanism, the instantiated listeners are sorted by using Spring's `AnnotationAwareOrderComparator`, which honors Spring's `Ordered` interface and `@Order` annotation for ordering. `AbstractTestExecutionListener` and all default @@ -1810,8 +1805,8 @@ which listeners are registered by default. Moreover, the set of default listener change from release to release -- for example, `SqlScriptsTestExecutionListener` was introduced in Spring Framework 4.1, and `DirtiesContextBeforeModesTestExecutionListener` was introduced in Spring Framework 4.2. Furthermore, third-party frameworks like Spring -Security register their own default `TestExecutionListener` implementations by using the -aforementioned <>. To avoid having to be aware of and re-declare all default listeners, you can set the @@ -1905,8 +1900,8 @@ the web application context into your test, as follows: ==== Dependency injection by using `@Autowired` is provided by the -`DependencyInjectionTestExecutionListener`, which is configured by default (see -<>). +`DependencyInjectionTestExecutionListener`, which is configured by default +(see <>). ===== Test classes that use the TestContext framework do not need to extend any particular @@ -2011,11 +2006,11 @@ example shows how to do so: ===== Context Configuration with Groovy Scripts To load an `ApplicationContext` for your tests by using Groovy scripts that use the -<>, you can annotate +<>, you can annotate your test class with `@ContextConfiguration` and configure the `locations` or `value` attribute with an array that contains the resource locations of Groovy scripts. Resource lookup semantics for Groovy scripts are the same as those described for -<>. +<>. .Enabling Groovy script support TIP: Support for using Groovy scripts to load an `ApplicationContext` in the Spring @@ -3000,7 +2995,7 @@ Contrast the comments in this example with the previous example. -- To provide comprehensive web testing support, Spring 3.2 introduced a `ServletTestExecutionListener` that is enabled by default. When testing against a -`WebApplicationContext`, this <> +`WebApplicationContext`, this <> sets up default thread-local state by using Spring Web's `RequestContextHolder` before each test method and creates a `MockHttpServletRequest`, a `MockHttpServletResponse`, and a `ServletWebRequest` based on the base resource path configured with @@ -3287,7 +3282,7 @@ shows this configuration scenario: NOTE: If you use `@DirtiesContext` in a test whose context is configured as part of a context hierarchy, you can use the `hierarchyMode` flag to control how the context cache is cleared. For further details, see the discussion of `@DirtiesContext` in -<> and the +<> and the {api-spring-framework}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc. -- @@ -3297,12 +3292,12 @@ is cleared. For further details, see the discussion of `@DirtiesContext` in When you use the `DependencyInjectionTestExecutionListener` (which is configured by default), the dependencies of your test instances are injected from beans in the application context that you configured with `@ContextConfiguration` or related -annotations. You may use setter injection, field injection, or both, depending on which -annotations you choose and whether you place them on setter methods or fields. If you are -using JUnit Jupiter you may also optionally use constructor injection (see -<>). For consistency with the annotation support introduced -in Spring 2.5 and 3.0, you can use Spring's `@Autowired` annotation or the `@Inject` -annotation from JSR 330 for field and setter injection. +annotations. You may use setter injection, field injection, or both, depending on +which annotations you choose and whether you place them on setter methods or fields. +If you are using JUnit Jupiter you may also optionally use constructor injection +(see <>). For consistency with Spring's annotation-based +injection support, you may also use Spring's `@Autowired` annotation or the `@Inject` +annotation from JSR-330 for field and setter injection. TIP: For testing frameworks other than JUnit Jupiter, the TestContext framework does not participate in instantiation of the test class. Thus, the use of `@Autowired` or @@ -3328,7 +3323,7 @@ dependency injection altogether by explicitly configuring your class with from the list of listeners. Consider the scenario of testing a `HibernateTitleRepository` class, as outlined in the -<> section. The next two code listings demonstrate the +<> section. The next two code listings demonstrate the use of `@Autowired` on fields and setter methods. The application context configuration is presented after all sample code listings. @@ -3459,7 +3454,7 @@ bean by name there (as shown earlier, assuming that `myDataSource` is the bean ` [[testcontext-web-scoped-beans]] ==== Testing Request- and Session-scoped Beans -Spring has supported <> since the early years. Since Spring 3.2, you can test your request-scoped and session-scoped beans by following these steps: @@ -3473,7 +3468,7 @@ session-scoped beans by following these steps: The next code snippet shows the XML configuration for a login use case. Note that the `userService` bean has a dependency on a request-scoped `loginAction` bean. Also, the -`LoginAction` is instantiated by using <> that +`LoginAction` is instantiated by using <> that retrieve the username and password from the current HTTP request. In our test, we want to configure these request parameters through the mock managed by the TestContext framework. The following listing shows the configuration for this use case: @@ -3615,7 +3610,7 @@ application code that is invoked by tests). Spring-managed and application-manag transactions typically participate in test-managed transactions. However, you should use caution if Spring-managed or application-managed transactions are configured with any propagation type other than `REQUIRED` or `SUPPORTS` (see the discussion on -<> for details). +<> for details). .Preemptive timeouts and test-managed transactions [WARNING] @@ -3715,7 +3710,7 @@ database are automatically rolled back by the `TransactionalTestExecutionListene By default, test transactions will be automatically rolled back after completion of the test; however, transactional commit and rollback behavior can be configured declaratively via the `@Commit` and `@Rollback` annotations. See the corresponding entries in the -<> section for further details. +<> section for further details. [[testcontext-tx-programmatic-tx-mgt]] ===== Programmatic Transaction Management @@ -3802,7 +3797,7 @@ algorithm used to look up a transaction manager in the test's `ApplicationContex The following JUnit 4 based example displays a fictitious integration testing scenario that highlights all transaction-related annotations. The example is not intended to demonstrate best practices but rather to demonstrate how these annotations can be used. -See the <> section for further +See the <> section for further information and configuration examples. <> contains an additional example that uses `@Sql` for declarative SQL script execution with default transaction rollback semantics. The @@ -3992,7 +3987,7 @@ specifies SQL scripts for a test schema and test data, sets the statement separa Note that `ResourceDatabasePopulator` internally delegates to `ScriptUtils` for parsing and running SQL scripts. Similarly, the `executeSqlScript(..)` methods in <> -and <> +and <> internally use a `ResourceDatabasePopulator` to run SQL scripts. See the javadoc for the various `executeSqlScript(..)` methods for further details. @@ -4259,8 +4254,8 @@ This may be due to the use of `@DirtiesContext` or due to automatic eviction fro `ContextCache`. If `@DirtiesContext` is the culprit, you either need to find a way to avoid using `@DirtiesContext` or exclude such tests from parallel execution. If the maximum size of the `ContextCache` has been exceeded, you can increase the maximum size -of the cache. See the discussion on <> for details. +of the cache. See the discussion on <> +for details. ==== WARNING: Parallel test execution in the Spring TestContext Framework is only possible if @@ -4288,7 +4283,7 @@ loading application contexts, dependency injection of test instances, transactio method execution, and so on. If you want to use the Spring TestContext Framework with an alternative runner (such as JUnit 4's `Parameterized` runner) or third-party runners (such as the `MockitoJUnitRunner`), you can, optionally, use -<> instead. +<> instead. The following code listing shows the minimal requirements for configuring a test class to run with the custom Spring `Runner`: @@ -4381,8 +4376,8 @@ extend `AbstractTransactionalJUnit4SpringContextTests`, you can access a `protec database. You can use such queries to confirm database state both before and after running database-related application code, and Spring ensures that such queries run in the scope of the same transaction as the application code. When used in conjunction with -an ORM tool, be sure to avoid <>. As -mentioned in <>, +an ORM tool, be sure to avoid <>. +As mentioned in <>, `AbstractTransactionalJUnit4SpringContextTests` also provides convenience methods that delegate to methods in `JdbcTestUtils` by using the aforementioned `jdbcTemplate`. Furthermore, `AbstractTransactionalJUnit4SpringContextTests` provides an @@ -4390,7 +4385,7 @@ Furthermore, `AbstractTransactionalJUnit4SpringContextTests` provides an TIP: These classes are a convenience for extension. If you do not want your test classes to be tied to a Spring-specific class hierarchy, you can configure your own custom test -classes by using `@RunWith(SpringRunner.class)` or <>. [[testcontext-junit-jupiter-extension]] @@ -4635,8 +4630,8 @@ extend `AbstractTransactionalTestNGSpringContextTests`, you can access a `protec database. You can use such queries to confirm database state both before and after running database-related application code, and Spring ensures that such queries run in the scope of the same transaction as the application code. When used in conjunction with -an ORM tool, be sure to avoid <>. As -mentioned in <>, +an ORM tool, be sure to avoid <>. +As mentioned in <>, `AbstractTransactionalTestNGSpringContextTests` also provides convenience methods that delegate to methods in `JdbcTestUtils` by using the aforementioned `jdbcTemplate`. Furthermore, `AbstractTransactionalTestNGSpringContextTests` provides an @@ -4687,7 +4682,7 @@ Furthermore, other controller methods such as `@InitBinder`, `@ModelAttribute`, The goal of Spring MVC Test is to provide an effective way to test controllers by performing requests and generating responses through the actual `DispatcherServlet`. -Spring MVC Test builds on the familiar <> available in the `spring-test` module. This allows performing requests and generating responses without the need for running in a Servlet container. For the most part, everything should work as it does at runtime with a few notable exceptions, as @@ -4738,7 +4733,7 @@ discussed later in this document. [[spring-mvc-test-server-static-imports]] ===== Static Imports -The fluent API in the example from the <> +The fluent API in the example from the <> requires a few static imports, such as `MockMvcRequestBuilders.{asterisk}`, `MockMvcResultMatchers.{asterisk}`, and `MockMvcBuilders.{asterisk}`. An easy way to find these classes is to search for types that match `MockMvc*`. If you use Eclipse or the @@ -5197,7 +5192,7 @@ full test coverage based on Spring MVC Test. [[spring-mvc-test-server-htmlunit]] ==== HtmlUnit Integration -Spring provides integration between <> and +Spring provides integration between <> and http://htmlunit.sourceforge.net/[HtmlUnit]. This simplifies performing end-to-end testing when using HTML-based views. This integration lets you: @@ -5456,7 +5451,7 @@ assertions use the http://joel-costigliola.github.io/assertj/[AssertJ] library: ==== The preceding code improves on our -<> in a number of ways. +<> in a number of ways. First, we no longer have to explicitly verify our form and then create a request that looks like the form. Instead, we request the form, fill it out, and submit it, thereby significantly reducing the overhead. @@ -5702,8 +5697,8 @@ We can then fill out the form and submit it to create a message, as follows: ---- ==== -This improves on the design of our <> by leveraging the Page Object Pattern. As we mentioned in +This improves on the design of our <> +by leveraging the Page Object Pattern. As we mentioned in <>, we can use the Page Object Pattern with HtmlUnit, but it is much easier with WebDriver. Consider the following `CreateMessagePage` implementation: @@ -5892,7 +5887,7 @@ use http://www.gebish.org/[Geb] to make our tests even Groovy-er. ====== Why Geb and MockMvc? Geb is backed by WebDriver, so it offers many of the -<> that we get from +<> that we get from WebDriver. However, Geb makes things even easier by taking care of some of the boilerplate code for us. @@ -5952,7 +5947,7 @@ forwarded to the current page object. This removes a lot of the boilerplate code needed when using WebDriver directly. As with direct WebDriver usage, this improves on the design of our -<> by using the Page Object +<> by using the Page Object Pattern. As mentioned previously, we can use the Page Object Pattern with HtmlUnit and WebDriver, but it is even easier with Geb. Consider our new Groovy-based `CreateMessagePage` implementation: diff --git a/src/docs/asciidoc/web-reactive.adoc b/src/docs/asciidoc/web-reactive.adoc index d8a05ad8ea6..308ef40f9be 100644 --- a/src/docs/asciidoc/web-reactive.adoc +++ b/src/docs/asciidoc/web-reactive.adoc @@ -7,13 +7,13 @@ :tabsize: 4 :docinfo1: -This part of the documentation covers support for reactive-stack web applications built on a -http://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking +This part of the documentation covers support for reactive-stack web applications built +on a http://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking servers, such as Netty, Undertow, and Servlet 3.1+ containers. Individual chapters cover -the <> framework, -the reactive <>, support for <>, -and <>. For Servlet-stack web applications, see -<>. +the <> framework, +the reactive <>, support for <>, +and <>. For Servlet-stack web applications, +see <>. include::web/webflux.adoc[leveloffset=+1] @@ -26,13 +26,14 @@ include::web/webflux-websocket.adoc[leveloffset=+1] [[webflux-test]] == Testing -[.small]#<># +[.small]#<># The `spring-test` module provides mock implementations of `ServerHttpRequest`, `ServerHttpResponse`, and `ServerWebExchange`. -See <> for a discussion of mock objects. +See <> for a +discussion of mock objects. -<> builds on these mock request and +<> builds on these mock request and response objects to provide support for testing WebFlux applications without an HTTP server. You can use the `WebTestClient` for end-to-end integration tests, too. @@ -53,10 +54,10 @@ server. You can use the `WebTestClient` for end-to-end integration tests, too. `spring-webflux` depends on `reactor-core` and uses it internally to compose asynchronous logic and to provide Reactive Streams support. Generally, WebFlux APIs return `Flux` or `Mono` (since those are used internally) and leniently accept any Reactive Streams -`Publisher` implementation as input. The use of `Flux` versus `Mono` is important, because it -helps to express cardinality -- for example, whether a single or multiple asynchronous values are -expected, and that can be essential for making decisions (for example, when encoding or -decoding HTTP messages). +`Publisher` implementation as input. The use of `Flux` versus `Mono` is important, because +it helps to express cardinality -- for example, whether a single or multiple asynchronous +values are expected, and that can be essential for making decisions (for example, when +encoding or decoding HTTP messages). For annotated controllers, WebFlux transparently adapts to the reactive library chosen by the application. This is done with the help of the diff --git a/src/docs/asciidoc/web.adoc b/src/docs/asciidoc/web.adoc index e72482f4e97..aed854cfbb1 100644 --- a/src/docs/asciidoc/web.adoc +++ b/src/docs/asciidoc/web.adoc @@ -8,9 +8,9 @@ :docinfo1: This part of the documentation covers support for Servlet-stack web applications built on the -Servlet API and deployed to Servlet containers. Individual chapters include <>, -<>, <>, and <>. -For reactive-stack web applications, see <>. +Servlet API and deployed to Servlet containers. Individual chapters include <>, +<>, <>, and <>. +For reactive-stack web applications, see <>. include::web/webmvc.adoc[leveloffset=+1] diff --git a/src/docs/asciidoc/web/integration.adoc b/src/docs/asciidoc/web/integration.adoc index 0d130d8edf4..9af64e634d9 100644 --- a/src/docs/asciidoc/web/integration.adoc +++ b/src/docs/asciidoc/web/integration.adoc @@ -1,16 +1,16 @@ [[web-integration]] = Other Web Frameworks -This chapter details Spring's integration with third party web frameworks. +This chapter details Spring's integration with third-party web frameworks. One of the core value propositions of the Spring Framework is that of enabling _choice_. In a general sense, Spring does not force you to use or buy into any particular architecture, technology, or methodology (although it certainly recommends some over others). This freedom to pick and choose the architecture, technology, or methodology that is most relevant to a developer and their development team is -arguably most evident in the web area, where Spring provides its own web framework -(<>) while, at the same time, providing integration with a number of -popular third party web frameworks. +arguably most evident in the web area, where Spring provides its own web frameworks +(<> and <>) while, at the same time, +supporting integration with a number of popular third-party web frameworks. @@ -19,9 +19,8 @@ popular third party web frameworks. == Common Configuration Before diving into the integration specifics of each supported web framework, let us -first take a look at the Spring configuration that is not specific to any one web -framework. (This section is equally applicable to Spring's own web framework, Spring -MVC.) +first take a look at common Spring configuration that is not specific to any one web +framework. (This section is equally applicable to Spring's own web framework variants.) One of the concepts (for want of a better word) espoused by Spring's lightweight application model is that of a layered architecture. Remember that in a "`classic`" @@ -96,14 +95,14 @@ key. Rather than risk getting `NullPointerExceptions` in your application, it is to use the `getRequiredWebApplicationContext()` method. This method throws an exception when the `ApplicationContext` is missing. -Once you have a reference to the `WebApplicationContext`, you can retrieve beans by -their name or type. Most developers retrieve beans by name and then cast them to one of -their implemented interfaces. +Once you have a reference to the `WebApplicationContext`, you can retrieve beans by their +name or type. Most developers retrieve beans by name and then cast them to one of their +implemented interfaces. -Fortunately, most of the frameworks in this section have simpler ways of looking up -beans. Not only do they make it easy to get beans from a Spring container, but they also -let you use dependency injection on their controllers. Each web framework section -has more detail on its specific integration strategies. +Fortunately, most of the frameworks in this section have simpler ways of looking up beans. +Not only do they make it easy to get beans from a Spring container, but they also let you +use dependency injection on their controllers. Each web framework section has more detail +on its specific integration strategies. @@ -111,18 +110,14 @@ has more detail on its specific integration strategies. [[jsf]] == JSF -JavaServer Faces (JSF) is the JCP's standard component-based, event-driven web user -interface framework. As of Java EE 5, it is an official part of the Java EE umbrella. +JavaServer Faces (JSF) is the JCP's standard component-based, event-driven web +user interface framework. It is an official part of the Java EE umbrella but also +individually usable, e.g. through embedding Mojarra or MyFaces within Tomcat. -For a popular JSF runtime as well as for popular JSF component libraries, check out the -http://myfaces.apache.org/[Apache MyFaces project]. The MyFaces project also provides -common JSF extensions, such as http://myfaces.apache.org/orchestra/[MyFaces Orchestra] -(a Spring-based JSF extension that provides rich conversation scope support). - -NOTE: Spring Web Flow 2.0 provides rich JSF support through its newly established Spring Faces -module, both for JSF-centric usage (as described in this section) and for Spring-centric -usage (using JSF views within a Spring MVC dispatcher). See the -http://projects.spring.io/spring-webflow[Spring Web Flow website] for details. +Please note that recent versions of JSF became closely tied to CDI infrastructure +in application servers, with some new JSF functionality only working in such an +environment. Spring's JSF support is not actively evolved anymore and primarily +exists for migration purposes when modernizing older JSF-based applications. The key element in Spring's JSF integration is the JSF `ELResolver` mechanism. @@ -131,11 +126,10 @@ The key element in Spring's JSF integration is the JSF `ELResolver` mechanism. [[jsf-springbeanfaceselresolver]] === Spring Bean Resolver -`SpringBeanFacesELResolver` is a JSF 1.2+ compliant `ELResolver` implementation, -integrating with the standard Unified EL as used by JSF 1.2 and JSP 2.1. As -`SpringBeanVariableResolver`, it delegates to Spring's "`business context`" -`WebApplicationContext` first and then to the default resolver of the underlying JSF -implementation. +`SpringBeanFacesELResolver` is a JSF compliant `ELResolver` implementation, +integrating with the standard Unified EL as used by JSF and JSP. It delegates to +Spring's "`business context`" `WebApplicationContext` first and then to the +default resolver of the underlying JSF implementation. Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF `faces-context.xml` file, as the following example shows: @@ -158,11 +152,11 @@ Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF [[jsf-facescontextutils]] === Using `FacesContextUtils` -A custom `VariableResolver` works well when mapping your properties to beans -in `faces-config.xml`, but, at times, you may need to explicitly grab a bean. The -{api-spring-framework}/web/jsf/FacesContextUtils.html[`FacesContextUtils`] -class makes this easy. It is similar to `WebApplicationContextUtils`, except that it -takes a `FacesContext` parameter rather than a `ServletContext` parameter. +A custom `ELResolver` works well when mapping your properties to beans in +`faces-config.xml`, but, at times, you may need to explicitly grab a bean. +The {api-spring-framework}/web/jsf/FacesContextUtils.html[`FacesContextUtils`] +class makes this easy. It is similar to `WebApplicationContextUtils`, except that +it takes a `FacesContext` parameter rather than a `ServletContext` parameter. The following example shows how to use `FacesContextUtils`: @@ -183,30 +177,29 @@ The following example shows how to use `FacesContextUtils`: Invented by Craig McClanahan, http://struts.apache.org[Struts] is an open-source project hosted by the Apache Software Foundation. At the time, it greatly simplified the JSP/Servlet programming paradigm and won over many developers who were using proprietary -frameworks. It simplified the programming model, it was open source (and thus free, as in -beer), and it had a large community, which let the project grow and become popular -among Java web developers. +frameworks. It simplified the programming model, it was open source (and thus free as in +beer), and it had a large community, which let the project grow and become popular among +Java web developers. -Check out the Struts +As a successor to the original Struts 1.x, check out Struts 2.x and the Struts-provided https://struts.apache.org/release/2.3.x/docs/spring-plugin.html[Spring Plugin] for the -built-in Spring integration shipped with Struts. +built-in Spring integration. [[tapestry]] -== Tapestry 5.x +== Apache Tapestry 5.x -http://tapestry.apache.org/[Tapestry] is a ""Component oriented framework for creating dynamic, robust, -highly scalable web applications in Java."" +http://tapestry.apache.org/[Tapestry] is a ""Component oriented framework for creating +dynamic, robust, highly scalable web applications in Java."" -While Spring has its own <>, there are a number of unique +While Spring has its own <>, there are a number of unique advantages to building an enterprise Java application by using a combination of Tapestry for the web user interface and the Spring container for the lower layers. For more information, see Tapestry's dedicated -https://tapestry.apache.org/integrating-with-spring-framework.html[integration module for -Spring]. +https://tapestry.apache.org/integrating-with-spring-framework.html[integration module for Spring]. @@ -214,8 +207,8 @@ Spring]. [[web-integration-resources]] == Further Resources -The following links go to further resources about the various web frameworks described in this -chapter. +The following links go to further resources about the various web frameworks described in +this chapter. * The http://www.oracle.com/technetwork/java/javaee/javaserverfaces-139869.html[JSF] homepage * The http://struts.apache.org/[Struts] homepage diff --git a/src/docs/asciidoc/web/web-uris.adoc b/src/docs/asciidoc/web/web-uris.adoc index 7c1453a58fa..a46a17d12de 100644 --- a/src/docs/asciidoc/web/web-uris.adoc +++ b/src/docs/asciidoc/web/web-uris.adoc @@ -71,10 +71,10 @@ You shorter it further still with a full URI template, as the following example = UriBuilder [.small]#Spring MVC and Spring WebFlux# -<> implements `UriBuilder`. You can create a `UriBuilder`, in turn, -with a `UriBuilderFactory`. Together, `UriBuilderFactory` and `UriBuilder` -provide a pluggable mechanism to build URIs from URI templates, based on shared -configuration, such as a base URL, encoding preferences, and other details. +<> implements `UriBuilder`. You can create a +`UriBuilder`, in turn, with a `UriBuilderFactory`. Together, `UriBuilderFactory` and +`UriBuilder` provide a pluggable mechanism to build URIs from URI templates, based on +shared configuration, such as a base URL, encoding preferences, and other details. You can configure `RestTemplate` and `WebClient` with a `UriBuilderFactory` to customize the preparation of URIs. `DefaultUriBuilderFactory` is a default diff --git a/src/docs/asciidoc/web/webflux-cors.adoc b/src/docs/asciidoc/web/webflux-cors.adoc index d981d41d2a9..03e87844a89 100644 --- a/src/docs/asciidoc/web/webflux-cors.adoc +++ b/src/docs/asciidoc/web/webflux-cors.adoc @@ -1,6 +1,6 @@ [[webflux-cors]] = CORS -[.small]#<># +[.small]#<># Spring WebFlux lets you handle CORS (Cross-Origin Resource Sharing). This section describes how to do so. @@ -10,7 +10,7 @@ describes how to do so. [[webflux-cors-intro]] == Introduction -[.small]#<># +[.small]#<># For security reasons, browsers prohibit AJAX calls to resources outside the current origin. For example, you could have your bank account in one tab and evil.com in another. Scripts @@ -27,7 +27,7 @@ powerful workarounds based on IFRAME or JSONP. [[webflux-cors-processing]] == Processing -[.small]#<># +[.small]#<># The CORS specification distinguishes between preflight, simple, and actual requests. To learn how CORS works, you can read @@ -77,7 +77,7 @@ To learn more from the source or to make advanced customizations, see: [[webflux-cors-controller]] == `@CrossOrigin` -[.small]#<># +[.small]#<># The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`] annotation enables cross-origin requests on annotated controller methods, as the @@ -176,7 +176,7 @@ public class AccountController { [[webflux-cors-global]] == Global Configuration -[.small]#<># +[.small]#<># In addition to fine-grained, controller method-level configuration, you probably want to define some global CORS configuration, too. You can set URL-based `CorsConfiguration` @@ -227,11 +227,11 @@ public class WebConfig implements WebFluxConfigurer { [[webflux-cors-webfilter]] == CORS `WebFilter` -[.small]#<># +[.small]#<># You can apply CORS support through the built-in {api-spring-framework}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a -good fit with <>. +good fit with <>. NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring Security has diff --git a/src/docs/asciidoc/web/webflux-functional.adoc b/src/docs/asciidoc/web/webflux-functional.adoc index a99319ca8ec..9d318ad2787 100644 --- a/src/docs/asciidoc/web/webflux-functional.adoc +++ b/src/docs/asciidoc/web/webflux-functional.adoc @@ -66,7 +66,7 @@ public class PersonHandler { ==== One way to run a `RouterFunction` is to turn it into an `HttpHandler` and install it -through one of the built-in <>: +through one of the built-in <>: * `RouterFunctions.toHttpHandler(RouterFunction)` * `RouterFunctions.toHttpHandler(RouterFunction, HandlerStrategies)` @@ -85,7 +85,7 @@ Both request and response provide http://www.reactive-streams.org[Reactive Strea against the body streams. The request body is represented with a Reactor `Flux` or `Mono`. The response body is represented with any Reactive Streams `Publisher`, including `Flux` and `Mono`. -For more on that, see <>. +For more on that, see <>. @@ -255,9 +255,9 @@ found. If it is not found, we use `switchIfEmpty(Mono)` to return a 404 Not F [[webflux-fn-handler-validation]] === Validation -A functional endpoint can use Spring's <> to +A functional endpoint can use Spring's <> to apply validation to the request body. For example, given a custom Spring -<> implementation for a `Person`: +<> implementation for a `Person`: ==== [source,java,indent=0] @@ -290,7 +290,7 @@ public class PersonHandler { Handlers can also use the standard bean validation API (JSR-303) by creating and injecting a global `Validator` instance based on `LocalValidatorFactoryBean`. -See <>. +See <>. @@ -454,10 +454,10 @@ function to an `HttpHandler` by using one of the following: * `RouterFunctions.toHttpHandler(RouterFunction, HandlerStrategies)` You can then use the returned `HttpHandler` with a number of server adapters by following -<> for server-specific instructions. +<> for server-specific instructions. A more typical option, also used by Spring Boot, is to run with a -<>-based setup through the +<>-based setup through the <>, which uses Spring configuration to declare the components required to process requests. The WebFlux Java configuration declares the following infrastructure components to support functional endpoints: @@ -476,7 +476,7 @@ any are declared. It is also how functional endpoints are enabled by the Spring starter. The following example shows a WebFlux Java configuration (see -<> for how to run it): +<> for how to run it): ==== [source,java,indent=0] @@ -590,4 +590,5 @@ We allow only the handler function to be executed when access is allowed. Besides using the `filter` method on the router function builder, it is possible to apply a filter to an existing router function via `RouterFunction.filter(HandlerFilterFunction)`. -NOTE: CORS support for functional endpoints is provided through a dedicated <>. +NOTE: CORS support for functional endpoints is provided through a dedicated +<>. diff --git a/src/docs/asciidoc/web/webflux-view.adoc b/src/docs/asciidoc/web/webflux-view.adoc index 2377ba15a76..005da730fa9 100644 --- a/src/docs/asciidoc/web/webflux-view.adoc +++ b/src/docs/asciidoc/web/webflux-view.adoc @@ -1,6 +1,6 @@ [[webflux-view]] = View Technologies -[.small]#<># +[.small]#<># The use of view technologies in Spring WebFlux is pluggable. Whether you decide to use Thymeleaf, FreeMarker, or some other view technology is primarily a matter of a @@ -12,7 +12,7 @@ WebFlux. We assume you are already familiar with <>. [[webflux-view-thymeleaf]] == Thymeleaf -[.small]#<># +[.small]#<># Thymeleaf is a modern server-side Java template engine that emphasizes natural HTML templates that can be previewed in a browser by double-clicking, which is very @@ -33,7 +33,7 @@ http://forum.thymeleaf.org/Thymeleaf-3-0-8-JUST-PUBLISHED-td4030687.html[announc [[webflux-view-freemarker]] == FreeMarker -[.small]#<># +[.small]#<># http://www.freemarker.org[Apache FreeMarker] is a template engine for generating any kind of text output from HTML to email and others. The Spring Framework has a built-in @@ -43,7 +43,7 @@ integration for using Spring WebFlux with FreeMarker templates. [[webflux-view-freemarker-contextconfig]] === View Configuration -[.small]#<># +[.small]#<># The following example shows how to configure FreeMarker as a view technology: @@ -81,7 +81,7 @@ shown in the preceding example. Given the preceding configuration, if your contr [[webflux-views-freemarker]] === FreeMarker Configuration -[.small]#<># +[.small]#<># You can pass FreeMarker 'Settings' and 'SharedVariables' directly to the FreeMarker `Configuration` object (managed by Spring) by setting the appropriate bean properties on @@ -121,7 +121,7 @@ the `Configuration` object. [[webflux-view-script]] == Script Views -[.small]#<># +[.small]#<># The Spring Framework has a built-in integration for using Spring WebFlux with any templating library that can run on top of the @@ -147,7 +147,7 @@ TIP: The basic rule for integrating any other script engine is that it must impl [[webflux-view-script-dependencies]] === Requirements -[.small]#<># +[.small]#<># You need to have the script engine on your classpath, the details of which vary by script engine: @@ -167,7 +167,7 @@ through http://www.webjars.org/[WebJars]. [[webflux-view-script-integrate]] === Script Templates -[.small]#<># +[.small]#<># You can declare a `ScriptTemplateConfigurer` bean to specify the script engine to use, the script files to load, what function to call to render templates, and so on. @@ -286,20 +286,20 @@ for more configuration examples. [[webflux-view-httpmessagewriter]] == JSON and XML -[.small]#<># +[.small]#<># For <> purposes, it is useful to be able to alternate between rendering a model with an HTML template or as other formats (such as JSON or XML), depending on the content type requested by the client. To support doing so, Spring WebFlux provides the `HttpMessageWriterView`, which you can use to plug in any of the available -<> from `spring-web`, such as `Jackson2JsonEncoder`, -`Jackson2SmileEncoder`, or `Jaxb2XmlEncoder`. +<> from `spring-web`, such as `Jackson2JsonEncoder`, `Jackson2SmileEncoder`, +or `Jaxb2XmlEncoder`. Unlike other view technologies, `HttpMessageWriterView` does not require a `ViewResolver` -but is instead <> as a default view. You can -configure one or more such default views, wrapping different `HttpMessageWriter` instances or -`Encoder` instances. The one that matches the requested content type is used at runtime. +but is instead <> as a default view. You can +configure one or more such default views, wrapping different `HttpMessageWriter` instances +or `Encoder` instances. The one that matches the requested content type is used at runtime. -In most cases, a model contains multiple attributes. To determine which one -to serialize, you can configure `HttpMessageWriterView` with the name of the model -attribute to use for rendering. If the model contains only one attribute, that one is used. +In most cases, a model contains multiple attributes. To determine which one to serialize, +you can configure `HttpMessageWriterView` with the name of the model attribute to use for +rendering. If the model contains only one attribute, that one is used. diff --git a/src/docs/asciidoc/web/webflux-webclient.adoc b/src/docs/asciidoc/web/webflux-webclient.adoc index c9ddf2ebc29..6964090f820 100644 --- a/src/docs/asciidoc/web/webflux-webclient.adoc +++ b/src/docs/asciidoc/web/webflux-webclient.adoc @@ -4,7 +4,7 @@ Spring WebFlux includes a reactive, non-blocking `WebClient` for HTTP requests. The client has a functional, fluent API with reactive types for declarative composition, see <>. WebFlux client and server rely on the -same non-blocking <> to encode and decode request +same non-blocking <> to encode and decode request and response content. Internally `WebClient` delegates to an HTTP client library. By default, it uses @@ -36,7 +36,7 @@ You can also use `WebClient.builder()` with further options: * `exchangeStrategies`: HTTP message reader/writer customizations. * `clientConnector`: HTTP client library settings. -The following example configures <>: +The following example configures <>: ==== [source,java,intent=0] diff --git a/src/docs/asciidoc/web/webflux-websocket.adoc b/src/docs/asciidoc/web/webflux-websocket.adoc index e2a9d9bf202..104283ec716 100644 --- a/src/docs/asciidoc/web/webflux-websocket.adoc +++ b/src/docs/asciidoc/web/webflux-websocket.adoc @@ -1,6 +1,6 @@ [[webflux-websocket]] = WebSockets -[.small]#<># +[.small]#<># This part of the reference documentation covers support for reactive-stack WebSocket messaging. @@ -12,7 +12,7 @@ include::websocket-intro.adoc[leveloffset=+1] [[webflux-websocket-server]] == WebSocket API -[.small]#<># +[.small]#<># The Spring Framework provides a WebSocket API that you can use to write client- and server-side applications that handle WebSocket messages. @@ -21,7 +21,7 @@ server-side applications that handle WebSocket messages. [[webflux-websocket-server-handler]] === Server -[.small]#<># +[.small]#<># To create a WebSocket server, you can first create a `WebSocketHandler`. The following example shows how to do so: @@ -138,7 +138,7 @@ class ExampleHandler implements WebSocketHandler { TIP: For nested, asynchronous operations, you may need to call `message.retain()` on underlying servers that use pooled data buffers (for example, Netty). Otherwise, the data buffer may be released before you have had a chance to read the data. For more background, see -<>. +<>. The following implementation combines the inbound and outbound streams: @@ -209,7 +209,7 @@ class ExampleHandler implements WebSocketHandler { `DataBuffer` is the representation for a byte buffer in WebFlux. The Spring Core part of the reference has more on that in the section on -<>. The key point to understand is that on some +<>. The key point to understand is that on some servers like Netty, byte buffers are pooled and reference counted, and must be released when consumed to avoid memory leaks. @@ -222,7 +222,7 @@ subsequently use `DataBufferUtils.release(dataBuffer)` when the buffers are cons [[webflux-websocket-server-handshake]] === Handshake -[.small]#<># +[.small]#<># `WebSocketHandlerAdapter` delegates to a `WebSocketService`. By default, that is an instance of `HandshakeWebSocketService`, which performs basic checks on the WebSocket request and @@ -237,7 +237,7 @@ into the attributes of the `WebSocketSession`. [[webflux-websocket-server-config]] === Server Configation -[.small]#<># +[.small]#<># The `RequestUpgradeStrategy` for each server exposes WebSocket-related configuration options available for the underlying WebSocket engine. The following example sets @@ -272,7 +272,7 @@ only Tomcat and Jetty expose such options. [[webflux-websocket-server-cors]] === CORS -[.small]#<># +[.small]#<># The easiest way to configure CORS and restrict access to a WebSocket endpoint is to have your `WebSocketHandler` implement `CorsConfigurationSource` and return a diff --git a/src/docs/asciidoc/web/webflux.adoc b/src/docs/asciidoc/web/webflux.adoc index bfbcc662c1a..57a5bbc94c5 100644 --- a/src/docs/asciidoc/web/webflux.adoc +++ b/src/docs/asciidoc/web/webflux.adoc @@ -107,8 +107,8 @@ of RxJava or another reactive library. See <> for mo === Programming Models The `spring-web` module contains the reactive foundation that underlies Spring WebFlux, -including HTTP abstractions, Reactive Streams <> for supported -servers, <>, and a core <> comparable to +including HTTP abstractions, Reactive Streams <> for supported +servers, <>, and a core <> comparable to the Servlet API but with non-blocking contracts. On that foundation, Spring WebFlux provides a choice of two programming models: @@ -167,7 +167,7 @@ RxJava to perform blocking calls on a separate thread but you would not be makin most of a non-blocking web stack. * If you have a Spring MVC application with calls to remote services, try the reactive `WebClient`. -You can return reactive types (Reactor, RxJava, <>) +You can return reactive types (Reactor, RxJava, <>) directly from Spring MVC controller methods. The greater the latency per call or the interdependency among calls, the more dramatic the benefits. Spring MVC controllers can call other reactive components too. @@ -186,12 +186,12 @@ unsure what benefits to look for, start by learning about how non-blocking I/O w Spring WebFlux is supported on Tomcat, Jetty, Servlet 3.1+ containers, as well as on non-Servlet runtimes such as Netty and Undertow. All servers are adapted to a low-level, -<> so that higher-level -<> can be supported across servers. +<> so that higher-level +<> can be supported across servers. Spring WebFlux does not have built-in support to start or stop a server. However, it is -easy to <> an application from Spring configuration and -<> and <> with a few +easy to <> an application from Spring configuration and +<> and <> with a few lines of code. Spring Boot has a WebFlux starter that automates these steps. By default, the starter uses @@ -284,11 +284,11 @@ of their own. .Configuring The Spring Framework does not provide support for starting and stopping -<>. To configure the threading model for a server, you -need to use server-specific configuration APIs, or, if you use Spring Boot, check the Spring -Boot configuration options for each server. You can <> The `WebClient` -directly. For all other -libraries, see their respective documentation. +<>. To configure the threading model for a server, +you need to use server-specific configuration APIs, or, if you use Spring Boot, +check the Spring Boot configuration options for each server. You can +<> the `WebClient` directly. +For all other libraries, see their respective documentation. @@ -300,7 +300,7 @@ The `spring-web` module contains the following foundational support for reactive applications: * For server request processing there are two levels of support. -** <>: Basic contract for HTTP request handling with +** <>: Basic contract for HTTP request handling with non-blocking I/O and Reactive Streams back pressure, along with adapters for Reactor Netty, Undertow, Tomcat, Jetty, and any Servlet 3.1+ container. ** <>: Slightly higher level, general-purpose web API for @@ -310,9 +310,9 @@ controllers and functional endpoints are built. requests with non-blocking I/O and Reactive Streams back pressure, along with adapters for https://github.com/reactor/reactor-netty[Reactor Netty] and for the reactive https://github.com/jetty-project/jetty-reactive-httpclient[Jetty HttpClient]. -The higher level <> used in applications +The higher level <> used in applications builds on this basic contract. -* For client and server, <> to use to serialize and +* For client and server, <> to use to serialize and deserialize HTTP request and response content. @@ -453,7 +453,7 @@ to provide a general-purpose web API for processing requests through a chain of {api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. The chain can be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring `ApplicationContext` where components are -<>, and/or by registering components +<>, and/or by registering components with the builder. While `HttpHandler` has a simple goal to abstract the use of different HTTP servers, the @@ -536,12 +536,12 @@ Mono> getFormData(); The `DefaultServerWebExchange` uses the configured `HttpMessageReader` to parse form data (`application/x-www-form-urlencoded`) into a `MultiValueMap`. By default, `FormHttpMessageReader` is configured for use by the `ServerCodecConfigurer` bean -(see the <>). +(see the <>). [[webflux-multipart]] ==== Multipart Data -[.small]#<># +[.small]#<># `ServerWebExchange` exposes the following method for access to multipart data: @@ -559,7 +559,7 @@ into a `MultiValueMap`. At present, https://github.com/synchronoss/nio-multipart[Synchronoss NIO Multipart] is the only third-party library supported and the only library we know for non-blocking parsing of multipart requests. It is enabled through the `ServerCodecConfigurer` bean -(see the <>). +(see the <>). To parse multipart data in streaming fashion, you can use the `Flux` returned from an `HttpMessageReader` instead. For example, in an annotated controller, use of @@ -570,7 +570,7 @@ content to `Flux` without collecting to a `MultiValueMap`. [[webflux-forwarded-headers]] ==== Forwarded Headers -[.small]#<># +[.small]#<># As a request goes through proxies (such as load balancers), the host, port, and scheme may change, and that makes it a challenge, from a client perspective, to create links that point to the correct @@ -601,7 +601,7 @@ filters, and `ForwardedHeaderTransformer` is used instead. [[webflux-filters]] === Filters -[.small]#<># +[.small]#<># In the <>, you can use a `WebFilter` to apply interception-style logic before and after the rest of the processing chain of filters and the target @@ -612,7 +612,7 @@ the bean declaration or by implementing `Ordered`. [[webflux-filters-cors]] ==== CORS -[.small]#<># +[.small]#<># Spring WebFlux provides fine-grained support for CORS configuration through annotations on controllers. However, when you use it with Spring Security, we advise relying on the built-in @@ -624,7 +624,7 @@ See the section on <> and the <> for more [[webflux-exception-handler]] === Exceptions -[.small]#<># +[.small]#<># In the <>, you can use a `WebExceptionHandler` to handle exceptions from the chain of `WebFilter` instances and the target `WebHandler`. When using the @@ -655,7 +655,7 @@ The following table describes the available `WebExceptionHandler` implementation [[webflux-codecs]] === Codecs -[.small]#<># +[.small]#<># The `spring-web` and `spring-core` modules provide support for serializing and deserializing byte content to and from higher level objects through non-blocking I/O with @@ -763,7 +763,7 @@ for repeated, map-like access to parts, or otherwise rely on the [[webflux-codecs-streaming]] ==== Streaming -[.small]#<># +[.small]#<># When streaming to the HTTP response (for example, `text/event-stream`, `application/stream+json`), it is important to send data periodically, in order to @@ -777,15 +777,15 @@ a heartbeat. `DataBuffer` is the representation for a byte buffer in WebFlux. The Spring Core part of the reference has more on that in the section on -<>. The key point to understand is that on some +<>. The key point to understand is that on some servers like Netty, byte buffers are pooled and reference counted, and must be released when consumed to avoid memory leaks. WebFlux applications generally do not need to be concerned with such issues, unless they consume or produce data buffers directly, as opposed to relying on codecs to convert to and from higher level objects. Or unless they choose to create custom codecs. For such -cases please review the the information in <>, -especially the section on <>. +cases please review the the information in <>, +especially the section on <>. @@ -793,7 +793,7 @@ especially the section on <>. [[webflux-logging]] === Logging -[.small]#<># +[.small]#<># DEBUG level logging in Spring WebFlux is designed to be compact, minimal, and human-friendly. It focuses on high value bits of information that are useful over and @@ -825,7 +825,7 @@ while a fully formatted prefix based on that ID is available from [[webflux-logging-sensitive-data]] ==== Sensitive Data -[.small]#<># +[.small]#<># `DEBUG` and `TRACE` logging can log sensitive information. This is why form parameters and headers are masked by default and you must explicitly enable their logging in full. @@ -868,11 +868,11 @@ WebClient webClient = WebClient.builder() [[webflux-dispatcher-handler]] == `DispatcherHandler` -[.small]#<># +[.small]#<># -Spring WebFlux, similarly to Spring MVC, is designed around the front controller pattern, where a -central `WebHandler`, the `DispatcherHandler`, provides a shared algorithm for request -processing, while actual work is performed by configurable, delegate components. +Spring WebFlux, similarly to Spring MVC, is designed around the front controller pattern, +where a central `WebHandler`, the `DispatcherHandler`, provides a shared algorithm for +request processing, while actual work is performed by configurable, delegate components. This model is flexible and supports diverse workflows. `DispatcherHandler` discovers the delegate components it needs from Spring configuration. @@ -880,8 +880,7 @@ It is also designed to be a Spring bean itself and implements `ApplicationContex for access to the context in which it runs. If `DispatcherHandler` is declared with a bean name of `webHandler`, it is, in turn, discovered by {api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`], -which puts together a request-processing chain, as described in -<>. +which puts together a request-processing chain, as described in <>. Spring configuration in a WebFlux application typically contains: @@ -902,14 +901,13 @@ HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context); ---- ==== -The resulting `HttpHandler` is ready for use with a -<>. +The resulting `HttpHandler` is ready for use with a <>. [[webflux-special-bean-types]] === Special Bean Types -[.small]#<># +[.small]#<># The `DispatcherHandler` delegates to special beans to process requests and render the appropriate responses. By "`special beans,`" we mean Spring-managed `Object` instances that @@ -951,11 +949,11 @@ there are also some other beans detected at a lower level (see [[webflux-framework-config]] === WebFlux Config -[.small]#<># +[.small]#<># Applications can declare the infrastructure beans (listed under -<> and -<>) that are required to process requests. +<> and +<>) that are required to process requests. However, in most cases, the <> is the best starting point. It declares the required beans and provides a higher-level configuration callback API to customize it. @@ -966,7 +964,7 @@ many extra convenient options. [[webflux-dispatcher-handler-sequence]] === Processing -[.small]#<># +[.small]#<># `DispatcherHandler` processes requests as follows: @@ -1017,7 +1015,7 @@ as a `HandlerResult`, along with some additional context, and passed to the firs [[webflux-dispatcher-exceptions]] === Exceptions -[.small]#<># +[.small]#<># The `HandlerResult` returned from a `HandlerAdapter` can expose a function for error handling based on some handler-specific mechanism. This error function is called if: @@ -1040,18 +1038,18 @@ See also <> in the "`Annotated Controller`" s [[webflux-viewresolution]] === View Resolution -[.small]#<># +[.small]#<># View resolution enables rendering to a browser with an HTML template and a model without tying you to a specific view technology. In Spring WebFlux, view resolution is -supported through a dedicated <> that uses +supported through a dedicated <> that uses `ViewResolver` instances to map a String (representing a logical view name) to a `View` instance. The `View` is then used to render the response. [[webflux-viewresolution-handling]] ==== Handling -[.small]#<># +[.small]#<># The `HandlerResult` passed into `ViewResolutionResultHandler` contains the return value from the handler and the model that contains attributes added during request @@ -1079,7 +1077,7 @@ value or no value (if empty), while multi-value reactive types (for example, `Fl collected and resolved to `List`. To configure view resolution is as simple as adding a `ViewResolutionResultHandler` bean -to your Spring configuration. <> provides a +to your Spring configuration. <> provides a dedicated configuration API for view resolution. See <> for more on the view technologies integrated with Spring WebFlux. @@ -1087,7 +1085,7 @@ See <> for more on the view technologies integrated with Spring We [[webflux-redirecting-redirect-prefix]] ==== Redirecting -[.small]#<># +[.small]#<># The special `redirect:` prefix in a view name lets you perform a redirect. The `UrlBasedViewResolver` (and sub-classes) recognize this as an instruction that a @@ -1102,7 +1100,7 @@ operate in terms of logical view names. A view name such as [[webflux-multiple-representations]] ==== Content Negotiation -[.small]#<># +[.small]#<># `ViewResolutionResultHandler` supports content negotiation. It compares the request media types with the media types supported by each selected `View`. The first `View` @@ -1110,8 +1108,8 @@ that supports the requested media type(s) is used. In order to support media types such as JSON and XML, Spring WebFlux provides `HttpMessageWriterView`, which is a special `View` that renders through an -<>. Typically, you would configure these as default -views through the <>. Default views are +<>. Typically, you would configure these as default +views through the <>. Default views are always selected and used if they match the requested media type. @@ -1119,7 +1117,7 @@ always selected and used if they match the requested media type. [[webflux-controller]] == Annotated Controllers -[.small]#<># +[.small]#<># Spring WebFlux provides an annotation-based programming model, where `@Controller` and `@RestController` components use annotations to express request mappings, request input, @@ -1149,7 +1147,7 @@ In the preceding example, the method returns a `String` to be written to the res [[webflux-ann-controller]] === `@Controller` -[.small]#<># +[.small]#<># You can define controller beans by using a standard Spring bean definition. The `@Controller` stereotype allows for auto-detection and is aligned with Spring general support @@ -1174,7 +1172,7 @@ your Java configuration, as the following example shows: <1> Scan the `org.example.web` package. ==== -`@RestController` is a <> that is +`@RestController` is a <> that is itself meta-annotated with `@Controller` and `@ResponseBody`, indicating a controller whose every method inherits the type-level `@ResponseBody` annotation and, therefore, writes directly to the response body versus view resolution and rendering with an HTML template. @@ -1183,7 +1181,7 @@ directly to the response body versus view resolution and rendering with an HTML [[webflux-ann-requestmapping]] === Request Mapping -[.small]#<># +[.small]#<># The `@RequestMapping` annotation is used to map requests to controllers methods. It has various attributes to match by URL, HTTP method, request parameters, headers, and media @@ -1230,7 +1228,7 @@ The following example uses type and method level mappings: [[webflux-ann-requestmapping-uri-templates]] ==== URI Patterns -[.small]#<># +[.small]#<># You can map requests by using glob patterns and wildcards: @@ -1317,7 +1315,7 @@ explicit, and less vulnerable to URL path based exploits. [[webflux-ann-requestmapping-pattern-comparison]] ==== Pattern Comparison -[.small]#<># +[.small]#<># When multiple patterns match a URL, they must be compared to find the best match. This is done with `PathPattern.SPECIFICITY_COMPARATOR`, which looks for patterns that are more specific. @@ -1332,7 +1330,7 @@ sorted last instead. If two patterns are both catch-all, the longer is chosen. [[webflux-ann-requestmapping-consumes]] ==== Consumable Media Types -[.small]#<># +[.small]#<># You can narrow the request mapping based on the `Content-Type` of the request, as the following example shows: @@ -1361,7 +1359,7 @@ TIP: `MediaType` provides constants for commonly used media types -- for example [[webflux-ann-requestmapping-produces]] ==== Producible Media Types -[.small]#<># +[.small]#<># You can narrow the request mapping based on the `Accept` request header and the list of content types that a controller method produces, as the following example shows: @@ -1396,7 +1394,7 @@ TIP: `MediaType` provides constants for commonly used media types -- e.g. [[webflux-ann-requestmapping-params-and-headers]] ==== Parameters and Headers -[.small]#<># +[.small]#<># You can narrow request mappings based on query parameter conditions. You can test for the presence of a query parameter (`myParam`), for its absence (`!myParam`), or for a @@ -1431,7 +1429,7 @@ You can also use the same with request header conditions, as the follwing exampl [[webflux-ann-requestmapping-head-options]] ==== HTTP HEAD, OPTIONS -[.small]#<># +[.small]#<># `@GetMapping` and `@RequestMapping(method=HttpMethod.GET)` support HTTP HEAD transparently for request mapping purposes. Controller methods need not change. @@ -1452,9 +1450,9 @@ is not necessary in the common case. [[webflux-ann-requestmapping-composed]] ==== Custom Annotations -[.small]#<># +[.small]#<># -Spring WebFlux supports the use of <> +Spring WebFlux supports the use of <> for request mapping. Those are annotations that are themselves meta-annotated with `@RequestMapping` and composed to redeclare a subset (or all) of the `@RequestMapping` attributes with a narrower, more specific purpose. @@ -1473,7 +1471,7 @@ you can check the custom attribute and return your own `RequestCondition`. [[webflux-ann-requestmapping-registration]] ==== Explicit Registrations -[.small]#<># +[.small]#<># You can programmatically register Handler methods, which can be used for dynamic registrations or for advanced cases, such as different instances of the same handler @@ -1510,7 +1508,7 @@ public class MyConfig { [[webflux-ann-methods]] === Handler Methods -[.small]#<># +[.small]#<># `@RequestMapping` handler methods have a flexible signature and can choose from a range of supported controller method arguments and return values. @@ -1518,11 +1516,11 @@ supported controller method arguments and return values. [[webflux-ann-arguments]] ==== Method Arguments -[.small]#<># +[.small]#<># The following table shows the supported controller method arguments. -Reactive types (Reactor, RxJava, <>) are +Reactive types (Reactor, RxJava, <>) are supported on arguments that require blocking I/O (for example, reading the request body) to be resolved. This is marked in the Description column. Reactive types are not expected on arguments that do not require blocking. @@ -1639,10 +1637,10 @@ and others) and is equivalent to `required=false`. [[webflux-ann-return-types]] ==== Return Values -[.small]#<># +[.small]#<># -The following table shows the supported controller method return values. Note that reactive types -from libraries such as Reactor, RxJava, <> are +The following table shows the supported controller method return values. Note that reactive +types from libraries such as Reactor, RxJava, <> are generally supported for all return values. [cols="1,2", options="header"] @@ -1665,12 +1663,13 @@ generally supported for all return values. | A view name to be resolved with `ViewResolver` instances and used together with the implicit model -- determined through command objects and `@ModelAttribute` methods. The handler method can also programmatically enrich the model by declaring a `Model` argument - (described <>). + (described <>). | `View` | A `View` instance to use for rendering together with the implicit model -- determined through command objects and `@ModelAttribute` methods. The handler method can also - programmatically enrich the model by declaring a `Model` argument (described <>). + programmatically enrich the model by declaring a `Model` argument + (described <>). | `java.util.Map`, `org.springframework.ui.Model` | Attributes to be added to the implicit model, with the view name implicitly determined @@ -1712,7 +1711,7 @@ generally supported for all return values. [[webflux-ann-typeconversion]] ==== Type Conversion -[.small]#<># +[.small]#<># Some annotated controller method arguments that represent String-based request input (for example, `@RequestParam`, `@RequestHeader`, `@PathVariable`, `@MatrixVariable`, and `@CookieValue`) @@ -1721,13 +1720,12 @@ can require type conversion if the argument is declared as something other than For such cases, type conversion is automatically applied based on the configured converters. By default, simple types (such as `int`, `long`, `Date`, and others) are supported. Type conversion can be customized through a `WebDataBinder` (see <>) or by registering -`Formatters` with the `FormattingConversionService` (see -<>). +`Formatters` with the `FormattingConversionService` (see <>). [[webflux-ann-matrix-variables]] ==== Matrix Variables -[.small]#<># +[.small]#<># http://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in path segments. In Spring WebFlux, we refer to those as "`matrix variables`" based on an @@ -1820,7 +1818,7 @@ To get all matrix variables, use a `MultiValueMap`, as the following example sho [[webflux-ann-requestparam]] ==== `@RequestParam` -[.small]#<># +[.small]#<># You can use the `@RequestParam` annotation to bind query parameters to a method argument in a controller. The following code snippet shows the usage: @@ -1853,7 +1851,7 @@ TIP: The Servlet API "`request parameter`" concept conflates query parameters, f data, and multiparts into one. However, in WebFlux, each is accessed individually through `ServerWebExchange`. While `@RequestParam` binds to query parameters only, you can use data binding to apply query parameters, form data, and multiparts to a -<>. +<>. Method parameters that use the `@RequestParam` annotation are required by default, but you can specify that a method parameter is optional by setting the required flag of a `@RequestParam` @@ -1875,7 +1873,7 @@ with `@RequestParam`. [[webflux-ann-requestheader]] ==== `@RequestHeader` -[.small]#<># +[.small]#<># You can use the `@RequestHeader` annotation to bind a request header to a method argument in a controller. @@ -1927,7 +1925,7 @@ example, a method parameter annotated with `@RequestHeader("Accept")` may be of [[webflux-ann-cookievalue]] ==== `@CookieValue` -[.small]#<># +[.small]#<># You can use the `@CookieValue` annotation to bind the value of an HTTP cookie to a method argument in a controller. @@ -1962,7 +1960,7 @@ Type conversion is applied automatically if the target method parameter type is [[webflux-ann-modelattrib-method-args]] ==== `@ModelAttribute` -[.small]#<># +[.small]#<># You can use the `@ModelAttribute` annotation on a method argument to access an attribute from the model or have it instantiated if not present. The model attribute is also overlain with @@ -2017,7 +2015,7 @@ immediately next to the `@ModelAttribute`, as the following example shows: You can automatically apply validation after data binding by adding the `javax.validation.Valid` annotation or Spring's `@Validated` annotation (see also -<> and +<> and <>). The following example uses the `@Valid` annotation: ==== @@ -2069,7 +2067,7 @@ with `@ModelAttribute`. [[webflux-ann-sessionattributes]] ==== `@SessionAttributes` -[.small]#<># +[.small]#<># `@SessionAttributes` is used to store model attributes in the `WebSession` between requests. It is a type-level annotation that declares session attributes used by a @@ -2125,7 +2123,7 @@ as the following example shows: [[webflux-ann-sessionattribute]] ==== `@SessionAttribute` -[.small]#<># +[.small]#<># If you need access to pre-existing session attributes that are managed globally (that is, outside the controller -- for example, by a filter) and may or may not be present, @@ -2153,7 +2151,7 @@ workflow, consider using `SessionAttributes`, as described in [[webflux-ann-requestattrib]] ==== `@RequestAttribute` -[.small]#<># +[.small]#<># Similarly to `@SessionAttribute`, you can use the `@RequestAttribute` annotation to access pre-existing request attributes created earlier (for example, by a `WebFilter`), @@ -2174,11 +2172,11 @@ as the following example shows: [[webflux-multipart-forms]] ==== Multipart Content -[.small]#<># +[.small]#<># As explained in <>, `ServerWebExchange` provides access to multipart content. The best way to handle a file upload form (for example, from a browser) in a controller -is through data binding to a <>, +is through data binding to a <>, as the following example shows: ==== @@ -2317,7 +2315,7 @@ To access multipart data sequentially, in streaming fashion, you can use `@Reque [[webflux-ann-requestbody]] ==== `@RequestBody` -[.small]#<># +[.small]#<># You can use the `@RequestBody` annotation to have the request body read and deserialized into an `Object` through an <>. @@ -2373,7 +2371,7 @@ example uses a `BindingResult` argument`: [[webflux-ann-httpentity]] ==== `HttpEntity` -[.small]#<># +[.small]#<># `HttpEntity` is more or less identical to using <> but is based on a container object that exposes request headers and the body. The following example uses an @@ -2393,10 +2391,11 @@ container object that exposes request headers and the body. The following exampl [[webflux-ann-responsebody]] ==== `@ResponseBody` -[.small]#<># +[.small]#<># -You can use the `@ResponseBody` annotation on a method to have the return serialized to the -response body through an <>. The following example shows how to do so: +You can use the `@ResponseBody` annotation on a method to have the return serialized +to the response body through an <>. The following +example shows how to do so: ==== [source,java,indent=0] @@ -2428,7 +2427,7 @@ configure or customize message writing. [[webflux-ann-responseentity]] ==== `ResponseEntity` -[.small]#<># +[.small]#<># `ResponseEntity` is like <> but with status and headers. For example: @@ -2445,7 +2444,7 @@ configure or customize message writing. ---- ==== -WebFlux supports using a single value <> to +WebFlux supports using a single value <> to produce the `ResponseEntity` asynchronously, and/or single and multi-value reactive types for the body. @@ -2457,7 +2456,7 @@ Spring offers support for the Jackson JSON library. [[webflux-ann-jsonview]] ===== JSON Views -[.small]#<># +[.small]#<># Spring WebFlux provides built-in support for http://wiki.fasterxml.com/JacksonJsonViews[Jackson's Serialization Views], @@ -2515,11 +2514,11 @@ controller method. Use a composite interface if you need to activate multiple vi [[webflux-ann-modelattrib-methods]] === `Model` -[.small]#<># +[.small]#<># You can use the `@ModelAttribute` annotation: -* On a <> in `@RequestMapping` methods +* On a <> in `@RequestMapping` methods to create or access an Object from the model and to bind it to the request through a `WebDataBinder`. * As a method-level annotation in `@Controller` or `@ControllerAdvice` classes, helping @@ -2618,7 +2617,7 @@ as the following example shows: [[webflux-ann-initbinder]] === `DataBinder` -[.small]#<># +[.small]#<># `@Controller` or `@ControllerAdvice` classes can have `@InitBinder` methods, to initialize instances of `WebDataBinder`. Those, in turn, are used to: @@ -2630,7 +2629,7 @@ headers, cookies, and others) to the target type of controller method arguments. `@InitBinder` methods can register controller-specific `java.bean.PropertyEditor` or Spring `Converter` and `Formatter` components. In addition, you can use the -<> to register `Converter` and +<> to register `Converter` and `Formatter` types in a globally shared `FormattingConversionService`. `@InitBinder` methods support many of the same arguments that `@RequestMapping` methods @@ -2684,9 +2683,9 @@ controller-specific `Formatter` instances, as the following example shows: [[webflux-ann-controller-exceptions]] === Managing Exceptions -[.small]#<># +[.small]#<># -`@Controller` and <> classes can have +`@Controller` and <> classes can have `@ExceptionHandler` methods to handle exceptions from controller methods. The following example includes such a handler method: @@ -2709,14 +2708,15 @@ example includes such a handler method: ==== The exception can match against a top-level exception being propagated (that is, a direct -`IOException` being thrown) or against the immediate cause within a top-level wrapper exception -(for example, an `IOException` wrapped inside an `IllegalStateException`). +`IOException` being thrown) or against the immediate cause within a top-level wrapper +exception (for example, an `IOException` wrapped inside an `IllegalStateException`). For matching exception types, preferably declare the target exception as a method argument, -as shown in the preceding example. Alternatively, the annotation declaration can narrow the exception types to -match. We generally recommend being as specific as possible in the argument signature and to -declare your primary root exception mappings on a `@ControllerAdvice` prioritized with a -corresponding order. See <> for details. +as shown in the preceding example. Alternatively, the annotation declaration can narrow the +exception types to match. We generally recommend being as specific as possible in the +argument signature and to declare your primary root exception mappings on a +`@ControllerAdvice` prioritized with a corresponding order. +See <> for details. NOTE: An `@ExceptionHandler` method in WebFlux supports the same method arguments and return values as a `@RequestMapping` method, with the exception of request body- @@ -2729,7 +2729,7 @@ for more detail. [[webflux-ann-rest-exceptions]] ==== REST API exceptions -[.small]#<># +[.small]#<># A common requirement for REST services is to include error details in the body of the response. The Spring Framework does not automatically do so, because the representation @@ -2747,7 +2747,7 @@ an HTTP status code. [[webflux-ann-controller-advice]] === Controller Advice -[.small]#<># +[.small]#<># Typically, the `@ExceptionHandler`, `@InitBinder`, and `@ModelAttribute` methods apply within the `@Controller` class (or class hierarchy) in which they are declared. If you want such @@ -2755,7 +2755,7 @@ methods to apply more globally (across controllers), you can declare them in a c marked with `@ControllerAdvice` or `@RestControllerAdvice`. `@ControllerAdvice` is marked with `@Component`, which means that such classes can be registered -as Spring beans through <>. +as Spring beans through <>. `@RestControllerAdvice` is also a meta-annotation marked with both `@ControllerAdvice` and `@ResponseBody`, which essentially means `@ExceptionHandler` methods are rendered to the response body through message conversion (versus view resolution or template rendering). @@ -2800,7 +2800,7 @@ include::webflux-functional.adoc[leveloffset=+1] [[webflux-uri-building]] == URI Links -[.small]#<># +[.small]#<># This section describes various options available in the Spring Framework to prepare URIs. @@ -2813,7 +2813,7 @@ include::webflux-cors.adoc[leveloffset=+1] [[webflux-web-security]] == Web Security -[.small]#<># +[.small]#<># The http://projects.spring.io/spring-security/[Spring Security] project provides support for protecting web applications from malicious exploits. See the Spring Security @@ -2831,7 +2831,7 @@ include::webflux-view.adoc[leveloffset=+1] [[webflux-caching]] == HTTP Caching -[.small]#<># +[.small]#<># HTTP caching can significantly improve the performance of a web application. HTTP caching revolves around the `Cache-Control` response header and subsequent conditional request @@ -2847,7 +2847,7 @@ This section describes the HTTP caching related options available in Spring WebF [[webflux-caching-cachecontrol]] === `CacheControl` -[.small]#<># +[.small]#<># {api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for configuring settings related to the `Cache-Control` header and is accepted as an argument @@ -2881,7 +2881,7 @@ use case-oriented approach that focuses on the common scenarios, as the followin [[webflux-caching-etag-lastmodified]] === Controllers -[.small]#<># +[.small]#<># Controllers can add explicit support for HTTP caching. We recommend doing so, since the `lastModified` or `ETag` value for a resource needs to be calculated before it can be compared @@ -2946,7 +2946,7 @@ to 409 (PRECONDITION_FAILED) to prevent concurrent modification. [[webflux-caching-static-resources]] === Static Resources -[.small]#<># +[.small]#<># You should serve static resources with a `Cache-Control` and conditional response headers for optimal performance. See the section on configuring <>. @@ -2956,13 +2956,14 @@ for optimal performance. See the section on configuring <># +[.small]#<># -The WebFlux Java configuration declares the components that are required to process requests with annotated -controllers or functional endpoints, and it offers an API to customize the configuration. -That means you do not need to understand the underlying beans created by the Java configuration. -However, if you want to understand them, you can see them in `WebFluxConfigurationSupport` or read more -about what they are in <>. +The WebFlux Java configuration declares the components that are required to process +requests with annotated controllers or functional endpoints, and it offers an API to +customize the configuration. That means you do not need to understand the underlying +beans created by the Java configuration. However, if you want to understand them, +you can see them in `WebFluxConfigurationSupport` or read more about what they are +in <>. For more advanced customizations, not available in the configuration API, you can gain full control over the configuration through the @@ -2972,7 +2973,7 @@ gain full control over the configuration through the [[webflux-config-enable]] === Enabling WebFlux Config -[.small]#<># +[.small]#<># You can use the `@EnableWebFlux` annotation in your Java config, as the following example shows: @@ -2988,14 +2989,14 @@ You can use the `@EnableWebFlux` annotation in your Java config, as the followin ==== The preceding example registers a number of Spring WebFlux -<> and adapts to dependencies +<> and adapts to dependencies available on the classpath -- for JSON, XML, and others. [[webflux-config-customize]] === WebFlux config API -[.small]#<># +[.small]#<># In your Java configuration, you can implement the `WebFluxConfigurer` interface, as the following example shows: @@ -3018,7 +3019,7 @@ as the following example shows: [[webflux-config-conversion]] === Conversion, formatting -[.small]#<># +[.small]#<># By default, formatters for `Number` and `Date` types are installed, including support for the `@NumberFormat` and `@DateTimeFormat` annotations. Full support for the Joda-Time @@ -3043,19 +3044,20 @@ The following example shows how to register custom formatters and converters: ---- ==== -NOTE: See <> -and the `FormattingConversionServiceFactoryBean` for more information on when to use `FormatterRegistrar` implementations. +NOTE: See <> +and the `FormattingConversionServiceFactoryBean` for more information on when to +use `FormatterRegistrar` implementations. [[webflux-config-validation]] === Validation -[.small]#<># +[.small]#<># -By default, if <> is present -on the classpath (for example, the Hibernate Validator), the `LocalValidatorFactoryBean` is registered -as a global <> for use with `@Valid` and `Validated` on -`@Controller` method arguments. +By default, if <> is present +on the classpath (for example, the Hibernate Validator), the `LocalValidatorFactoryBean` +is registered as a global <> for use with `@Valid` and +`Validated` on `@Controller` method arguments. In your Java configuration, you can customize the global `Validator` instance, as the following example shows: @@ -3103,11 +3105,11 @@ mark it with `@Primary` in order to avoid conflict with the one declared in the [[webflux-config-content-negotiation]] === Content Type Resolvers -[.small]#<># +[.small]#<># You can configure how Spring WebFlux determines the requested media types for -`@Controller` instances from the request. By default, only the `Accept` header is checked, but you -can also enable a query parameter-based strategy. +`@Controller` instances from the request. By default, only the `Accept` header is checked, +but you can also enable a query parameter-based strategy. The following example shows how to customize the requested content type resolution: @@ -3131,7 +3133,7 @@ The following example shows how to customize the requested content type resoluti [[webflux-config-message-codecs]] === HTTP message codecs -[.small]#<># +[.small]#<># The following example shows how to customize how the request and response body are read and written: @@ -3172,7 +3174,7 @@ It also automatically registers the following well-known modules if they are det [[webflux-config-view-resolvers]] === View Resolvers -[.small]#<># +[.small]#<># The following example shows how to configure view resolution: @@ -3275,7 +3277,7 @@ See <> for more on the view technologies that are integrated with [[webflux-config-static-resources]] === Static Resources -[.small]#<># +[.small]#<># This option provides a convenient way to serve static resources from a list of {api-spring-framework}/core/io/Resource.html[`Resource`]-based locations. @@ -3363,7 +3365,7 @@ match to incoming URLs without versions (for example, `/jquery/jquery.min.js` to [[webflux-config-path-matching]] === Path Matching -[.small]#<># +[.small]#<># You can customize options related to path matching. For details on the individual options, see the {api-spring-framework}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc. @@ -3399,7 +3401,7 @@ whether to decode the request path nor whether to remove semicolon content for path matching purposes. Spring WebFlux also does not support suffix pattern matching, unlike in Spring MVC, where we -are also <> moving away from +are also <> moving away from reliance on it. ==== @@ -3407,7 +3409,7 @@ reliance on it. [[webflux-config-advanced-java]] === Advanced Configuration Mode -[.small]#<># +[.small]#<># `@EnableWebFlux` imports `DelegatingWebFluxConfiguration` that: @@ -3441,7 +3443,7 @@ the classpath. [[webflux-http2]] == HTTP/2 -[.small]#<># +[.small]#<># Servlet 4 containers are required to support HTTP/2, and Spring Framework 5 is compatible with Servlet API 4. From a programming model perspective, there is nothing specific that diff --git a/src/docs/asciidoc/web/webmvc-client.adoc b/src/docs/asciidoc/web/webmvc-client.adoc index 69bfa6ba958..b1184ee030f 100644 --- a/src/docs/asciidoc/web/webmvc-client.adoc +++ b/src/docs/asciidoc/web/webmvc-client.adoc @@ -15,12 +15,12 @@ libraries. NOTE: As of 5.0, the non-blocking, reactive `WebClient` offers a modern alternative to the `RestTemplate`, with efficient support for both -<>, as well as +<>, as well as streaming scenarios. The `RestTemplate` will be deprecated in a future version and will not have major new features added going forward. -See <> for details. +See <> for details. @@ -41,4 +41,4 @@ In contrast to `RestTemplate`, `WebClient` supports the following: * Synchronous and asynchronous interactions. * Streaming up to or streaming down from a server. -See <> for more details. +See <> for more details. diff --git a/src/docs/asciidoc/web/webmvc-cors.adoc b/src/docs/asciidoc/web/webmvc-cors.adoc index 144edaa56c2..4ceca052564 100644 --- a/src/docs/asciidoc/web/webmvc-cors.adoc +++ b/src/docs/asciidoc/web/webmvc-cors.adoc @@ -1,6 +1,6 @@ [[mvc-cors]] = CORS -[.small]#<># +[.small]#<># Spring MVC lets you handle CORS (Cross-Origin Resource Sharing). This section describes how to do so. @@ -10,7 +10,7 @@ describes how to do so. [[mvc-cors-intro]] == Introduction -[.small]#<># +[.small]#<># For security reasons, browsers prohibit AJAX calls to resources outside the current origin. For example, you could have your bank account in one tab and evil.com in another. Scripts @@ -27,7 +27,7 @@ powerful workarounds based on IFRAME or JSONP. [[mvc-cors-processing]] == Processing -[.small]#<># +[.small]#<># The CORS specification distinguishes between preflight, simple, and actual requests. To learn how CORS works, you can read @@ -77,7 +77,7 @@ To learn more from the source or make advanced customizations, check the code be [[mvc-cors-controller]] == `@CrossOrigin` -[.small]#<># +[.small]#<># The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`] annotation enables cross-origin requests on annotated controller methods, @@ -173,7 +173,7 @@ public class AccountController { [[mvc-cors-global]] == Global Configuration -[.small]#<># +[.small]#<># In addition to fine-grained, controller method level configuration, you probably want to define some global CORS configuration, too. You can set URL-based `CorsConfiguration` @@ -197,7 +197,7 @@ should only be used where appropriate. [[mvc-cors-global-java]] === Java Configuration -[.small]#<># +[.small]#<># To enable CORS in the MVC Java config, you can use the `CorsRegistry` callback, as the following example shows: @@ -259,13 +259,13 @@ as the following example shows: [[mvc-cors-filter]] == CORS Filter -[.small]#<># +[.small]#<># You can apply CORS support through the built-in {api-spring-framework}/web/filter/CorsFilter.html[`CorsFilter`]. -NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring -Security has +NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that +Spring Security has https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#cors[built-in support] for CORS. diff --git a/src/docs/asciidoc/web/webmvc-test.adoc b/src/docs/asciidoc/web/webmvc-test.adoc index 87a167f2314..307fe10a6bf 100644 --- a/src/docs/asciidoc/web/webmvc-test.adoc +++ b/src/docs/asciidoc/web/webmvc-test.adoc @@ -1,26 +1,26 @@ [[testing]] = Testing -[.small]#<># +[.small]#<># This section summarizes the options available in `spring-test` for Spring MVC applications. -* Servlet API Mocks: Mock implementations of Servlet API contracts for unit testing controllers, filters, and -other web components. See <> mock objects -for more details. +* Servlet API Mocks: Mock implementations of Servlet API contracts for unit testing controllers, +filters, and other web components. See <> +mock objects for more details. -* TestContext Framework: Support for loading Spring configuration in JUnit and TestNG tests, including efficient -caching of the loaded configuration across test methods and support for loading a -`WebApplicationContext` with a `MockServletContext`. +* TestContext Framework: Support for loading Spring configuration in JUnit and TestNG tests, +including efficient caching of the loaded configuration across test methods and support for +loading a `WebApplicationContext` with a `MockServletContext`. See <> for more details. -* Spring MVC Test: A framework, also known as `MockMvc`, for testing annotated controllers through the -`DispatcherServlet` (that is, supporting annotations), complete with the Spring MVC -infrastructure but without an HTTP server. See -<> for more details. +* Spring MVC Test: A framework, also known as `MockMvc`, for testing annotated controllers +through the `DispatcherServlet` (that is, supporting annotations), complete with the +Spring MVC infrastructure but without an HTTP server. +See <> for more details. -* Client-side REST: `spring-test` provides a `MockRestServiceServer` that you can use as a mock server for -testing client-side code that internally uses the `RestTemplate`. -See <> for more details. +* Client-side REST: `spring-test` provides a `MockRestServiceServer` that you can use as +a mock server for testing client-side code that internally uses the `RestTemplate`. +See <> for more details. * `WebTestClient`: Built for testing WebFlux applications, but it can also be used for end-to-end integration testing, to any server, over an HTTP connection. It is a diff --git a/src/docs/asciidoc/web/webmvc-view.adoc b/src/docs/asciidoc/web/webmvc-view.adoc index 62194d7aeeb..eeea6b262f7 100644 --- a/src/docs/asciidoc/web/webmvc-view.adoc +++ b/src/docs/asciidoc/web/webmvc-view.adoc @@ -1,18 +1,18 @@ [[mvc-view]] = View Technologies -[.small]#<># +[.small]#<># -The use of view technologies in Spring MVC is pluggable, whether you decide to -use Thymeleaf, Groovy Markup Templates, JSPs, or other technologies, is primarily a matter of a -configuration change. This chapter covers view technologies integrated with Spring MVC. -We assume you are already familiar with <>. +The use of view technologies in Spring MVC is pluggable, whether you decide to use +Thymeleaf, Groovy Markup Templates, JSPs, or other technologies, is primarily a matter +of a configuration change. This chapter covers view technologies integrated with +Spring MVC. We assume you are already familiar with <>. [[mvc-view-thymeleaf]] == Thymeleaf -[.small]#<># +[.small]#<># Thymeleaf is a modern server-side Java template engine that emphasizes natural HTML templates that can be previewed in a browser by double-clicking, which is very helpful @@ -32,7 +32,7 @@ See http://www.thymeleaf.org/documentation.html[Thymeleaf+Spring] for more detai [[mvc-view-freemarker]] == FreeMarker -[.small]#<># +[.small]#<># http://www.freemarker.org[Apache FreeMarker] is a template engine for generating any kind of text output from HTML to email and others. The Spring Framework has a built-in @@ -42,7 +42,7 @@ integration for using Spring MVC with FreeMarker templates. [[mvc-view-freemarker-contextconfig]] === View Configuration -[.small]#<># +[.small]#<># The following example shows how to configure FreeMarker as a view technology: @@ -111,7 +111,7 @@ of `welcome`, the resolver looks for the `/WEB-INF/freemarker/welcome.ftl` templ [[mvc-views-freemarker]] === FreeMarker Configuration -[.small]#<># +[.small]#<># You can pass FreeMarker 'Settings' and 'SharedVariables' directly to the FreeMarker `Configuration` object (which is managed by Spring) by setting the appropriate bean properties on @@ -568,7 +568,7 @@ syntax. The following example shows a sample template for an HTML page: [[mvc-view-script]] == Script Views -[.small]#<># +[.small]#<># The Spring Framework has a built-in integration for using Spring MVC with any templating library that can run on top of the @@ -594,7 +594,7 @@ TIP: The basic rule for integrating any other script engine is that it must impl [[mvc-view-script-dependencies]] === Requirements -[.small]#<># +[.small]#<># You need to have the script engine on your classpath, the details of which vary by script engine: @@ -614,7 +614,7 @@ through http://www.webjars.org/[WebJars]. [[mvc-view-script-integrate]] === Script Templates -[.small]#<># +[.small]#<># You can declare a `ScriptTemplateConfigurer` bean to specify the script engine to use, the script files to load, what function to call to render templates, and so on. @@ -1192,13 +1192,13 @@ but with different values, as the following example shows: This tag renders multiple HTML `input` elements with the `type` set to `radio`. -As with the <>, you might want to pass in the available options as -a runtime variable. For this usage, you can use the `radiobuttons` tag. You pass in an -`Array`, a `List`, or a `Map` that contains the available options in the `items` property. -If you use a `Map`, the map entry key is used as the value and the map -entry's value are used as the label to be displayed. You can also use a custom -object where you can provide the property names for the value by using `itemValue` and the -label by using `itemLabel`, as the following example shows: +As with the <>, you might want to +pass in the available options as a runtime variable. For this usage, you can use the +`radiobuttons` tag. You pass in an `Array`, a `List`, or a `Map` that contains the +available options in the `items` property. If you use a `Map`, the map entry key is +used as the value and the map entry's value are used as the label to be displayed. +You can also use a custom object where you can provide the property names for the value +by using `itemValue` and the label by using `itemLabel`, as the following example shows: ==== [source,xml,indent=0] @@ -2013,7 +2013,7 @@ an external definition (by name) or as a `View` instance from the handler method [[mvc-view-jackson]] == Jackson -[.small]#<># +[.small]#<># Spring offers support for the Jackson JSON library. @@ -2021,7 +2021,7 @@ Spring offers support for the Jackson JSON library. [[mvc-view-json-mapping]] === Jackson-based JSON MVC Views -[.small]#<># +[.small]#<># The `MappingJackson2JsonView` uses the Jackson library's `ObjectMapper` to render the response content as JSON. By default, the entire contents of the model map (with the exception of @@ -2040,7 +2040,7 @@ serializers and deserializers for specific types. [[mvc-view-xml-mapping]] === Jackson-based XML Views -[.small]#<># +[.small]#<># `MappingJackson2XmlView` uses the https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper` diff --git a/src/docs/asciidoc/web/webmvc.adoc b/src/docs/asciidoc/web/webmvc.adoc index 7d9337cc406..bb67800b463 100644 --- a/src/docs/asciidoc/web/webmvc.adoc +++ b/src/docs/asciidoc/web/webmvc.adoc @@ -11,7 +11,7 @@ but it is more commonly known as "`Spring MVC`". Parallel to Spring Web MVC, Spring Framework 5.0 introduced a reactive-stack web framework whose name, "`Spring WebFlux,`" is also based on its source module (https://github.com/spring-projects/spring-framework/tree/master/spring-webflux[`spring-webflux`]). -This section covers Spring Web MVC. The <> +This section covers Spring Web MVC. The <> covers Spring WebFlux. For baseline information and compatibility with Servlet container and Java EE version @@ -23,7 +23,7 @@ https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versio [[mvc-servlet]] == DispatcherServlet -[.small]#<># +[.small]#<># Spring MVC, as many other web frameworks, is designed around the front controller pattern where a central `Servlet`, the `DispatcherServlet`, provides a shared algorithm @@ -34,7 +34,7 @@ The `DispatcherServlet`, as any `Servlet`, needs to be declared and mapped accor to the Servlet specification by using Java configuration or in `web.xml`. In turn, the `DispatcherServlet` uses Spring configuration to discover the delegate components it needs for request mapping, view resolution, exception -handling, <>. +handling, <>. The following example of the Java configuration registers and initializes the `DispatcherServlet`, which is auto-detected by the Servlet container @@ -209,7 +209,7 @@ TIP: If an application context hierarchy is not required, applications may confi [[mvc-servlet-special-bean-types]] === Special Bean Types -[.small]#<># +[.small]#<># The `DispatcherServlet` delegates to special beans to process requests and render the appropriate responses. By "`special beans`" we mean Spring-managed `Object` instances that @@ -239,27 +239,27 @@ The following table lists the special beans detected by the `DispatcherServlet`: requires resolving annotations. The main purpose of a `HandlerAdapter` is to shield the `DispatcherServlet` from such details. -| <> +| <> | Strategy to resolve exceptions, possibly mapping them to handlers, to HTML error views, or other targets. See <>. -| <> +| <> | Resolve logical `String`-based view names returned from a handler to an actual `View` with which to render to the response. See <> and <>. -| <>, <> +| <>, <> | Resolve the `Locale` a client is using and possibly their time zone, in order to be able to offer internationalized views. See <>. -| <> +| <> | Resolve themes your web application can use -- for example, to offer personalized layouts. See <>. -| <> +| <> | Abstraction for parsing a multi-part request (for example, browser form file upload) with the help of some multipart parsing library. See <>. -| <> +| <> | Store and retrieve the "`input`" and the "`output`" `FlashMap` that can be used to pass attributes from one request to another, usually across a redirect. See <>. @@ -269,7 +269,7 @@ The following table lists the special beans detected by the `DispatcherServlet`: [[mvc-servlet-config]] === Web MVC Config -[.small]#<># +[.small]#<># Applications can declare the infrastructure beans listed in <> that are required to process requests. The `DispatcherServlet` checks the @@ -412,7 +412,7 @@ override the `createDispatcherServlet` method. [[mvc-servlet-sequence]] === Processing -[.small]#<># +[.small]#<># The `DispatcherServlet` processes requests as follows: @@ -522,7 +522,7 @@ declare it as an <> bean or configure it directly on [[mvc-exceptionhandlers]] === Exceptions -[.small]#<># +[.small]#<># If an exception occurs during request mapping or is thrown from a request handler (such as a `@Controller`), the `DispatcherServlet` delegates to a chain of `HandlerExceptionResolver` @@ -550,7 +550,7 @@ The following table lists the available `HandlerExceptionResolver` implementatio | `ExceptionHandlerExceptionResolver` | Resolves exceptions by invoking an `@ExceptionHandler` method in a `@Controller` or a - `@ControllerAdvice` class. See <>. + `@ControllerAdvice` class. See <>. |=== @@ -623,7 +623,7 @@ however, use both a `WebApplicationInitializer` and a minimal `web.xml`. [[mvc-viewresolver]] === View Resolution -[.small]#<># +[.small]#<># Spring MVC defines the `ViewResolver` and `View` interfaces that let you render models in a browser without tying you to a specific view technology. `ViewResolver` @@ -681,7 +681,7 @@ The following table provides more details on the `ViewResolver` hierarchy: [[mvc-viewresolver-handling]] ==== Handling -[.small]#<># +[.small]#<># You can chain view resolvers by declaring more than one resolver bean and, if necessary, by setting the `order` property to specify ordering. Remember, the higher the order property, @@ -696,13 +696,13 @@ to be last in the overall order of view resolvers. Configuring view resolution is as simple as adding `ViewResolver` beans to your Spring configuration. The <> provides a dedicated configuration API for <> and for adding logic-less -<> which are useful for HTML template +<> which are useful for HTML template rendering without controller logic. [[mvc-redirecting-redirect-prefix]] ==== Redirecting -[.small]#<># +[.small]#<># The special `redirect:` prefix in a view name lets you perform a redirect. The `UrlBasedViewResolver` (and its subclasses) recognize this as an instruction that a @@ -732,7 +732,7 @@ Servlet/JSP engine. Note that you may also chain multiple view resolvers, instea [[mvc-multiple-representations]] ==== Content Negotiation -[.small]#<># +[.small]#<># {api-spring-framework}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`] does not resolve views itself but rather delegates @@ -973,7 +973,7 @@ background image with Dutch text on it. [[mvc-themeresolver-resolving]] ==== Resolving Themes -After you define themes, as described in the <>, +After you define themes, as described in the <>, you decide which theme to use. The `DispatcherServlet` looks for a bean named `themeResolver` to find out which `ThemeResolver` implementation to use. A theme resolver works in much the same way as a `LocaleResolver`. It detects the theme to use for a particular request and can also @@ -1003,7 +1003,7 @@ request with a simple request parameter. [[mvc-multipart]] === Multipart Resolver -[.small]#<># +[.small]#<># `MultipartResolver` from the `org.springframework.web.multipart` package is a strategy for parsing multipart requests including file uploads. There is one implementation @@ -1063,7 +1063,7 @@ Once the Servlet 3.0 configuration is in place, you can add a bean of type [[mvc-logging]] === Logging -[.small]#<># +[.small]#<># DEBUG-level logging in Spring MVC is designed to be compact, minimal, and human-friendly. It focuses on high-value bits of information that are useful over and @@ -1079,7 +1079,7 @@ not meet the stated goals, please let us know. [[mvc-logging-sensitive-data]] ==== Sensitive Data -[.small]#<># +[.small]#<># DEBUG and TRACE logging may log sensitive information. This is why request parameters and headers are masked by default and their logging in full must be enabled explicitly @@ -1123,7 +1123,7 @@ public class MyInitializer [[filters]] == Filters -[.small]#<># +[.small]#<># The `spring-web` module provides some useful filters: @@ -1150,7 +1150,7 @@ available through the `ServletRequest.getParameter{asterisk}()` family of method [[filters-forwarded-headers]] === Forwarded Headers -[.small]#<># +[.small]#<># As a request goes through proxies (such as load balancers) the host, port, and scheme may change, and that makes it a challenge to create links that point to the correct @@ -1177,12 +1177,12 @@ from the outside. You can also configure the `ForwardedHeaderFilter` with The `ShallowEtagHeaderFilter` filter creates a "`shallow`" ETag by caching the content written to the response and computing an MD5 hash from it. The next time a client sends, -it does the same, but it also compares the computed value against the `If-None-Match` request -header and, if the two are equal, returns a 304 (NOT_MODIFIED). +it does the same, but it also compares the computed value against the `If-None-Match` +request header and, if the two are equal, returns a 304 (NOT_MODIFIED). This strategy saves network bandwidth but not CPU, as the full response must be computed -for each request. Other strategies at the controller level, described earlier, can avoid the -computation. See <>. +for each request. Other strategies at the controller level, described earlier, can avoid +the computation. See <>. This filter has a `writeWeakETag` parameter that configures the filter to write weak ETags similar to the following: `W/"02a2d595e6ed9a0b24f027f2b63b134d6"` (as defined in @@ -1192,7 +1192,7 @@ https://tools.ietf.org/html/rfc7232#section-2.3[RFC 7232 Section 2.3]). [[filters-cors]] === CORS -[.small]#<># +[.small]#<># Spring MVC provides fine-grained support for CORS configuration through annotations on controllers. However, when used with Spring Security, we advise relying on the built-in @@ -1205,7 +1205,7 @@ See the sections on <> and the <> for more details. [[mvc-controller]] == Annotated Controllers -[.small]#<># +[.small]#<># Spring MVC provides an annotation-based programming model where `@Controller` and `@RestController` components use annotations to express request mappings, request input, @@ -1239,7 +1239,7 @@ programming model described in this section. [[mvc-ann-controller]] === Declaration -[.small]#<># +[.small]#<># You can define controller beans by using a standard Spring bean definition in the Servlet's `WebApplicationContext`. The `@Controller` stereotype allows for auto-detection, @@ -1288,7 +1288,7 @@ The following example shows the XML configuration equivalent of the preceding ex ---- ==== -`@RestController` is a <> that is +`@RestController` is a <> that is itself meta-annotated with `@Controller` and `@ResponseBody` to indicate a controller whose every method inherits the type-level `@ResponseBody` annotation and, therefore, writes directly to the response body versus view resolution and rendering with an HTML template. @@ -1310,7 +1310,7 @@ change to ``. [[mvc-ann-requestmapping]] === Request Mapping -[.small]#<># +[.small]#<># You can use the `@RequestMapping` annotation to map requests to controllers methods. It has various attributes to match by URL, HTTP method, request parameters, headers, and media @@ -1325,10 +1325,10 @@ There are also HTTP method specific shortcut variants of `@RequestMapping`: * `@DeleteMapping` * `@PatchMapping` -The shortcuts are <> that are provided -because, arguably, most controller methods should be mapped to a specific HTTP method versus -using `@RequestMapping`, which, by default, matches to all HTTP methods. At the same, a -`@RequestMapping` is still needed at the class level to express shared mappings. +The shortcuts are <> that are provided because, +arguably, most controller methods should be mapped to a specific HTTP method versus +using `@RequestMapping`, which, by default, matches to all HTTP methods. At the same, +a `@RequestMapping` is still needed at the class level to express shared mappings. The following example has type and method level mappings: @@ -1357,7 +1357,7 @@ The following example has type and method level mappings: [[mvc-ann-requestmapping-uri-templates]] ==== URI patterns -[.small]#<># +[.small]#<># You can map requests by using the following global patterns and wildcards: @@ -1433,7 +1433,7 @@ NOTE: Spring MVC uses the `PathMatcher` contract and the `AntPathMatcher` implem [[mvc-ann-requestmapping-pattern-comparison]] ==== Pattern Comparison -[.small]#<># +[.small]#<># When multiple patterns match a URL, they must be compared to find the best match. This is done by using `AntPathMatcher.getPatternComparator(String path)`, which looks for patterns that are more @@ -1474,8 +1474,8 @@ and security (see next section for more details) also become more difficult. To completely disable the use of file extensions, you must set both of the following: -* `useSuffixPatternMatching(false)`, see <> -* `favorPathExtension(false)`, see <> +* `useSuffixPatternMatching(false)`, see <> +* `favorPathExtension(false)`, see <> URL-based content negotiation can still be useful (for example, when typing a URL in a browser). To enable that, we recommend a query parameter-based strategy to avoid most of @@ -1514,7 +1514,7 @@ recommendations related to RFD. [[mvc-ann-requestmapping-consumes]] ==== Consumable Media Types -[.small]#<># +[.small]#<># You can narrow the request mapping based on the `Content-Type` of the request, as the following example shows: @@ -1544,7 +1544,7 @@ TIP: `MediaType` provides constants for commonly used media types, such as [[mvc-ann-requestmapping-produces]] ==== Producible Media Types -[.small]#<># +[.small]#<># You can narrow the request mapping based on the `Accept` request header and the list of content types that a controller method produces, as the following example shows: @@ -1580,7 +1580,7 @@ TIP: `MediaType` provides constants for commonly used media types, such as [[mvc-ann-requestmapping-params-and-headers]] ==== Parameters, headers -[.small]#<># +[.small]#<># You can narrow request mappings based on request parameter conditions. You can test for the presence of a request parameter (`myParam`), for the absence of one (`!myParam`), or for a @@ -1613,13 +1613,13 @@ You can also use the same with request header conditions, as the following examp ==== TIP: You can match `Content-Type` and `Accept` with the headers condition, but it is better to use -<> and <> +<> and <> instead. [[mvc-ann-requestmapping-head-options]] ==== HTTP HEAD, OPTIONS -[.small]#<># +[.small]#<># `@GetMapping` (and `@RequestMapping(method=HttpMethod.GET)`) support HTTP HEAD transparently for request mapping. Controller methods do not need to change. @@ -1645,9 +1645,9 @@ is not necessary in the common case. [[mvc-ann-requestmapping-composed]] ==== Custom Annotations -[.small]#<># +[.small]#<># -Spring MVC supports the use of <> +Spring MVC supports the use of <> for request mapping. Those are annotations that are themselves meta-annotated with `@RequestMapping` and composed to redeclare a subset (or all) of the `@RequestMapping` attributes with a narrower, more specific purpose. @@ -1666,7 +1666,7 @@ you can check the custom attribute and return your own `RequestCondition`. [[mvc-ann-requestmapping-registration]] ==== Explicit Registrations -[.small]#<># +[.small]#<># You can programmatically register handler methods, which you can use for dynamic registrations or for advanced cases, such as different instances of the same handler @@ -1704,7 +1704,7 @@ public class MyConfig { [[mvc-ann-methods]] === Handler Methods -[.small]#<># +[.small]#<># `@RequestMapping` handler methods have a flexible signature and can choose from a range of supported controller method arguments and return values. @@ -1712,7 +1712,7 @@ supported controller method arguments and return values. [[mvc-ann-arguments]] ==== Method Arguments -[.small]#<># +[.small]#<># The next table describes the supported controller method arguments. Reactive types are not supported for any arguments. @@ -1847,7 +1847,7 @@ and others) and is equivalent to `required=false`. [[mvc-ann-return-types]] ==== Return Values -[.small]#<># +[.small]#<># The next table describes the supported controller method return values. Reactive types are supported for all return values. @@ -1877,7 +1877,8 @@ supported for all return values. | `View` | A `View` instance to use for rendering together with the implicit model -- determined through command objects and `@ModelAttribute` methods. The handler method can also - programmatically enrich the model by declaring a `Model` argument (see <>). + programmatically enrich the model by declaring a `Model` argument + (see <>). | `java.util.Map`, `org.springframework.ui.Model` | Attributes to be added to the implicit model, with the view name implicitly determined @@ -1904,8 +1905,7 @@ supported for all return values. | `DeferredResult` | Produce any of the preceding return values asynchronously from any thread -- for example, as a - result of some event or callback. See <> and - <>. + result of some event or callback. See <> and <>. | `Callable` | Produce any of the above return values asynchronously in a Spring MVC-managed thread. @@ -1948,22 +1948,22 @@ supported for all return values. [[mvc-ann-typeconversion]] ==== Type Conversion -[.small]#<># +[.small]#<># Some annotated controller method arguments that represent `String`-based request input (such as `@RequestParam`, `@RequestHeader`, `@PathVariable`, `@MatrixVariable`, and `@CookieValue`) can require type conversion if the argument is declared as something other than `String`. For such cases, type conversion is automatically applied based on the configured converters. -By default, simple types (`int`, `long`, `Date`, and others) are supported. You can customize type conversion -through a `WebDataBinder` (see <>) or by registering -`Formatters` with the `FormattingConversionService`. See -<>. +By default, simple types (`int`, `long`, `Date`, and others) are supported. You can customize +type conversion through a `WebDataBinder` (see <>) or by registering +`Formatters` with the `FormattingConversionService`. +See <>. [[mvc-ann-matrix-variables]] ==== Matrix Variables -[.small]#<># +[.small]#<># http://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in path segments. In Spring MVC, we refer to those as "`matrix variables`" based on an @@ -2060,7 +2060,7 @@ you need to set a `UrlPathHelper` with `removeSemicolonContent=false` through [[mvc-ann-requestparam]] ==== `@RequestParam` -[.small]#<># +[.small]#<># You can use the `@RequestParam` annotation to bind Servlet request parameters (that is, query parameters or form data) to a method argument in a controller. @@ -2114,7 +2114,7 @@ with `@RequestParam`. [[mvc-ann-requestheader]] ==== `@RequestHeader` -[.small]#<># +[.small]#<># You can use the `@RequestHeader` annotation to bind a request header to a method argument in a controller. @@ -2166,7 +2166,7 @@ example, a method parameter annotated with `@RequestHeader("Accept")` can be of [[mvc-ann-cookievalue]] ==== `@CookieValue` -[.small]#<># +[.small]#<># You can use the `@CookieValue` annotation to bind the value of an HTTP cookie to a method argument in a controller. @@ -2201,7 +2201,7 @@ if the target method parameter type is not [[mvc-ann-modelattrib-method-args]] ==== `@ModelAttribute` -[.small]#<># +[.small]#<># You can use the `@ModelAttribute` annotation on a method argument to access an attribute from the model or have it be instantiated if not present. The model attribute is also overlain with @@ -2301,7 +2301,7 @@ alternatively, set `@ModelAttribute(binding=false)`, as the following example sh You can automatically apply validation after data binding by adding the `javax.validation.Valid` annotation or Spring's `@Validated` annotation ( -<> and +<> and <>). The following example shows how to do so: ==== @@ -2328,7 +2328,7 @@ with `@ModelAttribute`. [[mvc-ann-sessionattributes]] ==== `@SessionAttributes` -[.small]#<># +[.small]#<># `@SessionAttributes` is used to store model attributes in the HTTP Servlet session between requests. It is a type-level annotation that declares the session attributes used by a @@ -2384,7 +2384,7 @@ storage, as the following example shows: [[mvc-ann-sessionattribute]] ==== `@SessionAttribute` -[.small]#<># +[.small]#<># If you need access to pre-existing session attributes that are managed globally (that is, outside the controller -- for example, by a filter) and may or may not be present, @@ -2414,7 +2414,7 @@ workflow, consider using `@SessionAttributes` as described in [[mvc-ann-requestattrib]] ==== `@RequestAttribute` -[.small]#<># +[.small]#<># Similar to `@SessionAttribute`, you can use the `@RequestAttribute` annotations to access pre-existing request attributes created earlier (for example, by a Servlet `Filter` @@ -2526,7 +2526,7 @@ Therefore, we recommend that you use flash attributes mainly for redirect scenar [[mvc-multipart-forms]] ==== Multipart -[.small]#<># +[.small]#<># After a `MultipartResolver` has been <>, the content of POST requests with `multipart/form-data` is parsed and accessible as regular request @@ -2566,7 +2566,7 @@ NOTE: With Servlet 3.0 multipart parsing, you may also declare `javax.servlet.ht instead of Spring's `MultipartFile`, as a method argument or collection value type. You can also use multipart content as part of data binding to a -<>. For example, the form field +<>. For example, the form field and file from the preceding example could be fields on a form object, as the following example shows: @@ -2627,7 +2627,7 @@ Content-Transfer-Encoding: 8bit You can access the "meta-data" part with `@RequestParam` as a `String` but you'll probably want it deserialized from JSON (similar to `@RequestBody`). Use the `@RequestPart` annotation to access a multipart after converting it with an -<>: +<>: [source,java,indent=0] [subs="verbatim,quotes"] @@ -2662,10 +2662,10 @@ public String handle(**@Valid** @RequestPart("meta-data") MetaData metadata, [[mvc-ann-requestbody]] ==== `@RequestBody` -[.small]#<># +[.small]#<># You can use the `@RequestBody` annotation to have the request body read and deserialized into an -`Object` through an <>. +`Object` through an <>. The following example uses a `@RequestBody` argument: ==== @@ -2703,7 +2703,7 @@ as the following example shows: [[mvc-ann-httpentity]] ==== HttpEntity -[.small]#<># +[.small]#<># `HttpEntity` is more or less identical to using <> but is based on a container object that exposes request headers and body. The following listing shows an example: @@ -2722,11 +2722,12 @@ container object that exposes request headers and body. The following listing sh [[mvc-ann-responsebody]] ==== `@ResponseBody` -[.small]#<># +[.small]#<># -You can use the `@ResponseBody` annotation on a method to have the return serialized to the -response body through an -<>. The following listing shows an example: +You can use the `@ResponseBody` annotation on a method to have the return serialized +to the response body through an +<>. +The following listing shows an example: ==== [source,java,indent=0] @@ -2756,7 +2757,7 @@ See <> for details. [[mvc-ann-responseentity]] ==== ResponseEntity -[.small]#<># +[.small]#<># `ResponseEntity` is like <> but with status and headers. For example: @@ -2773,7 +2774,7 @@ See <> for details. ---- ==== -Spring MVC supports using a single value <> +Spring MVC supports using a single value <> to produce the `ResponseEntity` asynchronously, and/or single and multi-value reactive types for the body. @@ -2785,7 +2786,7 @@ Spring offers support for the Jackson JSON library. [[mvc-ann-jsonview]] ===== JSON Views -[.small]#<># +[.small]#<># Spring MVC provides built-in support for http://wiki.fasterxml.com/JacksonJsonViews[Jackson's Serialization Views], @@ -2863,7 +2864,7 @@ to the model, as the following example shows: [[mvc-ann-modelattrib-methods]] === Model -[.small]#<># +[.small]#<># You can use the `@ModelAttribute` annotation: @@ -2939,7 +2940,7 @@ unless the return value is a `String` that would otherwise be interpreted as a v [[mvc-ann-initbinder]] === `DataBinder` -[.small]#<># +[.small]#<># `@Controller` or `@ControllerAdvice` classes can have `@InitBinder` methods that initialize instances of `WebDataBinder`, and those, in turn, can: @@ -3005,9 +3006,9 @@ controller-specific `Formatter` implementations, as the following example shows: [[mvc-ann-exceptionhandler]] === Exceptions -[.small]#<># +[.small]#<># -`@Controller` and <> classes can have +`@Controller` and <> classes can have `@ExceptionHandler` methods to handle exceptions from controller methods, as the following example shows: ==== @@ -3101,7 +3102,7 @@ exception is propagated through the remaining resolution chain, as though the given `@ExceptionHandler` method would not have matched in the first place. Support for `@ExceptionHandler` methods in Spring MVC is built on the `DispatcherServlet` -level, <> mechanism. +level, <> mechanism. [[mvc-ann-exceptionhandler-args]] @@ -3124,8 +3125,8 @@ level, <> mechanism. use of the Servlet API. | `javax.servlet.ServletRequest`, `javax.servlet.ServletResponse` -| Choose any specific request or response type (for example, `ServletRequest` or `HttpServletRequest` or - or Spring's `MultipartRequest` or `MultipartHttpServletRequest`). +| Choose any specific request or response type (for example, `ServletRequest` or + `HttpServletRequest` or or Spring's `MultipartRequest` or `MultipartHttpServletRequest`). | `javax.servlet.http.HttpSession` | Enforces the presence of a session. As a consequence, such an argument is never `null`. + @@ -3158,9 +3159,9 @@ level, <> mechanism. See <> and <>. | `@SessionAttribute` -| For access to any session attribute, in contrast to model attributes stored in the session - as a result of a class-level `@SessionAttributes` declaration. See - <> for more details. +| For access to any session attribute, in contrast to model attributes stored in the + session as a result of a class-level `@SessionAttributes` declaration. + See <> for more details. | `@RequestAttribute` | For access to request attributes. See <> for more details. @@ -3182,15 +3183,15 @@ level, <> mechanism. response. See <>. | `HttpEntity`, `ResponseEntity` -| The return value specifies that the full response (including the HTTP headers and the body) be converted - through `HttpMessageConverter` instances and written to the response. +| The return value specifies that the full response (including the HTTP headers and the body) + be converted through `HttpMessageConverter` instances and written to the response. See <>. | `String` -| A view name to be resolved with `ViewResolver` implementations and used together with the implicit - model -- determined through command objects and `@ModelAttribute` methods. The handler - method can also programmatically enrich the model by declaring a `Model` argument - (described earlier). +| A view name to be resolved with `ViewResolver` implementations and used together with the + implicit model -- determined through command objects and `@ModelAttribute` methods. + The handler method can also programmatically enrich the model by declaring a `Model` + argument (described earlier). | `View` | A `View` instance to use for rendering together with the implicit model -- determined @@ -3230,7 +3231,7 @@ level, <> mechanism. [[mvc-ann-rest-exceptions]] ==== REST API exceptions -[.small]#<># +[.small]#<># A common requirement for REST services is to include error details in the body of the response. The Spring Framework does not automatically do this because the representation @@ -3251,7 +3252,7 @@ necessary methods, and declare it as a Spring bean. [[mvc-ann-controller-advice]] === Controller Advice -[.small]#<># +[.small]#<># Typically `@ExceptionHandler`, `@InitBinder`, and `@ModelAttribute` methods apply within the `@Controller` class (or class hierarchy) in which they are declared. If you want such @@ -3259,7 +3260,7 @@ methods to apply more globally (across controllers), you can declare them in a c marked with `@ControllerAdvice` or `@RestControllerAdvice`. `@ControllerAdvice` is marked with `@Component`, which means such classes can be registered -as Spring beans through <>. +as Spring beans through <>. `@RestControllerAdvice` is also a meta-annotation marked with both `@ControllerAdvice` and `@ResponseBody`, which essentially means `@ExceptionHandler` methods are rendered to the response body through message conversion (versus view resolution or template rendering). @@ -3302,7 +3303,7 @@ javadoc for more details. [[mvc-uri-building]] == URI Links -[.small]#<># +[.small]#<># This section describes various options available in the Spring Framework to work with URI's. @@ -3360,7 +3361,7 @@ as the following example shows: NOTE: As of 5.1, `ServletUriComponentsBuilder` ignores information from the `Forwarded` and `X-Forwarded-*` headers, which specify the client-originated address. Consider using the -<> to extract and use or to discard +<> to extract and use or to discard such headers. @@ -3456,7 +3457,7 @@ following listing uses `withMethodCall`: NOTE: As of 5.1, `MvcUriComponentsBuilder` ignores information from the `Forwarded` and `X-Forwarded-*` headers, which specify the client-originated address. Consider using the -<> to extract and use or to discard +<> to extract and use or to discard such headers. @@ -3510,28 +3511,28 @@ capital letters of the class and the method name (for example, the `getThing` me [[mvc-ann-async]] == Asynchronous Requests -[.small]#<># +[.small]#<># Spring MVC has an extensive integration with Servlet 3.0 asynchronous request <>: -* <> and <> return values in -controller methods and provide basic support for a single asynchronous return value. +* <> and <> +return values in controller methods and provide basic support for a single asynchronous +return value. * Controllers can <> multiple values, including -<> and <>. +<> and <>. * Controllers can use reactive clients and return -<> for response handling. +<> for response handling. [[mvc-ann-async-deferredresult]] === `DeferredResult` -[.small]#<># +[.small]#<># -Once the asynchronous request processing feature is -<> in the Servlet container, controller methods can -wrap any supported controller method return value with `DeferredResult`, as the following -example shows: +Once the asynchronous request processing feature is <> +in the Servlet container, controller methods can wrap any supported controller method +return value with `DeferredResult`, as the following example shows: ==== [source,java,indent=0] @@ -3557,7 +3558,7 @@ example, in response to an external event (JMS message), a scheduled task, or ot [[mvc-ann-async-callable]] === `Callable` -[.small]#<># +[.small]#<># A controller can wrap any supported return value with `java.util.concurrent.Callable`, as the following example shows: @@ -3581,13 +3582,13 @@ as the following example shows: ==== The return value can then be obtained by running the the given task through the -<> `TaskExecutor`. +<> `TaskExecutor`. [[mvc-ann-async-processing]] === Processing -[.small]#<># +[.small]#<># Here is a very concise overview of Servlet asynchronous request processing: @@ -3696,7 +3697,7 @@ Spring WebFlux does support all that. [[mvc-ann-async-http-streaming]] === HTTP Streaming -[.small]#<># +[.small]#<># You can use `DeferredResult` and `Callable` for a single asynchronous return value. What if you want to produce multiple asynchronous values and have those written to the @@ -3708,7 +3709,7 @@ response? This section describes how to do so. You can use the `ResponseBodyEmitter` return value to produce a stream of objects, where each object is serialized with an -<> and written to the +<> and written to the response, as the following example shows: ==== @@ -3776,11 +3777,11 @@ stream from a controller, return `SseEmitter`, as the following example shows: While SSE is the main option for streaming into browsers, note that Internet Explorer does not support Server-Sent Events. Consider using Spring's -<> with -<> transports (including SSE) that target +<> with +<> transports (including SSE) that target a wide range of browsers. -See also <> for notes on exception handling. +See also <> for notes on exception handling. [[mvc-ann-async-output-stream]] @@ -3813,10 +3814,10 @@ customize the status and headers of the response. [[mvc-ann-async-reactive-types]] === Reactive Types -[.small]#<># +[.small]#<># Spring MVC supports use of reactive client libraries in a controller (also read -<> in the WebFlux section). +<> in the WebFlux section). This includes the `WebClient` from `spring-webflux` and others, such as Spring Data reactive data repositories. In such scenarios, it is convenient to be able to return reactive types from the controller method. @@ -3838,34 +3839,34 @@ TIP: Spring MVC supports Reactor and RxJava through the For streaming to the response, reactive back pressure is supported, but writes to the response are still blocking and are executed on a separate thread through the -<> `TaskExecutor`, to avoid +<> `TaskExecutor`, to avoid blocking the upstream source (such as a `Flux` returned from `WebClient`). By default, `SimpleAsyncTaskExecutor` is used for the blocking writes, but that is not suitable under load. If you plan to stream with a reactive type, you should use the -<> to configure a task executor. +<> to configure a task executor. [[mvc-ann-async-disconnects]] === Disconnects -[.small]#<># +[.small]#<># The Servlet API does not provide any notification when a remote client goes away. -Therefore, while streaming to the response, whether through <> or -<, it is important to send data periodically, -since the write fails if the client has disconnected. The send could take the form -of an empty (comment-only) SSE event or any other data that the other side would have to -to interpret as a heartbeat and ignore. +Therefore, while streaming to the response, whether through <> +or <, it is important to send data periodically, +since the write fails if the client has disconnected. The send could take the form of an +empty (comment-only) SSE event or any other data that the other side would have to interpret +as a heartbeat and ignore. Alternatively, consider using web messaging solutions (such as -<> or WebSocket with <>) +<> or WebSocket with <>) that have a built-in heartbeat mechanism. [[mvc-ann-async-configuration]] === Configuration -[.small]#<># +[.small]#<># The asynchronous request processing feature must be enabled at the Servlet container level. The MVC configuration also exposes several options for asynchronous requests. @@ -3906,8 +3907,8 @@ by default, it is a `SimpleAsyncTaskExecutor`. * `DeferredResultProcessingInterceptor` implementations and `CallableProcessingInterceptor` implementations. Note that you can also set the default timeout value on a `DeferredResult`, -a `ResponseBodyEmitter`, and an `SseEmitter`. For a `Callable`, you can use `WebAsyncTask` to provide -a timeout value. +a `ResponseBodyEmitter`, and an `SseEmitter`. For a `Callable`, you can use +`WebAsyncTask` to provide a timeout value. include::webmvc-cors.adoc[leveloffset=+1] @@ -3916,7 +3917,7 @@ include::webmvc-cors.adoc[leveloffset=+1] [[mvc-web-security]] == Web Security -[.small]#<># +[.small]#<># The http://projects.spring.io/spring-security/[Spring Security] project provides support for protecting web applications from malicious exploits. See the Spring Security @@ -3934,7 +3935,7 @@ http://hdiv.org/[HDIV] is another web security framework that integrates with Sp [[mvc-caching]] == HTTP Caching -[.small]#<># +[.small]#<># HTTP caching can significantly improve the performance of a web application. HTTP caching revolves around the `Cache-Control` response header and, subsequently, conditional request @@ -3950,7 +3951,7 @@ This section describes the HTTP caching-related options that are available in Sp [[mvc-caching-cachecontrol]] === `CacheControl` -[.small]#<># +[.small]#<># {api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for configuring settings related to the `Cache-Control` header and is accepted as an argument @@ -3994,7 +3995,7 @@ works as follows: [[mvc-caching-etag-lastmodified]] === Controllers -[.small]#<># +[.small]#<># Controllers can add explicit support for HTTP caching. We recommended doing so, since the `lastModified` or `ETag` value for a resource needs to be calculated before it can be compared @@ -4059,7 +4060,7 @@ to 409 (PRECONDITION_FAILED), to prevent concurrent modification. [[mvc-caching-static-resources]] === Static Resources -[.small]#<># +[.small]#<># You should serve static resources with a `Cache-Control` and conditional response headers for optimal performance. See the section on configuring <>. @@ -4079,23 +4080,23 @@ include::webmvc-view.adoc[leveloffset=+1] [[mvc-config]] == MVC Config -[.small]#<># +[.small]#<># -The MVC Java configuration and the MVC XML namespace provide default configuration suitable for most -applications and a configuration API to customize it. +The MVC Java configuration and the MVC XML namespace provide default configuration +suitable for most applications and a configuration API to customize it. -For more advanced customizations, which are not available in the configuration API, see -<> and <>. +For more advanced customizations, which are not available in the configuration API, +see <> and <>. -You do not need to understand the underlying beans created by the MVC Java configuration and -the MVC namespace. If you want to learn more, see <> +You do not need to understand the underlying beans created by the MVC Java configuration +and the MVC namespace. If you want to learn more, see <> and <>. [[mvc-config-enable]] === Enable MVC Configuration -[.small]#<># +[.small]#<># In Java configuration, you can use the `@EnableWebMvc` annotation to enable MVC configuration, as the following example shows: @@ -4135,14 +4136,14 @@ configuration, as the following example shows: ==== The preceding example registers a number of Spring MVC -<> and adapts to dependencies +<> and adapts to dependencies available on the classpath (for example, payload converters for JSON, XML, and others). [[mvc-config-customize]] === MVC Config API -[.small]#<># +[.small]#<># In Java configuration, you can implement the `WebMvcConfigurer` interface, as the following example shows: @@ -4169,7 +4170,7 @@ sub-elements are available. [[mvc-config-conversion]] === Type Conversion -[.small]#<># +[.small]#<># By default formatters, for `Number` and `Date` types are installed, including support for the `@NumberFormat` and `@DateTimeFormat` annotations. Full support for the Joda-Time @@ -4236,19 +4237,20 @@ The following example shows how to achieve the same configuration in XML: ---- ==== -NOTE: See <> -and the `FormattingConversionServiceFactoryBean` for more information on when to use FormatterRegistrar implementations. +NOTE: See <> +and the `FormattingConversionServiceFactoryBean` for more information on when to use +FormatterRegistrar implementations. [[mvc-config-validation]] === Validation -[.small]#<># +[.small]#<># -By default, if <> is present -on the classpath (for example, Hibernate Validator), the `LocalValidatorFactoryBean` is registered -as a global <> for use with `@Valid` and `Validated` on -controller method arguments. +By default, if <> is present +on the classpath (for example, Hibernate Validator), the `LocalValidatorFactoryBean` is +registered as a global <> for use with `@Valid` and +`Validated` on controller method arguments. In Java configuration, you can customize the global `Validator` instance, as the following example shows: @@ -4364,7 +4366,7 @@ The following example shows how to achieve the same configuration in XML: [[mvc-config-content-negotiation]] === Content Types -[.small]#<># +[.small]#<># You can configure how Spring MVC determines the requested media types from the request (for example, `Accept` header, URL path extension, query parameter, and others). @@ -4421,7 +4423,7 @@ The following example shows how to achieve the same configuration in XML: [[mvc-config-message-converters]] === Message Converters -[.small]#<># +[.small]#<># You can customize `HttpMessageConverter` in Java configuration by overriding {api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`] @@ -4550,7 +4552,7 @@ using the `` element: [[mvc-config-view-resolvers]] === View Resolvers -[.small]#<># +[.small]#<># The MVC configuration simplifies the registration of view resolvers. @@ -4648,7 +4650,7 @@ as the following example shows: [[mvc-config-static-resources]] === Static Resources -[.small]#<># +[.small]#<># This option provides a convenient way to serve static resources from a list of {api-spring-framework}/core/io/Resource.html[`Resource`]-based locations. @@ -4846,7 +4848,7 @@ The following example shows how to achieve the same configuration in XML: [[mvc-config-path-matching]] === Path Matching -[.small]#<># +[.small]#<># You can customize options related to path matching and treatment of the URL. For details on the individual options, see the @@ -4912,7 +4914,7 @@ The following example shows how to achieve the same configuration in XML: [[mvc-config-advanced-java]] === Advanced Java Config -[.small]#<># +[.small]#<># `@EnableWebMvc` imports `DelegatingWebMvcConfiguration`, which: @@ -4971,7 +4973,7 @@ by letting it be detected through a `` declaration. [[mvc-http2]] == HTTP/2 -[.small]#<># +[.small]#<># Servlet 4 containers are required to support HTTP/2, and Spring Framework 5 is compatible with Servlet API 4. From a programming model perspective, there is nothing specific that @@ -4981,4 +4983,4 @@ https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 w The Servlet API does expose one construct related to HTTP/2. You can use the `javax.servlet.http.PushBuilder` proactively push resources to clients, and it -is supported as a <> to `@RequestMapping` methods. +is supported as a <> to `@RequestMapping` methods. diff --git a/src/docs/asciidoc/web/websocket.adoc b/src/docs/asciidoc/web/websocket.adoc index e9ca3c68a0c..3a7f50df112 100644 --- a/src/docs/asciidoc/web/websocket.adoc +++ b/src/docs/asciidoc/web/websocket.adoc @@ -1,7 +1,7 @@ [[websocket]] = WebSockets :doc-spring-security: {doc-root}/spring-security/site/docs/current/reference -[.small]#<># +[.small]#<># This part of the reference documentation covers support for Servlet stack, WebSocket messaging that includes raw WebSocket interactions, WebSocket emulation through SockJS, and @@ -14,7 +14,7 @@ include::websocket-intro.adoc[leveloffset=+1] [[websocket-server]] == WebSocket API -[.small]#<># +[.small]#<># The Spring Framework provides a WebSocket API that you can use to write client- and server-side applications that handle WebSocket messages. @@ -23,7 +23,7 @@ server-side applications that handle WebSocket messages. [[websocket-server-handler]] === `WebSocketHandler` -[.small]#<># +[.small]#<># Creating a WebSocket server is as simple as implementing `WebSocketHandler` or, more likely, extending either `TextWebSocketHandler` or `BinaryWebSocketHandler`. The following @@ -102,10 +102,10 @@ The following example shows the XML configuration equivalent of the preceding ex ---- ==== -The preceding example is for use in Spring MVC applications and should be included in the -configuration of a <>. However, Spring's WebSocket -support does not depend on Spring MVC. It is relatively simple to integrate a `WebSocketHandler` -into other HTTP-serving environments with the help of +The preceding example is for use in Spring MVC applications and should be included +in the configuration of a <>. However, Spring's +WebSocket support does not depend on Spring MVC. It is relatively simple to +integrate a `WebSocketHandler` into other HTTP-serving environments with the help of {api-spring-framework}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`]. When using the `WebSocketHandler` API directly vs indirectly, e.g. through the @@ -118,7 +118,7 @@ sending. One option is to wrap the `WebSocketSession` with [[websocket-server-handshake]] === WebSocket Handshake -[.small]#<># +[.small]#<># The easiest way to customize the initial HTTP WebSocket handshake request is through a `HandshakeInterceptor`, which exposes methods for "`before`" and "`after`" the handshake. @@ -272,7 +272,7 @@ Java initialization API. The following example shows how to do so: [[websocket-server-runtime-configuration]] === Server Configuration -[.small]#<># +[.small]#<># Each underlying WebSocket engine exposes configuration properties that control runtime characteristics, such as the size of message buffer sizes, idle timeout, @@ -407,7 +407,7 @@ The following example shows the XML configuration equivalent of the preceding ex [[websocket-server-allowed-origins]] === Allowed Origins -[.small]#<># +[.small]#<># As of Spring Framework 4.1.5, the default behavior for WebSocket and SockJS is to accept only same-origin requests. It is also possible to allow all or a specified list of origins. @@ -621,7 +621,7 @@ The following example shows the XML configuration equivalent of the preceding ex ==== The preceding example is for use in Spring MVC applications and should be included in the -configuration of a <>. However, Spring's WebSocket +configuration of a <>. However, Spring's WebSocket and SockJS support does not depend on Spring MVC. It is relatively simple to integrate into other HTTP serving environments with the help of {api-spring-framework}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`]. @@ -1008,7 +1008,7 @@ made about HTTP versus raw TCP and how it lets Spring MVC and other web framewor provide rich functionality. The following is a list of benefits: * No need to invent a custom messaging protocol and message format. -* STOMP clients, including a <> +* STOMP clients, including a <> in the Spring Framework, are available. * You can (optionally) use message brokers (such as RabbitMQ, ActiveMQ, and others) to manage subscriptions and broadcast messages. @@ -1125,10 +1125,10 @@ Alternatively, if you connect through WebSocket (without SockJS), you can use th ---- ==== -Note that `stompClient` in the preceding example does not need to specify `login` and `passcode` headers. -Even if it did, they would be ignored (or, rather, overridden) on the server side. See -<> and -<> for more information on authentication. +Note that `stompClient` in the preceding example does not need to specify `login` +and `passcode` headers. Even if it did, they would be ignored (or, rather, +overridden) on the server side. See <> +and <> for more information on authentication. For more example code see: @@ -1255,7 +1255,6 @@ We can trace the flow through a simple example. Consider the following example, registry.setApplicationDestinationPrefixes("/app"); registry.enableSimpleBroker("/topic"); } - } @Controller @@ -1265,9 +1264,7 @@ We can trace the flow through a simple example. Consider the following example, public String handle(String greeting) { return "[" + getTimestamp() + ": " + greeting; } - } - ---- ==== @@ -1316,9 +1313,10 @@ level, `@MessageMapping` is used to express shared mappings across all methods i controller. By default, the mapping values are Ant-style path patterns (for example `/thing*`, `/thing/**`), -including support for template variables (for example, `/thing/{id}`). The values can be referenced through -`@DestinationVariable` method arguments. Applications can also switch to a dot-separated -destination convention for mappings, as explained in <>. +including support for template variables (for example, `/thing/{id}`). The values can be +referenced through `@DestinationVariable` method arguments. Applications can also switch to +a dot-separated destination convention for mappings, as explained in +<>. ===== Supported Method Arguments @@ -1396,7 +1394,7 @@ See <>. `@SubscribeMapping` is similar to `@MessageMapping` but narrows the mapping to subscription messages only. It supports the same -<> as `@MessageMapping`. However +<> as `@MessageMapping`. However for the return value, by default, a message is sent directly to the client (through `clientOutboundChannel`, in response to the subscription) and not to the broker (through `brokerChannel`, as a broadcast to matching subscriptions). Adding `@SendTo` or @@ -1407,8 +1405,8 @@ application controllers are mapped to `/app`. In this setup, the broker stores a subscriptions to `/topic` and `/queue` that are intended for repeated broadcasts, and there is no need for the application to get involved. A client could also also subscribe to some `/app` destination, and a controller could return a value in response to that -subscription without involving the broker -without storing or using the subscription again (effectively a one-time request-reply exchange). One use case for this is populating a UI +subscription without involving the broker without storing or using the subscription again +(effectively a one-time request-reply exchange). One use case for this is populating a UI with initial data on startup. When is this not useful? Do not try to map broker and controllers to the same destination @@ -1440,7 +1438,7 @@ receipt if the server supports it (simple broker does not). For example, with th ---- ==== -A server side option is <> an +A server side option is <> an `ExecutorChannelInterceptor` on the `brokerChannel` and implement the `afterMessageHandled` method that is invoked after messages, including subscriptions, have been handled. @@ -1471,13 +1469,15 @@ The following example declares an exception through a method argument: ---- ==== -`@MessageExceptionHandler` methods support flexible method signatures and support the same -method argument types and return values as <> methods. +`@MessageExceptionHandler` methods support flexible method signatures and support +the same method argument types and return values as +<> methods. -Typically, `@MessageExceptionHandler` methods apply within the `@Controller` class (or -class hierarchy) in which they are declared. If you want such methods to apply more globally -(across controllers), you can declare them in a class marked with `@ControllerAdvice`. -This is comparable to <> that is available in Spring MVC. +Typically, `@MessageExceptionHandler` methods apply within the `@Controller` class +(or class hierarchy) in which they are declared. If you want such methods to apply +more globally (across controllers), you can declare them in a class marked with +`@ControllerAdvice`. This is comparable to the +<> available in Spring MVC. @@ -1634,10 +1634,10 @@ The following example shows the XML configuration equivalent of the preceding ex The STOMP broker relay in the preceding configuration is a Spring {api-spring-framework}/messaging/MessageHandler.html[`MessageHandler`] that handles messages by forwarding them to an external message broker. -To do so, it establishes TCP connections to the broker, forwards all -messages to it, and then forwards all messages received -from the broker to clients through their WebSocket sessions. Essentially, -it acts as a "`relay`" that forwards messages in both directions. +To do so, it establishes TCP connections to the broker, forwards all messages to it, +and then forwards all messages received from the broker to clients through their +WebSocket sessions. Essentially, it acts as a "`relay`" that forwards messages +in both directions. NOTE: Add `io.projectreactor.netty:reactor-netty` and `io.netty:netty-all` dependencies to your project for TCP connection management. @@ -2231,7 +2231,8 @@ since that is also an implementation of `WebSocketClient`. The `SockJsClient` ca use WebSocket or HTTP-based transport as a fallback. For more details, see <>. -Next, you can establish a connection and provide a handler for the STOMP session, as the following example shows: +Next, you can establish a connection and provide a handler for the STOMP session, +as the following example shows: ==== [source,java,indent=0] From d034c053b37f71bc3ca260886e722f7c73300ebd Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 5 Mar 2019 13:47:26 +0100 Subject: [PATCH 6/6] Jackson2Tokenizer passes DeserializationContext into all TokenBuffers See gh-22510 --- .../springframework/http/codec/json/Jackson2Tokenizer.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java index 557948b5401..de9cfaaef22 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2Tokenizer.java @@ -48,6 +48,8 @@ final class Jackson2Tokenizer { private final JsonParser parser; + private final DeserializationContext deserializationContext; + private final boolean tokenizeArrayElements; private TokenBuffer tokenBuffer; @@ -65,6 +67,7 @@ final class Jackson2Tokenizer { JsonParser parser, DeserializationContext deserializationContext, boolean tokenizeArrayElements) { this.parser = parser; + this.deserializationContext = deserializationContext; this.tokenizeArrayElements = tokenizeArrayElements; this.tokenBuffer = new TokenBuffer(parser, deserializationContext); this.inputFeeder = (ByteArrayFeeder) this.parser.getNonBlockingInputFeeder(); @@ -144,7 +147,7 @@ final class Jackson2Tokenizer { if ((token.isStructEnd() || token.isScalarValue()) && this.objectDepth == 0 && this.arrayDepth == 0) { result.add(this.tokenBuffer); - this.tokenBuffer = new TokenBuffer(this.parser); + this.tokenBuffer = new TokenBuffer(this.parser, this.deserializationContext); } } @@ -157,7 +160,7 @@ final class Jackson2Tokenizer { if (this.objectDepth == 0 && (this.arrayDepth == 0 || this.arrayDepth == 1) && (token == JsonToken.END_OBJECT || token.isScalarValue())) { result.add(this.tokenBuffer); - this.tokenBuffer = new TokenBuffer(this.parser); + this.tokenBuffer = new TokenBuffer(this.parser, this.deserializationContext); } }