spring framework 4.1

73
Spring Framework 4.1 Sam Brannen @sam_brannen

Upload: sam-brannen

Post on 17-Jul-2015

471 views

Category:

Software


2 download

TRANSCRIPT

Page 1: Spring Framework 4.1

Spring Framework 4.1

Sam Brannen @sam_brannen

Page 2: Spring Framework 4.1

Sam Brannen •  Spring and Java Consultant @ Swiftmind •  Java Developer for over 15 years

•  Spring Framework Core Committer since 2007 •  Component lead for spring-test

•  Spring Trainer •  Speaker on Spring, Java, and testing

•  Swiss Spring User Group Lead

2

Page 3: Spring Framework 4.1

Areas of expertise –  Spring * –  Java EE –  Software Architecture –  Software Engineering Best

Practices

Where you find us •  Zurich, Switzerland •  @swiftmind •  http://www.swiftmind.com

3

Your experts for Spring & Enterprise Java

Page 4: Spring Framework 4.1

A show of hands…

4

?

? ?

?

?

?

Page 5: Spring Framework 4.1

Agenda •  Container enhancements •  Caching •  JMS •  Spring MVC •  Testing •  Q&A

5

Page 6: Spring Framework 4.1

Container Enhancements

6

Page 7: Spring Framework 4.1

Enhancements in 4.1 •  java.util.Optional

•  Dependency injection •  MVC method arguments

•  @Order on @Bean methods •  Injecting ordered lists

•  @Priority (javax.annotation) •  Ordering •  Primary candidate selection

•  SpEL compiler •  Modes: off, immediate, mixed •  System / Spring property: spring.expression.compiler.mode

7

Page 8: Spring Framework 4.1

Injection point with required flag @Servicepublic class MyService {

@Autowired(required=false) NotificationService notificationService;

public Book findBook(long id) { if (notificationService != null) { /* ... */ } }}

8

before

Page 9: Spring Framework 4.1

Injection point with java.util.Optional @Servicepublic class MyService {

@Autowired Optional<NotificationService> notificationService;

public Book findBook(long id) { notificationService.ifPresent(service -> /* ... */ ); }}

9

after

Page 10: Spring Framework 4.1

@Order on Components (4.0) @Service @Order(1)public class ServiceA implements MyService { /* ... */ }

@Service @Order(2)public class ServiceB implements MyService { /* ... */ }

@AutowiredList<MyService> myServices;

10

ServiceA is 1st

Page 11: Spring Framework 4.1

@Order on @Bean Methods (4.1) @Bean @Order(1)public MyService serviceA() { return new ServiceA(); }

@Bean @Order(2)public MyService serviceB() { return new ServiceB(); }

@AutowiredList<MyService> myServices;

11

ServiceA is 1st

Page 12: Spring Framework 4.1

Caching

12

Page 13: Spring Framework 4.1

New Caching Features •  @CacheConfig

•  common class-level configuration

•  CacheResolver •  fine grained, programmatic cache resolution

•  JCache (JSR-107)

•  New putIfAbsent() method in Cache API

13

Page 14: Spring Framework 4.1

Review: Spring Caching API

14

“books” cache name is duplicated everywhere. L

Page 15: Spring Framework 4.1

@CacheConfig

15

“books” cache name is declared only once! J

Page 16: Spring Framework 4.1

CacheResolver API

16

•  getOperation() •  getTarget() •  getMethod() •  getArgs()

Page 17: Spring Framework 4.1

JCache (JSR 107) and Spring •  JCache 1.0 annotations now supported in Spring

•  Integration based on Spring’s own Cache and CacheManager APIs •  JCacheCache and JCacheCacheManager

•  Enabled via Spring’s standard mechanisms: •  XML: <cache:annotation-driven />•  Java: @EnableCaching

•  Cache Abstraction: JCache (JSR-107) Annotations Support •  https://spring.io/blog/2014/04/14/cache-abstraction-jcache-jsr-107-annotations-support

17

Page 18: Spring Framework 4.1

JCache Annotations Support

18

Page 19: Spring Framework 4.1

Caching Annotations Comparison

19

Spring JCache @Cacheable @CacheResult@CachePut @CachePut@CacheEvict @CacheRemove@CacheEvict(allEntries=true) @CacheRemoveAll

Page 20: Spring Framework 4.1

JMS

20

Page 21: Spring Framework 4.1

JMS Overhaul •  Alignment with spring-messaging module

•  Annotation-driven endpoints •  Analogous to <jms:listener-container /> •  Listener methods declared via @JmsListener•  Configured via:

o  XML: <jms:annotation-driven />o  Java: @EnableJms and JmsListenerConfigurer

21

Page 22: Spring Framework 4.1

Review: Spring JMS Config in XML

22

Page 23: Spring Framework 4.1

Annotated JMS Endpoints

23

Page 24: Spring Framework 4.1

Flexible Method Signatures

24

Page 25: Spring Framework 4.1

Transition from existing XML config…

25

Page 26: Spring Framework 4.1

… or remove XML altogether

26

Page 27: Spring Framework 4.1

Spring MVC

27

Page 28: Spring Framework 4.1

ResponseBodyAdvice •  Callback for @ResponseBody / ResponseEntity methods

•  just before the response is written (and committed) •  you can still modify headers •  or the object to be written to the response

•  Two implementations already •  JsonViewResponseBodyAdvice •  AbstractJsonpResponseBodyAdvice

28

Page 29: Spring Framework 4.1

Jackson @JsonView Support interface PublicView {}

class User {

@JsonView(PublicView.class) String username;

String password;

// ...}

29

@RestControllerclass UserController {

@RequestMapping("/user") @JsonView(PublicView.class) public User getUser() { return new User("eric", "7!#H2"); }}

Page 30: Spring Framework 4.1

JSONP Support •  Simply declare as a Spring-managed component…

@ControllerAdviceclass JsonpAdvice extends AbstractJsonpResponseBodyAdvice {

public JsonpAdvice() { super("callback"); }}

30

Name of JSONP query param(s)

Page 31: Spring Framework 4.1

HttpMessageConverter Additions •  Gson

•  lighter footprint (vs Jackson); used in Spring Android

•  Google Protocol Buffers •  effective inter-service communication data protocol

•  Jackson / XML •  just add jackson-dataformat-xml to the classpath

31

Page 32: Spring Framework 4.1

Static Resource Handling in Web MVC •  ResourceTransformer API

•  Transforms the content of a resource

•  ResourceResolver API for resolving: •  Internal static resources •  External resource paths (i.e., links)

•  ResourceResolverChain •  Maintains a chain of resolvers •  Allowing for delegation

•  Configured via ResourceHandlerRegistry•  For example, via WebMvcConfigurationSupport

32

Page 33: Spring Framework 4.1

ResourceResolver Implementations •  PathResourceResolver

•  simple path lookup under configured locations

•  VersionResourceResolver •  resolution with version in URL path

•  GzipResourceResolver •  lookup with .gz extension when “Accept-Encoding: gzip”

•  CachingResourceResolver •  caching of resolved resource

33

Page 34: Spring Framework 4.1

ResourceTransformer Implementations •  CssLinkResourceTransformer

•  update links in CSS file (e.g. insert version)

•  AppCacheManifestTransformer •  update links in HTML5 AppCache manifest •  insert comment with content-based hash

•  CachingResourceTransformer •  caching of transformed resource

34

Page 35: Spring Framework 4.1

Ex: Fingerprinting URLs w/ content-based version boolean useResourceCache = !this.environment.acceptsProfiles("dev");

VersionResourceResolver resolver = new VersionResourceResolver();resolver.addContentVersionStrategy("/**");

registry.addResourceHandler("/**").addResourceLocations(locations) .resourceChain(useResourceCache).addResolver(resolver);

Example URL: “/css/font-awesome.min-7fbe76cdac.css”

35

Page 36: Spring Framework 4.1

Additional New Features in Spring MVC •  Groovy markup templates •  Declarative MVC view resolution •  Enhanced view controllers •  Linking to @RequestMapping methods

•  See HandlerMethodMappingNamingStrategy

•  ListenableFuture return type for handler methods •  ResponseEntity Builder API •  RequestEntity & RestTemplate.exchange()

36

Page 37: Spring Framework 4.1

Testing

37

Page 38: Spring Framework 4.1

Bootstrap Strategy & TestExecutionListeners •  TestContext bootstrap strategy

•  TestContextBootstrapper & @BootstrapWith

•  Automatic discovery of default TestExecutionListeners •  Uses SpringFactoriesLoader •  Already used by Spring Security

•  Merging custom TestExecutionListeners with defaults •  @TestExecutionListeners(mergeMode=MERGE_WITH_DEFAULTS) •  Defaults to REPLACE_DEFAULTS

38

Page 39: Spring Framework 4.1

Spring MVC Test •  Assert JSON responses with JSON Assert

•  Complements JSONPath support

•  Create MockMvcBuilder recipes with MockMvcConfigurer •  Developed to apply Spring Security setup but can be used by anyone

•  AsyncRestTemplate support in MockRestServiceServer •  For asynchronous client-side testing

39

Page 40: Spring Framework 4.1

Groovy Beans in Spring •  Spring Framework 4.0 introduced support for the Groovy Bean

Definition DSL via the GroovyBeanDefinitionReader and GenericGroovyApplicationContext

•  Spring Framework 4.1 introduces support for Groovy scripts in web applications via the GroovyWebApplicationContext

•  Testing support added in 4.1…

40

Page 41: Spring Framework 4.1

Groovy Scripts for Context Config in Tests •  Spring Framework 4.1 introduces support for Groovy scripts in

integration tests via @ContextConfiguration •  Scripts are configured via the locations or value attribute

o  Resource semantics identical to XML o  Default detected with “Context.groovy” suffix in same package

•  The inheritLocations flag is fully supported

•  Groovy and XML configuration can be declared together

•  Groovy WebApplicationContexts supported via @WebAppConfiguration

41

Page 42: Spring Framework 4.1

Ex: Groovy Script Config @RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("/context.groovy")public class GroovyPersonTests {

@Autowired private Person person;

/* test methods using person bean */}

42

Page 43: Spring Framework 4.1

Ex: Default Groovy Script Detection public com.example;

@RunWith(SpringJUnit4ClassRunner.class)// ApplicationContext will be loaded from// “classpath:com/example/MyTestContext.groovy”@ContextConfigurationpublic class MyTest { /* ... */}

43

Page 44: Spring Framework 4.1

Ex: Groovy & XML Config Together @RunWith(SpringJUnit4ClassRunner.class)// ApplicationContext will be loaded from// “/context.groovy” and “/context.xml”@ContextConfiguration({ "/context.groovy", "/context.xml" })public class MyTest { /* ... */}

44

Page 45: Spring Framework 4.1

Test Property Sources •  Spring 3.1 introduced PropertySources abstraction

•  Configured via Environment or via @PropertySource

•  Spring 4.1 supports declarative test property sources •  Configured via @TestPropertySource

•  Test property sources are declared via annotation attributes •  locations or value: resource locations •  properties: inlined properties •  both are inherited by default

45

Page 46: Spring Framework 4.1

@TestPropertySource – locations •  String array of resource locations for Java Properties files

•  Both traditional *.properties and XML formats are supported

•  Resource semantics are identical to those for locations in @ContextConfiguration

46

Page 47: Spring Framework 4.1

Ex: @TestPropertySource – locations @ContextConfiguration@TestPropertySource("/test.properties")public class MyIntegrationTests {

// class body...}

47

Page 48: Spring Framework 4.1

@TestPropertySource – properties •  Inlined properties can be declared as key/value pairs

•  Uses syntax for entries in Java properties files: •  "key=value" •  "key:value" •  "key value"

48

Page 49: Spring Framework 4.1

Ex: @TestPropertySource – properties @ContextConfiguration@TestPropertySource( properties = {"foo=bar", "port: 4242"})public class MyIntegrationTests {

// class body...}

49

Page 50: Spring Framework 4.1

Default Properties File Detection •  If neither locations nor properties are defined, a default properties

file will be detected

•  Default is detected with “.properties” suffix in same package

•  If the class is com.example.MyTest, the default properties file is “classpath:com/example/MyTest.properties”

•  Exception is thrown if default is not present

50

Page 51: Spring Framework 4.1

@TestPropertySource – Precedence

51

Inlined

Files

Application & System

test

prec

eden

ce

Page 52: Spring Framework 4.1

Ex: @TestPropertySource – locations & properties @ContextConfiguration@TestPropertySource( locations = "/test.properties", properties = "port: 4242")public class MyIntegrationTests {

// class body...}

52

Page 53: Spring Framework 4.1

Programmatic Transaction Management in Tests •  History Lesson: Spring’s JUnit 3.8 testing framework supported

endTransaction() and startNewTransaction() methods in AbstractTransactionalSpringContextTests

•  But… the Spring TestContext Framework, introduced in Spring 2.5, did not… until now

•  Due to popular demand, Spring 4.1 introduces a new TestTransaction API

53

Page 54: Spring Framework 4.1

Transactions in Spring •  Spring-managed transactions: managed by Spring in the

ApplicationContext •  @Transactional and AOP

•  Application-managed transactions: managed programmatically within application code

•  TransactionTemplate and TransactionSynchronizationManager

•  Test-managed transactions: managed by the Spring TestContext Framework

•  @Transactional on test classes and test methods •  Transaction is rolled back by default!

54

Page 55: Spring Framework 4.1

Ex: Declarative Transaction Management in Tests @RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration@Transactionalpublic class TransactionalTests {

@Test public void withinTransaction() { /* ... */ }

55

What if we want to stop & start the

transaction within the test method?

Page 56: Spring Framework 4.1

TestTransaction API •  Static methods for interacting with test-managed transactions

•  isActive() •  isFlaggedForRollback()

•  flagForCommit() •  flagForRollback()

•  end() •  start()

56

query status

change default rollback setting

end: roll back or commit based on flag start: new tx with default rollback setting

Page 57: Spring Framework 4.1

Ex: Programmatic Tx Management in Tests @Testpublic void withinTransaction() { // assert initial state in test database: assertNumUsers(2);

deleteFromTables("user");

// changes to the database will be committed TestTransaction.flagForCommit(); TestTransaction.end(); assertFalse(TestTransaction.isActive()); assertNumUsers(0);

TestTransaction.start(); // perform other actions against the database that will // be automatically rolled back after the test completes...}

57

Page 58: Spring Framework 4.1

Executing SQL Scripts

58

Page 59: Spring Framework 4.1

Ex: Embedded Database in Java Config

59

@Beanpublic DataSource dataSource() { return new EmbeddedDatabaseBuilder() .setType(H2) .setScriptEncoding("UTF-8") .ignoreFailedDrops(true) .addScript("schema.sql") .addScripts("user_data.sql", "country_data.sql") .build();}

API greatly improved in Spring 4.0.3

Page 60: Spring Framework 4.1

Ex: Embedded Database in XML Config <jdbc:embedded-database id="dataSource" type="H2"> <jdbc:script location="classpath:/schema.sql" /> <jdbc:script location="classpath:/user_data.sql" /></jdbc:embedded-database>

60

Page 61: Spring Framework 4.1

Ex: Populate Database in XML Config <jdbc:initialize-database data-source="dataSource"> <jdbc:script location="classpath:/schema_01.sql" /> <jdbc:script location="classpath:/schema_02.sql" /> <jdbc:script location="classpath:/data_01.sql" /> <jdbc:script location="classpath:/data_02.sql" /></jdbc:initialize-database>

61

Page 62: Spring Framework 4.1

Executing SQL per Test Method •  The previous techniques are very useful for setting up the initial

database state

•  Q: But how can we execute SQL scripts per test method? •  A: Programmatically via ScriptUtils,

ResourceDatabasePopulator, or abstract transactional base test classes for JUnit and TestNG.

•  Q: OK, but how can we do that declaratively? •  A: Via @Sql in Spring Framework 4.1!

62

Page 63: Spring Framework 4.1

Executing SQL Scripts Declaratively with @Sql •  @Sql: declared on a test class or test method

•  method-level overrides class-level

•  The scripts attribute is used to declare resource locations for SQL scripts

•  semantics analogous to locations in @ContextConfiguration

•  Scripts can be executed before or after a test method •  configured via the executionPhase attribute of @Sql

63

Page 64: Spring Framework 4.1

Ex: @Sql in Action @ContextConfiguration@Sql({ "schema1.sql", "data1.sql" })public class SqlScriptsTests {

@Test public void classLevelScripts() { /* ... */ }

@Test @Sql({ "schema2.sql", "data2.sql" }) public void methodLevelScripts() { /* ... */ }

64

Page 65: Spring Framework 4.1

Default SQL Script Detection •  If no scripts are declared, a default script will be detected

•  Depending on where @Sql is declared

•  Class-level: for com.example.DbTest, the default is “classpath:com/example/DbTest.sql”

•  Method-level: for com.example.DbTest.test(), the default is “classpath:com/example/DbTest.test.sql”

•  If the default is not present, an exception is thrown

65

Page 66: Spring Framework 4.1

Declaring Multiple @Sql Sets •  Declare multiple sets of @Sql scripts for varying configuration

•  Java 8: use @Sql as a repeatable annotation

•  Java 6 & 7: wrap @Sql sets in @SqlGroup

66

Page 67: Spring Framework 4.1

@Sql as a Repeatable Annotation (Java 8)

67

@Test@Sql( scripts="/test-schema.sql", config = @SqlConfig(commentPrefix = "`")@Sql("/user-data.sql")public void userTest() { // code that uses the test schema and test data}

Schema uses custom syntax

Page 68: Spring Framework 4.1

@Sql wrapped in @SqlGroup (Java 6 & 7)

68

@Test@SqlGroup({ @Sql( scripts="/test-schema.sql", config = @SqlConfig(commentPrefix = "`"), @Sql("/user-data.sql")})public void userTest() { // code that uses the test schema and test data}

Page 69: Spring Framework 4.1

Configuring SQL Scripts with @SqlConfig •  @SqlConfig: configures script parsing and error handling

•  Class-level: serves as global configuration for the test class •  @Sql(config): serves as local configuration for the enclosing @Sql

•  Local configuration inherits global configuration and can selectively override global configuration

•  Transaction management for script execution is configured via the dataSource, transactionManager, and transactionMode attributes

•  See Javadoc and reference manual for details

69

Page 70: Spring Framework 4.1

In closing…

70

Page 71: Spring Framework 4.1

Spring Resources

Spring Framework: http://projects.spring.io/spring-framework Spring Guides: http://spring.io/guides Spring JIRA: https://jira.spring.io

Spring on GitHub: https://github.com/spring-projects/spring-framework Stack Overflow: spring, spring-test, spring-mvc, …

71

Page 72: Spring Framework 4.1

Blogs Spring Blog: http://spring.io/blog Swiftmind Blog: http://www.swiftmind.com/blog

72

Page 73: Spring Framework 4.1

Q & A Sam Brannen

@sam_brannen

www.slideshare.net/sbrannen

www.swiftmind.com

73

@springcentral spring.io/video