Going Beyond Dependency Injection

75
© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission. Going Beyond Dependency Injection By Mark Secrist

description

Speaker: Mark Secrist Many developers who are learning the Spring Framework think of it as simply another mechanism for centralized dependency injection. While the framework does handle that responsibility quite well, the framework is so much more. In this session, we'll explore some of the building blocks and patterns used by the core framework as well as many of the other Spring projects. The result is that attendees will gain a better understanding of how to use the Spring Framework and learn how to build their own components that can leverage these same patterns. Topics we'll explore: - What is the benefit of centralized lifecycle management - Programming to interfaces - Leveraging the power of proxies - Using annotations - Understanding the template pattern Dependency injection is one very important part of what the Spring Framework does. However, it is also a collection of very key patterns that we'll explore. - Centralized lifecycle management - Examining the BeanFactoryPostProcessor - Examining the BeanPostProcessor - How to write your own BeanPostProcessor - Programming to interfaces - Benefits of programming to interfaces - loose coupling - Examples of how Spring leverages this mechanism - How to leverage in your own Spring applications - Leveraging the power of proxies - How proxies work in Spring - How Spring uses them - Writing your own proxy-based solution - Using annotations - Examples of how Spring uses annotations - Using your own annotations - Understanding the template pattern - Purpose of template pattern - How Spring uses templates - Creating your own template

Transcript of Going Beyond Dependency Injection

Page 1: Going Beyond Dependency Injection

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

Going Beyond Dependency Injection By Mark Secrist

Page 2: Going Beyond Dependency Injection

A Bit About Me •  Developer 20+ years

–  C/C++ –  Java/JEE

•  Consultant/Evangelist for Java on HP –  Promoting Java & JEE stack on HP Hardware

•  Technical Trainer –  Core Spring –  Spring Web –  Groovy & Grails –  Gemfire –  Big Data, Hadoop and Pivotal HD

Page 3: Going Beyond Dependency Injection

What We’re Going to Cover •  Overview of Spring Lifecycle •  Key Patterns used in Spring

–  Programming to Interfaces –  Proxy Power & AOP –  Templates

Goal: Understand how Spring leverages these patterns and learn how to take advantage of them yourself.

Page 4: Going Beyond Dependency Injection

How We’ll Get There 1.  Introduce the concept

2.  Show examples in the Spring Framework

3.  Discuss ways you can take advantage

Page 5: Going Beyond Dependency Injection

Overview of Spring Lifecycle

Page 6: Going Beyond Dependency Injection

XML Configuration Instructions <beans>" <bean id=“transferService” class=“com.acme.TransferServiceImpl”>" <constructor-arg ref=“accountRepository” />" </bean>"" <bean id=“accountRepository” class=“com.acme.JdbcAccountRepository”>" <constructor-arg ref=“dataSource” />" </bean>"" <bean id=“dataSource” class=“org.apache.commons.dbcp.BasicDataSource”>"

" <property name=“driverClassName” value=“org.postgresql.Driver” />"" <property name=“URL” value=“jdbc:postgresql://localhost/transfer” />"" …"

</bean>"</beans>""

Page 7: Going Beyond Dependency Injection

Creating and Using the Application // Create the application from the configuration"ApplicationContext context =" new ClassPathXmlApplicationContext(“application-config.xml”);""// Look up the application service interface"TransferService service = " (TransferService) context.getBean(“transferService”);""// Use the application"service.transfer(new MonetaryAmount(“300.00”), “1”, “2”);""

Page 8: Going Beyond Dependency Injection

Using Java Configuration @Configuration"public class AppConfig {" " @Bean(“transferService)" public TransferService transferService() {"

"TransferService service = new TransferServiceImpl();""service.setRepository(repository());""return service;"

}" " " @Bean ! public AccountRepository repository() {" //..." } "}"

ApplicationContext context = new AnnotationConfigApplicationContext(" " " " AppConfig.class);"

Page 9: Going Beyond Dependency Injection

Lifecycle of a Spring ApplicationContext

•  When a context is created the initialization phase completes

•  But what exactly happens in this phase?

// Create the application from the configuration"ApplicationContext context = new ClassPathXmlApplicationContext(" “application-config.xml”, " “test-infrastructure-config.xml”");"

Page 10: Going Beyond Dependency Injection

Bean Initialization Steps

Bean Ready

For Use

Bean Definitions

Loaded

Post Process Bean

Definitions Instantiate

Beans

Setters Called

Load Bean Definitions

for-each bean ...

BPP BPP Initializer Bean Post Processors

Create and Initialize Beans

BPP BPP

Dependency Injection

Page 11: Going Beyond Dependency Injection

Load Bean Definitions •  The Bean Definitions are read (ex, XML, Annotation or

JavaConfig) •  Bean definitions are loaded into the context’s BeanFactory

–  Each indexed under its id

•  Special BeanFactoryPostProcessor beans are invoked –  Can modify the definition of any bean

Bean Definitions Loaded

Post Process Bean

Definitions Load Bean Definitions

Page 12: Going Beyond Dependency Injection

XML Style Bean Definition Loading

Application Context <beans> <bean id=“transferService” … <bean id=“accountRepository”… </beans>

application-config.xml

<beans> <bean id=“dataSource” … </beans>

test-infrastructure-config.xml transferService accountRepository

BeanFactory

BeanFactoryPostProcessors

postProcess(BeanFactory)

transferService accountRepository dataSource

Can modify the definition of any bean in the factory before any objects are created

Page 13: Going Beyond Dependency Injection

The BeanFactoryPostProcessor •  Useful for applying transformations to groups of bean

definitions –  Before any objects are actually created

•  Several useful implementations are provided by the framework –  You can also write your own –  Implement the BeanFactoryPostProcessor public interface BeanFactoryPostProcessor { public void postProcessBeanFactory (ConfigurableListableBeanFactory beanFactory); }

Page 14: Going Beyond Dependency Injection

A Common Example <beans ...>" <context:property-placeholder location=“db-config.properties” />"" <bean id=“dataSource” class=“com.oracle.jdbc.pool.OracleDataSource”>" <property name=“URL” value=“${dbUrl}” />" <property name=“user” value=“${dbUserName}” />" </bean>"</beans> "

dbUrl=jdbc:oracle:..."dbUserName=moneytransfer-app"

<bean id=“dataSource” class=“com.oracle.jdbc.pool.OracleDataSource”>" <property name=“URL” value=“jdbc:oracle:...” />" <property name=“user” value=“moneytransfer-app” />" </bean>"

Page 15: Going Beyond Dependency Injection

But Where’s The BeanFactoryPostProcessor?

•  The namespace is just an elegant way to hide the corresponding bean declaration

<bean class="org.springframework...PropertySourcesPlaceholderConfigurer"> <property name="location" value="db-config.properties"/>

</bean>

<context:property-placeholder location=“db-config.properties” />

Implements BeanFactoryPostProcessor

PropertySourcesPlaceHolderConfigurer was introduced in Spring 3.1. Prior to that, PropertyPlaceholderConfigurer was used instead

Page 16: Going Beyond Dependency Injection

Instantiation and Initialization

Initializers Called

After Init

Bean Ready

For Use

Bean Definitions

Loaded

Post Process Bean

Definitions Instantiate

Beans

Setters Called

Create Beans Before

Init

Bean Post-Processor(s)

for-each bean

Page 17: Going Beyond Dependency Injection

Bean Post Processing •  There are two types of bean post processors

–  Initializers •  Initialize the bean if instructed •  Activated by init-method or @PostConstruct

–  All the rest! •  Allow for additional richer configuration features •  May run before or after the initialize step

BPP BPP Initializer

Bean Post Processors After Init

Before Init

Page 18: Going Beyond Dependency Injection

BeanPostProcessor: A Closer Look •  An important extension point in Spring

–  Can modify bean instances in any way –  Powerful enabling feature

•  Spring provides many implementations –  Not common to write your own (but you can)

public interface BeanPostProcessor { public Object postProcessAfterInitialization(Object bean, String beanName); public Object postProcessBeforeInitialization(Object bean,String beanName); }

Post-processed bean Original bean

Page 19: Going Beyond Dependency Injection

Commonly Used Bean Post Processors •  Activated by <context:annotation-config> (or <context:component-scan>)

–  CommonAnnotationBeanPostProcessor – Handles JSR-250 common annotations (Ex @PostConstruct)

–  RequiredAnnotationBeanPostProcessor – Enforces @Required annotation semantics

–  AutowiredAnnotationBeanPostProcessor – Enables recognition of @Autowired annotation

–  ConfigurationClassPostProcessor – Enables Java Configuration support •  Others that can be configured manually

–  PersistenceAnnotationBeanPostProcessor – Enables use of @PersistenceContext in JPA DAO classes

–  PersistenceExceptionTranslationPostProcessor – Performs exception translation for classes annotated with @Repository

Page 20: Going Beyond Dependency Injection

Configuration Lifecycle Summary

BeanFacPP

XML config

Annotation config

Bean detection

Bean instantiation and dependency injection BeanPP

@Component scanning

Instantiation & @Autowired

on constructor

Injection of @Autowired

methods & fields

Load xml definitions

Instantiation & constr. injection

Property injection

Java config

Read @Bean method

signatures Call @Bean method implementations

BeanFacPP → BeanFactoryPostProcessor BeanPP → BeanPostProcessor

Page 21: Going Beyond Dependency Injection

Demo Time •  Basic configuration •  Lifecycle

Page 22: Going Beyond Dependency Injection

Reminder: The BeanPostProcessor Phase

Initializers Called

After Init

Bean Ready

For Use

Bean Definitions

Loaded

Post Process Bean

Definitions Instantiate

Beans

Setters Called

Create Beans Before

Init

Bean Post-Processor(s)

for-each bean

Page 23: Going Beyond Dependency Injection

Spring Uses BeanPostProcessors to: •  Perform initialization

–  @PostConstruct annotation enabled by CommonAnnotationBeanPostProcessor

•  Perform validation –  JSR 303 validation enabled by BeanValidationPostProcessor

•  Add behavior –  @Async annotation enabled by

AsyncAnnotationBeanPostProcessor

Page 24: Going Beyond Dependency Injection

Writing a Custom BeanPostProcessor •  Problem: Spring MVC provides several ExceptionResolver

strategies enabled by default. Processing order is pre-defined. How do I change the order?

•  Solution: 1.  Manually configure the 3 resolvers and set the order

property 2.  Use a custom BeanPostProcessor to set the order

Page 25: Going Beyond Dependency Injection

Pre-configured Exception Resolvers <mvc:annotation-driven /> ""<!-- With this configuration, three ExceptionResolvers are registered:" ExceptionHandlerExceptionResolver – ExceptionResolver for @Exception annotated methods" ResponseStatusExceptionResolver – ExceptionResolver enabling @ResponseStatus mappings" DefaultHandlerExceptionResolver – ExceptionResolver for mapping exceptions to HTTP status codes"-->""

•  Three ExceptionResolvers are automatically registered •  Order they are consulted by DispatcherServlet is pre-defined •  What if you wanted to change the order?

Page 26: Going Beyond Dependency Injection

Implementing a BeanPostProcessor class ExceptionMappingBeanPostProcessor {" // Use this field to hold the list of resolvers by name and their desired order" private Properties exceptionResolvers; !" // Implement appropriate getter & setter "! public Object postProcessBeforeInitialization(Object bean, String beanName)"

" " "throws BeansException {" // Check if bean is an instance of ExceptionResolver" // If so, look to see if an order has been defined and assign" // Return the modified bean" "" }"}""

Page 27: Going Beyond Dependency Injection

Custom BeanPostProcessor Configuration <mvc:annotation-driven /> ""<bean class="com.pivotal.springone.gbdi.ExceptionResolverOrderPostProcessor">! <property name="exceptionResolvers">! <value>"

"ExceptionHandlerExceptionResolver=2!"ResponseStatusExceptionResolver=3!"DefaultHandlerExceptionResolver=1!

</value>" </property>"</bean>""

Page 28: Going Beyond Dependency Injection

Demo Time •  Spring MVC application with default ExceptionResolver

order •  Using a custom BeanPostProcessor

Page 29: Going Beyond Dependency Injection

Additional Patterns Used in Spring Framework

•  Programming to Interfaces •  Proxies and AOP •  Templates

Page 30: Going Beyond Dependency Injection

Programming to Interfaces

Page 31: Going Beyond Dependency Injection

Example: Programming to Interfaces

public class TransferServiceImpl implements TransferService { private AccountRepository accountRepository; public void setAccountRepository(AccountRepository ar) { accountRepository = ar; } … }

public class JdbcAccountRepository implements AccountRepository {" …"}"

Depends on service interface; conceals complexity of implementation; allows for swapping out implementation

Implements a service interface

Page 32: Going Beyond Dependency Injection

Benefits of Programming to Interfaces •  Loose Coupling

–  Enables a more pluggable architecture –  Provide out of the box components but support for user provided

implementations •  Improved Reuse

–  A component can often be used wherever interface is expected –  Write once, use multiple places

•  Improved Testability –  Ease of swapping a stub implementation for unit testing

Page 33: Going Beyond Dependency Injection

Swapping out Implementations #1

For Jdbc

TransferServiceImpl

JdbcAccountRepository

Spring

(1) new JdbcAccountRepository(…); (2) new TransferServiceImpl(); (3) service.setAccountRepository(repository);

Page 34: Going Beyond Dependency Injection

Swapping Out Implementations #2

TransferServiceImpl

JpaAccountRepository

(1) new JpaAccountRepository(…); (2) new TransferServiceImpl(); (3) service.setAccountRepository(repository);

For Jpa

Spring

Page 35: Going Beyond Dependency Injection

Swapping Out Implementations #3

TransferServiceImpl

StubAccountRepository

(1) new StubAccountRepository(); (2) new TransferServiceImpl(); (3) service.setAccountRepository(repository);

For Unit Testing

Page 36: Going Beyond Dependency Injection

Interfaces and Spring ApplicationContext // Create the application from the configuration"ApplicationContext context =" new ClassPathXmlApplicationContext(“application-config.xml”);""// Fetch a list of bean names of type BeanPostProcessor"String[] beanNamesOfType = " context.getBeanNamesForType(BeanPostProcessor.class);""// Fetch a list of beans of type BeanPostProcessor"Map<String,HandlerExceptionResolver> beansOfType = " context.getBeansOfType(HandlerExceptionResolver.class);""

BeanFactoryUtils provides ability to search nested definitions and ancestor BeanFactory

Page 37: Going Beyond Dependency Injection

Programming to Interfaces in Spring •  Core Spring

–  BeanPostProcessor –  BeanFactoryPostProcessor –  PlatformTransactionManager –  Spring remoting (ex RmiProxyFactoryBean, HttpInvokerProxyFactoryBean)

•  Spring MVC –  ViewResolver –  HandlerMapping –  ExceptionResolver (we’ve already seen this one)

•  Spring Security –  AuthenticationManager –  FilterChain

Page 38: Going Beyond Dependency Injection

Spring Security – the Big Picture

Security Context

Authentication

(Principal + Authorities)

Secured Resource

Authentication Manager

populates

thread of execution

obtains

AccessDecision Manager

delegates

Config Attributes

describes

consults protects Security Interceptor

Voters

polls

Page 39: Going Beyond Dependency Injection

Web Security Filter Configuration

Web User

Servlet

Servlet Container

Spring ApplicationContext

Filter 2

Filter N

DelegatingFilterProxy

FilterChainProxy

Filter 1

Page 40: Going Beyond Dependency Injection

Looking at Spring Security <!-- Define the appropriate security namespace and prefix -->"<beans>" <!-- Registers a chain of filters including FilterChainProxy -->" <security:http>" …" </security:http>"" " <!-- Registers the appropriate AuthenticationManager and supporting classes-->" <security:authentication-manager>" <security:authentication-provider>" <security:jdbc-user-service data-source-ref=“dataSource” />" </security:authentication-provider>" </security:authentication-manager>"</beans>""

Page 41: Going Beyond Dependency Injection

Customizing the Authentication Process

Easy Customization

Page 42: Going Beyond Dependency Injection

The UserDetails Interface •  Interface defines required properties •  Implementation can add additional properties

public interface UserDetails extends Serializable {" Collection<? extends GrantedAuthority> getAuthorities();" String getPassword();" String getUsername();" boolean isAccountNonExpired();" boolean isAccountNonLocked();" boolean isCredentialsNonExpired();" boolean isEnabled();"}"

Page 43: Going Beyond Dependency Injection

The UserDetailsService Interface •  Interface defines the contract

•  Implementation is free to use any approach to satisfy the request –  Read from file –  JDBC Database calls –  Hibernate/JPA/MyBatis, etc

•  All the hard work happens here

public interface UserDetailsService { " UserDetails loadUserByUsername(String username) " throws UsernameNotFoundException;"}"

Page 44: Going Beyond Dependency Injection

Configuring Custom Authentication •  Configure custom UserDetailsService implementation as a

Spring bean •  Configure AuthenticationProvider to reference it

<!-- Can also be discovered through component scanning -->"<bean id="userDetailsService" class="CustomUserDetailsService” ! p:dataSource-ref=”dataSource” />"<security:authentication-manager>" <security:authentication-provider " user-service-ref="userDetailsService" />"</security:authentication-manager>"

Page 45: Going Beyond Dependency Injection

Demo Time •  Implementing custom UserDetails and UserDetailsService

Page 46: Going Beyond Dependency Injection

Proxy Power

Page 47: Going Beyond Dependency Injection

What is a Proxy? •  A stand-in for the real object

•  Takes full advantage of Programming to Interfaces

Page 48: Going Beyond Dependency Injection

Proxy Usage in Spring •  FactoryBeans

–  RmiProxyFactoryBean –  MBeanProxyFactoryBean –  HttpInvokerProxyFactoryBean

•  Spring AOP –  Proxy style weaving using proxies

•  Transactions –  Really just implemented using Spring AOP mechanisms

•  Spring Data –  Exposed via special repository FactoryBean classes

Page 49: Going Beyond Dependency Injection

Remoting and the ProxyFactoryBean •  Dynamic proxies generated by Spring communicate with remote

objects •  Simpler to use than traditional RMI stub •  Provides RMI marshalling/unmarshalling + Exception conversion

Page 50: Going Beyond Dependency Injection

Basic ProxyFactoryBean Usage •  Define a factory bean to generate proxy

•  Inject it into the client

<bean id=“transferService” class=“org.springframework.remoting.rmi.RmiProxyFactoryBean”> <property name=“serviceInterface” value=“app.TransferService”/> <property name=“serviceUrl” value=“rmi://foo:1099/transferService”/> </bean>

<bean id=“tellerDesktopUI” class=“app.TellerDesktopUI”> <property name=“transferService” ref=“transferService”/> </bean>

TellerDesktopUI only depends on the TransferService interface

Page 51: Going Beyond Dependency Injection

Spring AOP in a Nutshell •  Extract cross-cutting concerns into a module that can be

‘woven’ into core functionality before application execution •  Modules

–  AspectJ uses a separate syntax –  AspectJ also supports annotations on Java classes –  Spring AOP leverages AspectJ annotation style

•  Weaving –  Compile-time weaving (AspectJ) –  Load-time weaving (AspectJ) –  Proxy-based weaving (Spring AOP)

Page 52: Going Beyond Dependency Injection

A Simple AOP Logging Example

public class SimpleCache implements Cache { private int cacheSize; private DataSource dataSource; public void setCacheSize(int size) { cacheSize = size; } public void setDataSource(DataSource ds) { dataSource = ds; } }

public interface Cache {" public void setCacheSize(int size);"}"

Page 53: Going Beyond Dependency Injection

An AOP Example

"public class PropertyChangeTracker {" private Logger logger = Logger.getLogger(getClass());"" " public void trackChange() {" logger.info(“Property about to change…”); " }"}"

@Aspect

@Before(“execution(void set*(*))”)

•  Implemented as a simple Java class… with annotations

•  … and some additional Spring configuration

Page 54: Going Beyond Dependency Injection

Spring AOP Configuraiton

<beans>" <aop:aspectj-autoproxy>" <aop:include name=“propertyChangeTracker” />" </aop:aspectj-autoproxy>"" <bean id=“propertyChangeTracker” class=“example.PropertyChangeTracker” />"</beans>"

Configures Spring to apply the @Aspect to your beans

aspects-config.xml

@Configuration"@EnableAspectJAutoProxy"public class AspectConfig {" @Bean(name=”propertyChangeTracker”)" public PropertyChangeTracker tracker() {" return new PropertyChangeTracker();" }"}" Using Java

Using XML

AspectConfig.java

Page 55: Going Beyond Dependency Injection

How Aspects are Applied

<<interface>> Cache

setCacheSize()

2. Proxy implements target interface(s)

setCacheSize(2500)

PropertyChange Tracker (aspect)

Simple Cache

Spring AOP Proxy (this)

1. Spring creates a proxy 'weaving' aspect & target

4. Matching advice is executed

5. Target method is executed

Method Interceptor

3. All calls routed through proxy interceptor

Target  

Page 56: Going Beyond Dependency Injection

JDK vs CGLib Proxies

•  JDK Proxy –  Interface based

SimpleCache Extra Logic

Spring Proxy

Cache

SimpleCache Extra Logic

Spring Proxy

SimpleCache

•  CGLib Proxy –  subclass based

Target   Target  

extends implements implements

Page 57: Going Beyond Dependency Injection

Selecting the Target Methods •  Pointcut Expression

–  An expression used to select the target methods to intercept with AOP functionality

•  Examples

execution(* rewards.*.restaurant.*.*(..)) –  Any methods on any class in a package with one directory

between rewards and restaurant

execution(void send*(String)) –  Any method starting with send that takes a single String

parameter and has a void return type

execution(@javax.annotation.security.RolesAllowed void send*(..)) –  Any void method starting with send that is annotated

with the @RolesAllowed annotation

Page 58: Going Beyond Dependency Injection

Spring Transactions in a Nutshell •  In the code

•  In the configuration

public class RewardNetworkImpl implements RewardNetwork {" @Transactional" public RewardConfirmation rewardAccountFor(Dining d) {" // atomic unit-of-work " }"}"

<tx:annotation-driven/> <bean id=“transactionManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”> <property name=“dataSource” ref=“dataSource”/> </bean> <jdbc:embedded-database id="dataSource"> … </jdbc:embedded-database>

Defines a BeanPostProcessor -proxies @Transactional beans

Page 59: Going Beyond Dependency Injection

How the Proxy Works •  A BeanPostProcessor may wrap your

beans in a dynamic proxy –  adds behavior to your application

logic transparently

Page 60: Going Beyond Dependency Injection

Giving Meaning to Your Annotations •  Problem: I want to selectively audit certain operations

within my application using a marker such as an annotation

•  Solution: 1.  Create an annotation to act as a marker 2.  Define AOP before advice to capture desired information 3.  Write a pointcut expression to select & apply advice

Page 61: Going Beyond Dependency Injection

The Target Class public class JpaOrderRepository implements OrderRepository { "" public Order findByOrderId(long id) {" …" }"" @Auditable" public Order save(Order entity) {" ..." }"" @Auditable" public void delete(Order entity) {" ..." }"}"

public @interface Auditable {" // Just a simple interface definition – nothing else required"}"

Mark these methods as candidates to audit

Page 62: Going Beyond Dependency Injection

The Advice & Pointcut Expression @Aspect"@Component"public class AuditingAdvice {! private Logger logger = Logger.getLogger(getClass());!" @Before("execution(@com.pivotal.springone.gbdi.Auditable * *(..))")" public void doAudit(JoinPoint jp) {!

"Object target = jp.getTarget();""logger.info("Audit on " + target.getClass().getSimpleName() + " for method " +

jp.getSignature().getName());" }"}"

Match all methods annotated with @Auditable

Page 63: Going Beyond Dependency Injection

The Configuration

<aop:aspectj-autoproxy> <aop:include name=“auditingAdvice” </aop:aspectj-autoproxy> <bean id=“auditingAdvice” class=”com.pivotal.springone.AuditingAdvice” />

@Configuration "@EnableAspectJAutoProxy!public class AppConfig {" @Bean" public AuditingAdvice auditingAdvice() {" // Return instantiated and configured AuditingAdvice instance" }"}"

•  Using XML

•  Using JavaConfig

Page 64: Going Beyond Dependency Injection

Demo Time •  Creating and using @Auditable with Spring AOP

Page 65: Going Beyond Dependency Injection

Templates

Page 66: Going Beyond Dependency Injection

Templates in Spring •  Objective

–  Define the outline or skeleton of an algorithm –  Hide away large amounts of boilerplate code

•  Accomplished by –  Providing convenience functions for simplified usage –  Providing Callback classes to expose specific processing

ability

Page 67: Going Beyond Dependency Injection

Examples of Templates in Spring •  Core Spring

–  JdbcTemplate –  JmsTemplate –  RestTemplate

•  Spring Data –  GemfireTemplate –  JpaTemplate –  RedisTemplate –  PigTemplate

•  Others –  WebServiceTemplate (Spring Web Services) –  RabbitTemplate (Spring AMQP)

Page 68: Going Beyond Dependency Injection

JdbcTemplate Example – convenience functions

•  Acquisition of the connection •  Participation in the transaction •  Execution of the statement •  Processing of the result set •  Handling any exceptions •  Release of the connection

•  Constructed with a JDBC DataSource

int count = template.queryForObject( “SELECT COUNT(*) FROM CUSTOMER”, Integer.class);

All handled by Spring

JdbcTemplate template = new JdbcTemplate(dataSource);

Page 69: Going Beyond Dependency Injection

JdbcTemplate With a Callback Class

List results = jdbcTemplate.query(someSql, new RowMapper<Customer>() { public Customer mapRow(ResultSet rs, int row) throws SQLException { // map the current row to a Customer object } });

class JdbcTemplate { public List<Customer> query(String sql, RowMapper rowMapper) { try { // acquire connection // prepare statement // execute statement // for each row in the result set results.add(rowMapper.mapRow(rs, rowNumber)); return results; } catch (SQLException e) { // convert to root cause exception } finally { // release connection

} }

Page 70: Going Beyond Dependency Injection

Summary of Callback Interfaces

•  RowMapper –  Best choice when each row of a ResultSet maps to a domain

object •  ResultSetExtractor

–  Best choice when multiple rows of a ResultSet map to a single object

•  RowCallbackHandler –  Best choice when no value should be returned from the

callback method for each row

Page 71: Going Beyond Dependency Injection

Demo Time •  Review ResultSetExtractor usage for customized

UserDetailsService demo

Page 72: Going Beyond Dependency Injection

Conclusion

Page 73: Going Beyond Dependency Injection

In Summary •  Spring is MUCH more than just dependency injection •  Dependency Injection does provide centralized lifecycle, which

enables an easy way add and modify objects uniformly •  Some patterns used by Spring that you can also leverage

–  Programming to Interfaces Enhanced reuse, lose coupling, improved testability

–  Creating and using Proxies Adding incredible power declaratively to your Spring apps

–  Templates Hiding the boilerplate and exposing only what’s necessary

Page 74: Going Beyond Dependency Injection

Spring Stack

DI AOP TX JMS JDBC

MVC Testing

ORM OXM Scheduling

JMX REST Caching Profiles Expression

Spring Framework

HATEOAS

JPA 2.0 JSF 2.0 JSR-250 JSR-330 JSR-303 JTA JDBC 4.1

Java EE 1.4+/SE5+

JMX 1.0+ WebSphere 6.1+

WebLogic 9+

GlassFish 2.1+

Tomcat 5+

OpenShift

Google App Eng.

Heroku

AWS Beanstalk

Cloud Foundry Spring Web Flow Spring Security

Spring Batch Spring Integration

Spring Security OAuth

Spring Social

Twitter LinkedIn Facebook

Spring Web Services

Spring AMQP

Spring Data

Redis HBase

MongoDB JDBC

JPA QueryDSL

Neo4j

GemFire

Solr Splunk

HDFS MapReduce Hive

Pig Cascading

Spring for Apache Hadoop

SI/Batch

Spring XD

Page 75: Going Beyond Dependency Injection

Learn More. Stay Connected.

•  [email protected]

•  Talk to us on Twitter: @springcentral •  Find Session replays on YouTube: spring.io/video