26
© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission. Caching and messaging improvements in Spring 4.1 Juergen Hoeller (@springjuergen) - Stéphane Nicoll (@snicoll)

Caching and Messaging Improvements in Spring Framework 4.1

Embed Size (px)

DESCRIPTION

Speaker: Juergen Hoeller, Stéphane Nicoll Core Spring Track This session showcases major new features along the lines of two key themes in Spring Framework 4.1: We’ll start with numerous improvements around the caching abstraction, as requested by the community, including the support for JCache (JSR-107) standard annotations. We’ll then move on to messaging-related features such as annotated JMS listener endpoints with flexible method signatures, using the messaging abstraction introduced in Spring Framework 4.0 and therefore aligning our core JMS support with our STOMP endpoint style.

Citation preview

Page 1: Caching and Messaging Improvements in Spring Framework 4.1

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Caching and messaging improvements in Spring 4.1

Juergen Hoeller (@springjuergen) - Stéphane Nicoll (@snicoll)

Page 2: Caching and Messaging Improvements in Spring Framework 4.1

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Caching improvements

Page 3: Caching and Messaging Improvements in Spring Framework 4.1

Cache abstraction recap

3

public class BookRepository {!!!!!!!!!!!!!!}!

@Cacheable("books")!public Book findById(String id) { }

@Cacheable(value = "books", key = "T(s2gx.caching.BookIdResolver).resolveBookId(#isbn)")!public Book findById(ISBN isbn) { }!

@CachePut(value = "books", key = "#book.id")!public Book update(Book book) { }

@CacheEvict(value = "books")!public void delete(String id) { }!

Page 4: Caching and Messaging Improvements in Spring Framework 4.1

Cache abstraction recap (cont’d)

4

@Configuration!@EnableCaching!public class ApplicationConfig {!! @Value("classpath:my-ehcache.xml")! private Resource ehCacheConfig;!! @Bean! public CacheManager cacheManager() {! return new EhCacheCacheManager(! EhCacheManagerUtils.buildCacheManager(ehCacheConfig));! }!!}!

Page 5: Caching and Messaging Improvements in Spring Framework 4.1

Class level customizations

5

@CacheConfig("books")!public class BookRepository {!! @Cacheable! public Book findById(String id) { }!! @Cacheable(key = "T(s2gx.caching.BookIdResolver).resolveBookId(#isbn)")! public Book findById(ISBN isbn) { }!! @CachePut(key = "#book.id")! public Book update(Book book) { }!! @CacheEvict! public void delete(String id) { }!!}!

Page 6: Caching and Messaging Improvements in Spring Framework 4.1

Custom key generator

6

@Component!public class IsbnKeyGenerator implements KeyGenerator {!!! @Override!! public Object generate(Object target, Method method, Object... params) {!! ! ISBN isbn = extract(params);!! ! if (isbn != null) {!! ! ! return BookIdResolver.resolveBookId(isbn);!! ! }!! ! throw new IllegalStateException(getClass().getName() +!! ! ! ! " could not generate a cache id from " + Arrays.toString(params));!! }!!! private ISBN extract(Object... params) { }!}!

Page 7: Caching and Messaging Improvements in Spring Framework 4.1

Operation level customizations

7

@CacheConfig("books")!public class BookRepository {!! @Cacheable! public Book findById(String id) { }!! @Cacheable(keyGenerator = "isbnKeyGenerator")! public Book findById(ISBN isbn) { }!! @CachePut(key = "#book.id")! public Book update(Book book) { }!! @CacheEvict! public void delete(String id) { }!!}!

Page 8: Caching and Messaging Improvements in Spring Framework 4.1

CacheResolver

8

public interface CacheResolver {!! Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context);!!}!

public class MyCacheResolver extends AbstractCacheResolver {!! @Autowired! public MyCacheResolver(CacheManager cacheManager) {! super(cacheManager);! }!! @Override! protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) {! return getCacheNames(context.getTarget().getClass());! }!! private Collection<String> getCacheNames(Class<?> serviceType) { }! !}!

Page 9: Caching and Messaging Improvements in Spring Framework 4.1

JCache (JSR-107) support

9

import javax.cache.annotation.CacheDefaults;!import javax.cache.annotation.CachePut;!import javax.cache.annotation.CacheRemove;!import javax.cache.annotation.CacheResult;!import javax.cache.annotation.CacheValue;!!@CacheDefaults(cacheName = "books")!public class BookRepository {!! @CacheResult! public Book findById(String id) { }!! @CacheResult(cacheKeyGenerator = IsbnCacheKeyGenerator.class)! public Book findById(ISBN isbn) { }!! @CachePut! public void update(String id, @CacheValue Book book) { }!! @CacheRemove! public void delete(String id) { }!!}!

Page 10: Caching and Messaging Improvements in Spring Framework 4.1

JCache configuration

10

@Configuration!@EnableCaching!public class ApplicationConfig {!! @Value("classpath:my-ehcache.xml")! private Resource ehCacheConfig;!! @Bean! public CacheManager cacheManager() {! return new EhCacheCacheManager(! EhCacheManagerUtils.buildCacheManager(ehCacheConfig));! }!!}!

Page 11: Caching and Messaging Improvements in Spring Framework 4.1

Standard JCache bootstraping

11

@Configuration!@EnableCaching!public class ApplicationConfig {!! @Bean! public CacheManager cacheManager() {! return new JCacheCacheManager();! }!!}!

Page 12: Caching and Messaging Improvements in Spring Framework 4.1

Wrapping up• More use cases are covered out-of-the-box, no need to fallback on

programmatic cache access: • CacheResolver: fine-grained runtime cache resolution • Class-level customizations via @CacheConfig: cache name(s),

key generator, cache manager and/or cache resolver • Operation-level customizations

• JCache (JSR-107) support • Supported automatically when the JSR-107 API is on the classpath • Reuse your existing infrastructure/configuration

• Others • Convenient putIfAbsent on Cache interface • Better exception handling

12

Page 13: Caching and Messaging Improvements in Spring Framework 4.1

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Messaging improvements

Page 14: Caching and Messaging Improvements in Spring Framework 4.1

Messaging infrastructure recap

14

public class OrderMessageHandler {!! public OrderStatus handleMessage(Order order) {! // order processing, return status! }!}!

<beans ...>! <jms:listener-container message-converter="jmsMessageConverter">! <jms:listener destination="order" ref="orderMessageHandler" method="handleMessage"/>! </jms:listener-container>!! <bean id="orderMessageHandler" class="sgx2014.messaging.spr40.OrderMessageHandler"/>!! <bean id="jmsMessageConverter"! class="org.springframework.jms.support.converter.MappingJackson2MessageConverter">! <property name="targetType" value="TEXT"/>! <property name="typeIdPropertyName" value="__type"/>! </bean>!</beans>!

Page 15: Caching and Messaging Improvements in Spring Framework 4.1

Annotated endpoint

15

@Component!public class OrderMessageHandler {!! @JmsListener(destination = "order")! public OrderStatus process(Order order) {! // order processing, return status! }!}!

@JmsListener(id = "orderListener", containerFactory = "myContainerFactory", ! destination = "order", selector = "orderType = 'sell'", concurrency = "2-10")!public OrderStatus process(Order order) {! // order processing, return status!}!

Page 16: Caching and Messaging Improvements in Spring Framework 4.1

Transition from your existing config

16

<?xml version="1.0" encoding="UTF-8"?>!<beans ...>!! <jms:annotation-driven/>!! <jms:listener-container factory-id="jmsListenerContainerFactory" ! message-converter="jmsMessageConverter"/>!! <bean id="jmsMessageConverter"! class="org.springframework.jms.support.converter.MappingJackson2MessageConverter">! <property name="targetType" value="TEXT"/>! <property name="typeIdPropertyName" value="__type"/>! </bean>!!</beans>!

Page 17: Caching and Messaging Improvements in Spring Framework 4.1

… or remove XML altogether

17

@EnableJms!@Configuration!public class ApplicationConfig {!! @Bean! public JmsListenerContainerFactory<?> jmsListenerContainerFactory(! ConnectionFactory connectionFactory) {!! DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();! factory.setConnectionFactory(connectionFactory);! factory.setMessageConverter(jmsMessageConverter());! return factory;! }!! @Bean! public MessageConverter jmsMessageConverter() {! MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();! converter.setTargetType(MessageType.TEXT);! converter.setTypeIdPropertyName("__type");! return converter;! }!}!

Page 18: Caching and Messaging Improvements in Spring Framework 4.1

Flexible method signature

18

@JmsListener(destination = "order")!public void processOrder(Order order) { }

@JmsListener(destination = "order")!public void processOrder(Session session, TextMessage textMessage) { }

@JmsListener(destination = "order")!public void processOrder(@Valid Order order) { }

@JmsListener(destination = "order")!public void processOrder(Order order, @Header String orderType) { }

@JmsListener(destination = "order")!@SendTo("orderStatus")!public OrderStatus processOrder(Order order) { }

Page 19: Caching and Messaging Improvements in Spring Framework 4.1

Messaging abstraction

• Introduced in Spring Framework 4.0 • org.springframework.messaging.Message is a generic

message representation with headers and a body !!!!

• Full access to body and headers for both inbound and outbound messages

19

@JmsListener(destination = "order")!@SendTo("orderStatus")!public Message<OrderStatus> processOrder(Message<Order> order) { }!

Page 20: Caching and Messaging Improvements in Spring Framework 4.1

JmsMessagingTemplate

• Similar to JmsTemplate, using o.s.messaging.Message • Exception translation • No JMS api involved at all • Implements common spring-messaging interfaces

• MessageSendingOperations

• MessageReceivingOperations

• MessageRequestReplyOperations

20

Message<Order> orderMessage = MessageBuilder.! withPayload(order).setHeader("orderType", "sell").build();!messagingTemplate.send("order", orderMessage);!

Page 21: Caching and Messaging Improvements in Spring Framework 4.1

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

https://github.com/SpringOne2GX-2014/messaging-improvements

Demo

Page 22: Caching and Messaging Improvements in Spring Framework 4.1

Programmatic endpoints registration

22

@EnableJms!@Configuration!public class ApplicationConfiguration implements JmsListenerConfigurer {!! @Override! public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {! SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();! endpoint.setDestination("myQueue");! endpoint.setConcurrency("2-10");! endpoint.setMessageListener(message -> {! // message processing! });! registrar.registerEndpoint(endpoint);! }!}!

Page 23: Caching and Messaging Improvements in Spring Framework 4.1

Container recovery

• Recovery policy when the broker becomes unreachable • BackOff interface • FixedBackOff: retry every X sec (default to 5 sec) • ExponentialBackOff: increases the back off period for

each retry attempt • Implement your own!

23

ExponentialBackOff backOff = new ExponentialBackOff();!backOff.setInitialInterval(2 * 1000); // initial retry every 2 sec!backOff.setMultiplier(1.5); // increase each attempt by 50%!backOff.setMaxInterval(30 * 1000); // stop increasing at 30 sec!factory.setBackOff(backOff);!

Page 24: Caching and Messaging Improvements in Spring Framework 4.1

Wrapping Up

• Annotation-driven endpoints • Full java config support

• Flexible method signature: @Payload, @Valid, @Header, @Headers

• Messaging abstraction integration • JmsMessagingTemplate

• Message<?> can be used as method argument / return type • Endpoint abstraction, programmatic endpoint registration • Container recovery customization • Further JMS 2.0 alignments (shared subscriptions)

24

Page 25: Caching and Messaging Improvements in Spring Framework 4.1

One more thing …

• You can use that with AMQP too • Spring AMQP 1.4.0.M1

25

@Component!public class OrderMessageHandler {!! @RabbitListener(queues = "order")! @SendTo("orderStatus")! public OrderStatus processOrder(Order order, @Header String orderType) { }!}!

Page 26: Caching and Messaging Improvements in Spring Framework 4.1

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Q/A

Thank you!