View
821
Download
3
Category
Preview:
Citation preview
• Josh Long, SpringSource, a division of VMware
1
Tailoring Spring for Custom Usage
Thursday, January 24, 13
Spring Developer Advocatetwitter: @starbuxmanweibo: @springsource josh.long@springsource.com
2
About Josh Long (龙之春)
Thursday, January 24, 13
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
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
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
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
Not confidential. Tell everyone. 7
Spring Integration rules!!
Thursday, January 24, 13
8
...what if it doesn’t do what I want?...but??!?
Thursday, January 24, 13
Not confidential. Tell everyone. 9
What is Spring Integration?FLEXIBLE
v
Thursday, January 24, 13
10
Thursday, January 24, 13
11
do NOT reinvent the Wheel!
Thursday, January 24, 13
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
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
Spring, a walking tour
• Demos:– Bean*PostProcessor– AspectJ
14
Thursday, January 24, 13
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
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
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
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
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
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
Spring, a walking tour
• Demos:– life cycle callbacks– scopes
• using• creating your own
18
Thursday, January 24, 13
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
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
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
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
Getting Beans from Strange Places
• An ApplicationContextInitializer
23
public interface ApplicationContextInitializer <C extends ConfigurableApplicationContext> {
void initialize(C applicationContext);}
Thursday, January 24, 13
Getting Beans from Strange Places
• Demos:– FactoryBeans– SpEL– Profiles
• ApplicationContextInitializers
24
Thursday, January 24, 13
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
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
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
Object to XML Marshallers
• Demos:– a custom object-to-XML marshaller
28
Thursday, January 24, 13
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
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
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
Registering a custom HttpMessageConverter
32
@EnableWebMvcpublic class WebConfiguration extends WebMvcConfigurerAdapter {
@Override public void configureMessageConverters( List<HttpMessageConverter<?>> converters) {
}
}
Thursday, January 24, 13
REST
• Demos:– Writing and using a customer HttpMessageConverter
33
Thursday, January 24, 13
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
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
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
Writing a custom View and View Resolver
37
Thursday, January 24, 13
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
Writing a custom View and View Resolver
39
public interface ViewResolver { View resolveViewName(String viewName, Locale locale) throws Exception;}
Thursday, January 24, 13
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
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
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
Writing a custom View and View Resolver
• Demo: writing a custom view/view resolver
42
Thursday, January 24, 13
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
Writing Adapters in Spring Integration
44
Thursday, January 24, 13
Writing Adapters in Spring Integration
• MessageSource for inbound adapters• MessageHandler for outbound adapters
45
MessageHandlerMessageSource
Thursday, January 24, 13
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
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
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
Writing Readers and Writers in Spring Batch
• ItemReader for inbound adapters• ItemWriters for outbound adapters
49
Thursday, January 24, 13
Summary / Questions
• code: git.springsource.org:spring-samples/spring-samples.git
• github.com/SpringSource • weibo.com/SpringFramework• blog.springsource.org • josh.long@springsource.com • springsource.com/developer/sts
50
Thursday, January 24, 13
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Q&A
51
Thursday, January 24, 13
Recommended