55
Josh Long, SpringSource, a division of VMware 1 Tailoring Spring for Custom Usage Thursday, January 24, 13

Extending spring

Embed Size (px)

Citation preview

Page 1: Extending spring

• Josh Long, SpringSource, a division of VMware

1

Tailoring Spring for Custom Usage

Thursday, January 24, 13

Page 2: Extending spring

Spring Developer Advocatetwitter: @starbuxmanweibo: @springsource [email protected]

2

About Josh Long (龙之春)

Thursday, January 24, 13

Page 3: Extending spring

Agenda

Explore the value of a framework Exploit some of the lesser known, but powerful, extension

hooks in the core Spring frameworkQA

3

Thursday, January 24, 13

Page 4: Extending spring

Spring’s aim:

bring simplicity to java development

4

web tier &

RIAservice tier batch

processing

integration &

messaging

data access

/ NoSQL / Big Data

mobile

tc ServerTomcatJetty

lightweightCloudFoundry

VMForce Google App Engine

Amazon Web Services

the cloud: WebSphereJBoss ASWebLogic

(on legacy versions, too!)

traditional

The Spring framework

Thursday, January 24, 13

Page 5: Extending spring

The Spring ApplicationContext

• Spring Manages the beans you tell it to manage– use annotations (JSR 250, JSR 330, native)– XML– Java configuration– component scanning

• You can of course use all of them! Mix ‘n match

• All configuration styles tell the ApplicationContext how to manage your beans

5

Thursday, January 24, 13

Page 6: Extending spring

Spring, a walking tour

• Demos:– introduce the tool chain– how to “setup” Spring– basic dependency injection

• annotations (JSR 250, JSR 330, native)• xml• java configuration

6

Thursday, January 24, 13

Page 7: Extending spring

Not confidential. Tell everyone. 7

Spring Integration rules!!

Thursday, January 24, 13

Page 8: Extending spring

8

...what if it doesn’t do what I want?...but??!?

Thursday, January 24, 13

Page 9: Extending spring

Not confidential. Tell everyone. 9

What is Spring Integration?FLEXIBLE

v

Thursday, January 24, 13

Page 10: Extending spring

10

Thursday, January 24, 13

Page 11: Extending spring

11

do NOT reinvent the Wheel!

Thursday, January 24, 13

Page 12: Extending spring

The Open/Closed Principle

"software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”

-Bob Martin

12

Thursday, January 24, 13

Page 13: Extending spring

Working with Lots of Beans

• One way to selectively augment beans at the lower level:– BeanPostProcessor

• are regular beans and are run after the configured beans have been created, but before the context is finished setting up

– BeanFactoryPostProcessor• is run before any of the beans definitions are realized • comes before BPP

• A more natural alternative is Spring’s AOP support– built on top of AspectJ– provides a very convenient, powerful way to solve cross

cutting problems

13

Thursday, January 24, 13

Page 14: Extending spring

Spring, a walking tour

• Demos:– Bean*PostProcessor– AspectJ

14

Thursday, January 24, 13

Page 15: Extending spring

Life Cycles

• Life Cycles for different folks – “safe and consistent” - use the interfaces

• InitializingBean, DisposableBean• correspond to init-method and destroy-method attributes

– Simple and component-centric : use the annotations• @PostConstruct, @PreDestroy• correspond to init-method and destroy-method attributes

– More power: SmartLifecycle• gives you the ability to dynamically start and stop beans in a

certain order as well as to query whether the bean’s been started or not.

15

Thursday, January 24, 13

Page 16: Extending spring

Scopes

• Spring beans have scopes– default: singleton– can be:

• prototype• HTTP session• HTTP request• HTTP application (servlet, basically)• “step” in Spring batch• thread-local • Spring Web Flow “flow” scoped• Spring Web Flow “conversation scoped”• Spring Web Flow “view” scoped (in JSF)• Activiti BPMN2 process-scoped

16

Thursday, January 24, 13

Page 17: Extending spring

public interface Scope {

Object get(String name, ObjectFactory<?> objectFactory); Object remove(String name); void registerDestructionCallback(String name, Runnable callback); Object resolveContextualObject(String key);

String getConversationId();}

Scopes– Implement o.s.beans.factory.config.Scope– register the scope with a o.s.beans.factory.config.CustomScopeConfigurer

17

Thursday, January 24, 13

Page 18: Extending spring

map-like lookup of beans in a given scope

public interface Scope {

Object get(String name, ObjectFactory<?> objectFactory); Object remove(String name); void registerDestructionCallback(String name, Runnable callback); Object resolveContextualObject(String key);

String getConversationId();}

Scopes– Implement o.s.beans.factory.config.Scope– register the scope with a o.s.beans.factory.config.CustomScopeConfigurer

17

Thursday, January 24, 13

Page 19: Extending spring

map-like lookup of beans in a given scope

well known beans like the HttpServletRequest ‘request’ for ‘request’ scope

public interface Scope {

Object get(String name, ObjectFactory<?> objectFactory); Object remove(String name); void registerDestructionCallback(String name, Runnable callback); Object resolveContextualObject(String key);

String getConversationId();}

Scopes– Implement o.s.beans.factory.config.Scope– register the scope with a o.s.beans.factory.config.CustomScopeConfigurer

17

Thursday, January 24, 13

Page 20: Extending spring

null, or storage specific ‘conversation’ ID

map-like lookup of beans in a given scope

well known beans like the HttpServletRequest ‘request’ for ‘request’ scope

public interface Scope {

Object get(String name, ObjectFactory<?> objectFactory); Object remove(String name); void registerDestructionCallback(String name, Runnable callback); Object resolveContextualObject(String key);

String getConversationId();}

Scopes– Implement o.s.beans.factory.config.Scope– register the scope with a o.s.beans.factory.config.CustomScopeConfigurer

17

Thursday, January 24, 13

Page 21: Extending spring

Spring, a walking tour

• Demos:– life cycle callbacks– scopes

• using• creating your own

18

Thursday, January 24, 13

Page 22: Extending spring

Getting Beans from Strange Places

• FactoryBeans• Spring Expression Language

– convenient way to get at values and inject them• Spring environment specific beans (profiles)

– introduced in Spring 3.1– make it easy to conditionally define an object based on

some sort of runtime condition

19

Thursday, January 24, 13

Page 23: Extending spring

Getting Beans from Strange Places

• FactoryBeans– interface that’s used to provide a reusable definition of how

to create a complicated object with many dependencies– Related: Java configuration, and builders

• prefer both over FactoryBeans where possible

20

Thursday, January 24, 13

Page 24: Extending spring

Getting Beans from Strange Places

• Spring Expression Language– convenient way to get at values and inject them– Andy Clement’s a genius – like the Unified JSF EL, on steroids – Can be used in Java, XML

• @Value(“#{ ... }”) or value = “#{ .. }”

21

Thursday, January 24, 13

Page 25: Extending spring

Getting Beans from Strange Places

• Spring profiles• @Profile(“production”) @Configuration ... • <beans profile = ‘production’> ... </beans>

– Use System properties or simply specify the active profile on the environment

– Use ApplicationContextInitializer in web applications

22

Thursday, January 24, 13

Page 26: Extending spring

Getting Beans from Strange Places

• An ApplicationContextInitializer

23

public interface ApplicationContextInitializer <C extends ConfigurableApplicationContext> {

void initialize(C applicationContext);}

Thursday, January 24, 13

Page 27: Extending spring

Getting Beans from Strange Places

• Demos:– FactoryBeans– SpEL– Profiles

• ApplicationContextInitializers

24

Thursday, January 24, 13

Page 28: Extending spring

Proxies!

25

CustomerService cs = new CustomerService();cs...

ProxyFactory pf = new ProxyFaxctory();pf.setTarget( cs );pf.addAdvice(new MethodInterceptor(){ public Object invoke(MethodInvocation mi) { // ... } } );return (CustomerService) pf.getObject() ;

Thursday, January 24, 13

Page 29: Extending spring

Using Spring’s Resources

• Spring supports out of the box ClassPathResource, FileResource system, etc.

• Writing your own Resource implementations

26

public interface Resource extends InputStreamSource { boolean exists(); boolean isReadable(); boolean isOpen(); URL getURL() throws IOException; URI getURI() throws IOException; File getFile() throws IOException; long contentLength() throws IOException; long lastModified() throws IOException; Resource createRelative(String relativePath) throws IOException; String getFilename(); String getDescription();}

Thursday, January 24, 13

Page 30: Extending spring

Object to XML Marshallers

• Easy to add your own Marshaller (and Unmarshaller)

27

public interface Marshaller {

boolean supports(Class<?> clazz); void marshal(Object graph, Result result) throws IOException, XmlMappingException;}

Thursday, January 24, 13

Page 31: Extending spring

Object to XML Marshallers

• Demos:– a custom object-to-XML marshaller

28

Thursday, January 24, 13

Page 32: Extending spring

REST

• Spring MVC for the server

29

@RequestMapping( value = “/crm/customers/{id}” , method =HttpMethod.GET)public @ResponseBody Customer lookupCustomerById( @PathVariable(“id”) long customerId ) { ... return customer; }

Thursday, January 24, 13

Page 33: Extending spring

REST

• RestTemplate for the client (Android, SE, web applications, etc.)

30

RestTemplate rt = new RestTemplate() ;

String url = “http://mysvc.cloudfoundry.com/crm/customer/{id}”;

Customer customer = rt.getForObject( url, Customer.class, 22);

Thursday, January 24, 13

Page 34: Extending spring

REST

• Both need o.s.http.converter.HttpMessageConverters• Spring supports:

– object-to-XML (JAXB as well as any Spring OXM impl)– object-to-JSON– binary data (o.s.resource.Resource references or byte[])– ATOM/RSS– images

• Easy to add your own

31

Thursday, January 24, 13

Page 35: Extending spring

Registering a custom HttpMessageConverter

32

@EnableWebMvcpublic class WebConfiguration extends WebMvcConfigurerAdapter {

@Override public void configureMessageConverters( List<HttpMessageConverter<?>> converters) {

}

}

Thursday, January 24, 13

Page 36: Extending spring

REST

• Demos:– Writing and using a customer HttpMessageConverter

33

Thursday, January 24, 13

Page 37: Extending spring

Transactions

• Spring supports declarative transaction management– @EnableTransactionManagement or

<tx:annotation-driven/>

• PlatformTransactionManager implementations used to manage transactions– lots of options out of the box:

• AMQP, JMS, JTA, JDBC, JDO, JPA, WebLogic-specific, WebSphere-specific, OC4J-specific, etc.

34

Thursday, January 24, 13

Page 38: Extending spring

Transactions

• PlatformTransactionManager abstracts the notion of a transactional “unit of work.”

35

public interface PlatformTransactionManager { TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException;}

Thursday, January 24, 13

Page 39: Extending spring

Caching

• CacheManager’s maintain Caches.– CacheManagers are like ‘connections’– Caches are like regions of a cache

36

public interface CacheManager { Cache getCache(String name); Collection<String> getCacheNames();}

public interface Cache {

interface ValueWrapper { Object get(); }

String getName(); Object getNativeCache(); ValueWrapper get(Object key); void put(Object key, Object value); void evict(Object key); void clear();}

Thursday, January 24, 13

Page 40: Extending spring

Writing a custom View and View Resolver

37

Thursday, January 24, 13

Page 41: Extending spring

Writing a custom View and View Resolver

• Easy to add your own View – supported views out of the box: FreeMarker, Velocity,

Excel, PDFs, JasperReports, XSLT, Jackson, JSTL, etc. – Lots of contributions from the open source community:

• Thymeleaf http://www.thymeleaf.org/

• Mustache by Sean Scanlon https://github.com/sps/mustache-spring-view

38

Thursday, January 24, 13

Page 42: Extending spring

Writing a custom View and View Resolver

39

public interface ViewResolver { View resolveViewName(String viewName, Locale locale) throws Exception;}

Thursday, January 24, 13

Page 43: Extending spring

Writing a custom View and View Resolver

40

public interface View {

String RESPONSE_STATUS_ATTRIBUTE = View.class.getName() + ".responseStatus"; String getContentType(); void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;

}

Thursday, January 24, 13

Page 44: Extending spring

if ‘detectAllViewResolvers’ is true, all ViewResolvers types will be registered.

Writing a custom View and View Resolver

41

@Beanpublic ViewResolver myCustomViewResolver(){ ... }

@Beanpublic MyCustomViewResolver viewResolver(){ ... }

Thursday, January 24, 13

Page 45: Extending spring

if ‘detectAllViewResolvers’ is true, all ViewResolvers types will be registered.

if ‘detectAllViewResolvers’ is false, it’ll lookup a bean by a well known name

Writing a custom View and View Resolver

41

@Beanpublic ViewResolver myCustomViewResolver(){ ... }

@Beanpublic MyCustomViewResolver viewResolver(){ ... }

Thursday, January 24, 13

Page 46: Extending spring

Writing a custom View and View Resolver

• Demo: writing a custom view/view resolver

42

Thursday, January 24, 13

Page 47: Extending spring

A Custom NameSpace

43

public class ASimpleParser extends AbstractSingleBeanDefinitionParser {

@Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { String exchangeName = element.getAttribute(NAME_ATTRIBUTE); builder.addConstructorArgValue(new TypedStringValue(exchangeName)); Element bindings = DomUtils.getChildElementByTagName(element, BINDINGS_ELE); if (bindings != null) { } NamespaceUtils.addConstructorArgBooleanValueIfAttributeDefined(builder, element, DURABLE_ATTRIBUTE, true); ...

}

Thursday, January 24, 13

Page 48: Extending spring

Writing Adapters in Spring Integration

44

Thursday, January 24, 13

Page 49: Extending spring

Writing Adapters in Spring Integration

• MessageSource for inbound adapters• MessageHandler for outbound adapters

45

MessageHandlerMessageSource

Thursday, January 24, 13

Page 50: Extending spring

Writing Adapters in Spring Integration

46

package org.springframework.integration.core;

public interface MessageSource<T> { org.springframework.integration.Message<T> receive();}

<int:channel id = “in” />

<int:inbound-channel-adapter channel = “in” ref = “myCustomMessageSource” > <int:cron-trigger ... /></int:inbound-channel-adapter>

• Inbound channel adapter “receives” message from external system inward relative to Spring Integration code

Thursday, January 24, 13

Page 51: Extending spring

Writing Adapters in Spring Integration

47

<int:channel id = “out” />

<int:outbound-channel-adapter channel = “out” ref = “myCustomMessageHandler” />

package org.springframework.integration.core;

public interface MessageHandler { void handleMessage( org.springframework.integration.Message<?> message) throws org.springframework.integration.MessagingException;

}

• Outbound channel adapter “publishes” message from Spring Integration outward relative to Spring Integration code

Thursday, January 24, 13

Page 52: Extending spring

Spring Integration File System Adapters

• Spring Integration provides rich file system adapters– FTP, SFTP, FTPS, files in general – But... what about SMB/CIFS?

48

Thursday, January 24, 13

Page 53: Extending spring

Writing Readers and Writers in Spring Batch

• ItemReader for inbound adapters• ItemWriters for outbound adapters

49

Thursday, January 24, 13

Page 54: Extending spring

Summary / Questions

• code: git.springsource.org:spring-samples/spring-samples.git

• github.com/SpringSource • weibo.com/SpringFramework• blog.springsource.org • [email protected] • springsource.com/developer/sts

50

Thursday, January 24, 13

Page 55: Extending spring

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

Q&A

51

Thursday, January 24, 13