Transcript
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!


Top Related