spring framework 4.1
Post on 17-Jul-2015
471 Views
Preview:
TRANSCRIPT
Spring Framework 4.1
Sam Brannen @sam_brannen
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
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
A show of hands…
4
?
? ?
?
?
?
Agenda • Container enhancements • Caching • JMS • Spring MVC • Testing • Q&A
5
Container Enhancements
6
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
Injection point with required flag @Servicepublic class MyService {
@Autowired(required=false) NotificationService notificationService;
public Book findBook(long id) { if (notificationService != null) { /* ... */ } }}
8
before
Injection point with java.util.Optional @Servicepublic class MyService {
@Autowired Optional<NotificationService> notificationService;
public Book findBook(long id) { notificationService.ifPresent(service -> /* ... */ ); }}
9
after
@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
@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
Caching
12
New Caching Features • @CacheConfig
• common class-level configuration
• CacheResolver • fine grained, programmatic cache resolution
• JCache (JSR-107)
• New putIfAbsent() method in Cache API
13
Review: Spring Caching API
14
“books” cache name is duplicated everywhere. L
@CacheConfig
15
“books” cache name is declared only once! J
CacheResolver API
16
• getOperation() • getTarget() • getMethod() • getArgs()
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
JCache Annotations Support
18
Caching Annotations Comparison
19
Spring JCache @Cacheable @CacheResult@CachePut @CachePut@CacheEvict @CacheRemove@CacheEvict(allEntries=true) @CacheRemoveAll
JMS
20
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
Review: Spring JMS Config in XML
22
Annotated JMS Endpoints
23
Flexible Method Signatures
24
Transition from existing XML config…
25
… or remove XML altogether
26
Spring MVC
27
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
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"); }}
JSONP Support • Simply declare as a Spring-managed component…
@ControllerAdviceclass JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpAdvice() { super("callback"); }}
30
Name of JSONP query param(s)
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
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
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
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
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
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
Testing
37
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
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
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
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
Ex: Groovy Script Config @RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("/context.groovy")public class GroovyPersonTests {
@Autowired private Person person;
/* test methods using person bean */}
42
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
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
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
@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
Ex: @TestPropertySource – locations @ContextConfiguration@TestPropertySource("/test.properties")public class MyIntegrationTests {
// class body...}
47
@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
Ex: @TestPropertySource – properties @ContextConfiguration@TestPropertySource( properties = {"foo=bar", "port: 4242"})public class MyIntegrationTests {
// class body...}
49
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
@TestPropertySource – Precedence
51
Inlined
Files
Application & System
test
prec
eden
ce
Ex: @TestPropertySource – locations & properties @ContextConfiguration@TestPropertySource( locations = "/test.properties", properties = "port: 4242")public class MyIntegrationTests {
// class body...}
52
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
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
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?
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
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
Executing SQL Scripts
58
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
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
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
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
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
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
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
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
@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
@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}
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
In closing…
70
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
Blogs Spring Blog: http://spring.io/blog Swiftmind Blog: http://www.swiftmind.com/blog
72
Q & A Sam Brannen
@sam_brannen
www.slideshare.net/sbrannen
www.swiftmind.com
73
@springcentral spring.io/video
top related