Skip to content

Commit

Permalink
Modernize the integration section of the refdoc
Browse files Browse the repository at this point in the history
This commit adds Java and Kotlin tabs to XML code snippets where
relevant, and leverages code includes.

Closes gh-32600
  • Loading branch information
sdeleuze committed May 6, 2024
1 parent bdc4ecd commit c6459b4
Show file tree
Hide file tree
Showing 95 changed files with 2,880 additions and 522 deletions.
3 changes: 3 additions & 0 deletions framework-docs/framework-docs.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ dependencies {
api("org.aspectj:aspectjweaver")
api("io.projectreactor.netty:reactor-netty-http")
api("org.eclipse.jetty.websocket:jetty-websocket-jetty-api")
api("javax.cache:cache-api")
api("jakarta.resource:jakarta.resource-api")
api("org.apache.activemq:activemq-ra:6.1.2")

implementation(project(":spring-core-test"))
implementation("org.assertj:assertj-core")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -518,41 +518,9 @@ disable it by removing only one configuration line rather than all the annotatio
your code).

To enable caching annotations add the annotation `@EnableCaching` to one of your
`@Configuration` classes:
`@Configuration` classes or use the `cache:annotation-driven` element with XML:

[source,java,indent=0,subs="verbatim,quotes"]
----
@Configuration
@EnableCaching
public class AppConfig {
@Bean
CacheManager cacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
cacheManager.setCacheSpecification(...);
return cacheManager;
}
}
----

Alternatively, for XML configuration you can use the `cache:annotation-driven` element:

[source,xml,indent=0,subs="verbatim,quotes"]
----
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache https://www.springframework.org/schema/cache/spring-cache.xsd">
<cache:annotation-driven/>
<bean id="cacheManager" class="org.springframework.cache.caffeine.CaffeineCacheManager">
<property name="cacheSpecification" value="..."/>
</bean>
</beans>
----
include-code::./CacheConfiguration[tag=snippet,indent=0]

Both the `cache:annotation-driven` element and the `@EnableCaching` annotation let you
specify various options that influence the way the caching behavior is added to the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,7 @@ The JDK-based `Cache` implementation resides under
`org.springframework.cache.concurrent` package. It lets you use `ConcurrentHashMap`
as a backing `Cache` store. The following example shows how to configure two caches:

[source,xml,indent=0,subs="verbatim,quotes"]
----
<!-- simple cache manager -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default"/>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="books"/>
</set>
</property>
</bean>
----
include-code::./CacheConfiguration[tag=snippet,indent=0]

The preceding snippet uses the `SimpleCacheManager` to create a `CacheManager` for the
two nested `ConcurrentMapCache` instances named `default` and `books`. Note that the
Expand Down Expand Up @@ -52,26 +41,12 @@ of Caffeine.

The following example configures a `CacheManager` that creates the cache on demand:

[source,xml,indent=0,subs="verbatim,quotes"]
----
<bean id="cacheManager"
class="org.springframework.cache.caffeine.CaffeineCacheManager"/>
----
include-code::./CacheConfiguration[tag=snippet,indent=0]

You can also provide the caches to use explicitly. In that case, only those
are made available by the manager. The following example shows how to do so:

[source,xml,indent=0,subs="verbatim,quotes"]
----
<bean id="cacheManager" class="org.springframework.cache.caffeine.CaffeineCacheManager">
<property name="cacheNames">
<set>
<value>default</value>
<value>books</value>
</set>
</property>
</bean>
----
include-code::./CustomCacheConfiguration[tag=snippet,indent=0]

The Caffeine `CacheManager` also supports custom `Caffeine` and `CacheLoader`.
See the https://github.com/ben-manes/caffeine/wiki[Caffeine documentation]
Expand All @@ -97,15 +72,7 @@ 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:

[source,xml,indent=0,subs="verbatim,quotes"]
----
<bean id="cacheManager"
class="org.springframework.cache.jcache.JCacheCacheManager"
p:cache-manager-ref="jCacheManager"/>
<!-- JSR-107 cache manager setup -->
<bean id="jCacheManager" .../>
----
include-code::./CacheConfiguration[tag=snippet,indent=0]


[[cache-store-configuration-noop]]
Expand All @@ -119,18 +86,7 @@ cache declarations (which can prove tedious), you can wire in a simple dummy cac
performs no caching -- that is, it forces the cached methods to be invoked every time.
The following example shows how to do so:

[source,xml,indent=0,subs="verbatim,quotes"]
----
<bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager">
<property name="cacheManagers">
<list>
<ref bean="jdkCache"/>
<ref bean="gemfireCache"/>
</list>
</property>
<property name="fallbackToNoOpCache" value="true"/>
</bean>
----
include-code::./CacheConfiguration[tag=snippet,indent=0]

The `CompositeCacheManager` in the preceding chains multiple `CacheManager` instances and,
through the `fallbackToNoOpCache` flag, adds a no-op cache for all the definitions not
Expand Down
72 changes: 3 additions & 69 deletions framework-docs/modules/ROOT/pages/integration/email.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,7 @@ JavaMail features, such as MIME message support to the `MailSender` interface

Assume that we have a business interface called `OrderManager`, as the following example shows:

[source,java,indent=0,subs="verbatim,quotes"]
----
public interface OrderManager {
void placeOrder(Order order);
}
----
include-code::./OrderManager[tag=snippet,indent=0]

Further assume that we have a requirement stating that an email message with an
order number needs to be generated and sent to a customer who placed the relevant order.
Expand All @@ -60,70 +53,11 @@ order number needs to be generated and sent to a customer who placed the relevan
The following example shows how to use `MailSender` and `SimpleMailMessage` to send an
email when someone places an order:

[source,java,indent=0,subs="verbatim,quotes"]
----
import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
public class SimpleOrderManager implements OrderManager {
private MailSender mailSender;
private SimpleMailMessage templateMessage;
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
public void setTemplateMessage(SimpleMailMessage templateMessage) {
this.templateMessage = templateMessage;
}
public void placeOrder(Order order) {
// Do the business calculations...
// Call the collaborators to persist the order...
// Create a thread-safe "copy" of the template message and customize it
SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);
msg.setTo(order.getCustomer().getEmailAddress());
msg.setText(
"Dear " + order.getCustomer().getFirstName()
+ order.getCustomer().getLastName()
+ ", thank you for placing order. Your order number is "
+ order.getOrderNumber());
try {
this.mailSender.send(msg);
}
catch (MailException ex) {
// simply log it and go on...
System.err.println(ex.getMessage());
}
}
}
----
include-code::./SimpleOrderManager[tag=snippet,indent=0]

The following example shows the bean definitions for the preceding code:

[source,xml,indent=0,subs="verbatim,quotes"]
----
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="mail.mycompany.example"/>
</bean>
<!-- this is a template message that we can pre-load with default state -->
<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="customerservice@mycompany.example"/>
<property name="subject" value="Your order"/>
</bean>
<bean id="orderManager" class="com.mycompany.businessapp.support.SimpleOrderManager">
<property name="mailSender" ref="mailSender"/>
<property name="templateMessage" ref="templateMessage"/>
</bean>
----
include-code::./MailConfiguration[tag=snippet,indent=0]


[[mail-usage-mime]]
Expand Down
34 changes: 1 addition & 33 deletions framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,7 @@ declarations to it.
To enable support for `@JmsListener` annotations, you can add `@EnableJms` to one of
your `@Configuration` classes, as the following example shows:

[source,java,indent=0,subs="verbatim,quotes"]
----
@Configuration
@EnableJms
public class AppConfig {
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
factory.setDestinationResolver(destinationResolver());
factory.setSessionTransacted(true);
factory.setConcurrency("3-10");
return factory;
}
}
----
include-code::./JmsConfiguration[tag=snippet,indent=0]

By default, the infrastructure looks for a bean named `jmsListenerContainerFactory`
as the source for the factory to use to create message listener containers. In this
Expand All @@ -67,22 +51,6 @@ container factory. See the javadoc of classes that implement
{spring-framework-api}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]
for details and examples.

If you prefer xref:integration/jms/namespace.adoc[XML configuration], you can use the `<jms:annotation-driven>`
element, as the following example shows:

[source,xml,indent=0,subs="verbatim,quotes"]
----
<jms:annotation-driven/>
<bean id="jmsListenerContainerFactory"
class="org.springframework.jms.config.DefaultJmsListenerContainerFactory">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destinationResolver" ref="destinationResolver"/>
<property name="sessionTransacted" value="true"/>
<property name="concurrency" value="3-10"/>
</bean>
----


[[jms-annotated-programmatic-registration]]
== Programmatic Endpoint Registration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,62 +7,13 @@ automatically determine the `ActivationSpec` class name from the provider's
`ResourceAdapter` class name. Therefore, it is typically possible to provide
Spring's generic `JmsActivationSpecConfig`, as the following example shows:

[source,xml,indent=0,subs="verbatim,quotes"]
----
<bean class="org.springframework.jms.listener.endpoint.JmsMessageEndpointManager">
<property name="resourceAdapter" ref="resourceAdapter"/>
<property name="activationSpecConfig">
<bean class="org.springframework.jms.listener.endpoint.JmsActivationSpecConfig">
<property name="destinationName" value="myQueue"/>
</bean>
</property>
<property name="messageListener" ref="myMessageListener"/>
</bean>
----
include-code::./JmsConfiguration[tag=snippet,indent=0]

Alternatively, you can set up a `JmsMessageEndpointManager` with a given
`ActivationSpec` object. The `ActivationSpec` object may also come from a JNDI lookup
(using `<jee:jndi-lookup>`). The following example shows how to do so:

[source,xml,indent=0,subs="verbatim,quotes"]
----
<bean class="org.springframework.jms.listener.endpoint.JmsMessageEndpointManager">
<property name="resourceAdapter" ref="resourceAdapter"/>
<property name="activationSpec">
<bean class="org.apache.activemq.ra.ActiveMQActivationSpec">
<property name="destination" value="myQueue"/>
<property name="destinationType" value="jakarta.jms.Queue"/>
</bean>
</property>
<property name="messageListener" ref="myMessageListener"/>
</bean>
----

Using Spring's `ResourceAdapterFactoryBean`, you can configure the target `ResourceAdapter`
locally, as the following example shows:

[source,xml,indent=0,subs="verbatim,quotes"]
----
<bean id="resourceAdapter" class="org.springframework.jca.support.ResourceAdapterFactoryBean">
<property name="resourceAdapter">
<bean class="org.apache.activemq.ra.ActiveMQResourceAdapter">
<property name="serverUrl" value="tcp://localhost:61616"/>
</bean>
</property>
<property name="workManager">
<bean class="org.springframework.jca.work.SimpleTaskWorkManager"/>
</property>
</bean>
----

The specified `WorkManager` can also point to an environment-specific thread pool --
typically through a `SimpleTaskWorkManager` instance's `asyncTaskExecutor` property.
Consider defining a shared thread pool for all your `ResourceAdapter` instances
if you happen to use multiple adapters.

In some environments, you can instead obtain the entire `ResourceAdapter` object from JNDI
(by using `<jee:jndi-lookup>`). The Spring-based message listeners can then interact with
the server-hosted `ResourceAdapter`, which also use the server's built-in `WorkManager`.
include-code::./AlternativeJmsConfiguration[tag=snippet,indent=0]

See the javadoc for {spring-framework-api}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],
{spring-framework-api}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],
Expand Down

0 comments on commit c6459b4

Please sign in to comment.