Upload
pei-tang-huang
View
1.342
Download
2
Embed Size (px)
Citation preview
Spring Booted, But…
黃培棠 (中華電信企業客戶分公司)Pei-Tang Huang @ Chunghwa Telecom Co., Ltd.
Spring Boot Recap
Spring Boot is a framework for Spring Framework
• Spring Framework gluing things together, wrapped them up, and left a lot of options for you.
• Spring Boot make your life easier by making a opinionated choice for you.
Spring Framework as Ingredients
http://blog.mimacom.com/introduction-to-spring-boot/
Spring Boot as Cake
http://blog.mimacom.com/introduction-to-spring-boot/
What If You Are Working In A Cake Factory…
By Marcel Ekkel from Hong Kong, Hong Kong (Cheese cAke paradise?)[CC BY 2.0 (http://creativecommons.org/licenses/by/2.0)], via Wikimedia Commons
Or Something Like That…
Create Your Own Layer
All problems in computer science can be solved by another level of indirection.
- David Wheeler
Making a Bootiful Library
Be even more opinionated!• Provides default for most cases important to you.• Automatically configure whenever possible.
Be polite!• Default is only used to de-fault.• Exposes properties for configuration.• Conditional bypass auto configuration.
Here Comes The Compost * {#} powered by
^/ /^ /^/ /y/ /^) /^/ /^/ =/= + | /_ /_/ / / /-' /_/ `_> / ____,&.__~_ (c) Chunghwa Telecom Co., Ltd.
------- Compost v0.2.0-SNAPSHOT // Spring Boot v1.4.1.RELEASE
2016-10-15 04:13:12.462 INFO 76431 --- [ restartedMain] com.cht.sample.Application : Starting Applicatio2016-10-15 04:13:12.465 INFO 76431 --- [ restartedMain] com.cht.sample.Application : The following profi2016-10-15 04:13:12.887 INFO 76431 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Refreshing org.spri2016-10-15 04:13:13.662 INFO 76431 --- [ restartedMain] mpostSecurityConfigurationImportSelector : "cht.security.login2016-10-15 04:13:14.895 INFO 76431 --- [ restartedMain] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean 2016-10-15 04:13:15.171 INFO 76431 --- [ restartedMain] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean 2016-10-15 04:13:15.966 INFO 76431 --- [ restartedMain] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inje2016-10-15 04:13:16.099 INFO 76431 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'managerTx2016-10-15 04:13:16.142 INFO 76431 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'com.cht.compo2016-10-15 04:13:16.245 INFO 76431 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springfra2016-10-15 04:13:16.437 INFO 76431 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'objectPostPro2016-10-15 04:13:16.443 INFO 76431 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springfra2016-10-15 04:13:16.639 INFO 76431 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'cht.function2016-10-15 04:13:16.643 INFO 76431 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'com.cht.compo2016-10-15 04:13:16.672 INFO 76431 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'environmentPr2016-10-15 04:13:16.678 INFO 76431 --- [ restartedMain] .c.c.c.f.CompositeFunctionMappingService : Found following 2016-10-15 04:13:16.678 WARN 76431 --- [ restartedMain] .c.c.c.f.CompositeFunctionMappingService : PropertiesFunctionM2016-10-15 04:13:16.678 INFO 76431 --- [ restartedMain] .c.c.c.f.CompositeFunctionMappingService : Registered function2016-10-15 04:13:16.678 INFO 76431 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'functionMappi2016-10-15 04:13:16.682 INFO 76431 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'com.cht.compo2016-10-15 04:13:16.702 INFO 76431 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'methodSecurit2016-10-15 04:13:16.719 INFO 76431 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springfra
Choose A Right Tool
Content assist will you a lot of time!
Spring Tool Suite™ v.s. IntelliJ® IDEA Ultimate
Weave Your Own Safety NetYou have less excuse to skip test!
https://spring.io/blog/2016/04/15/testing-improvements-in-spring-boot-1-4
@RunWith(SpringRunner.class)@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)public class MyWebIntegrationTests {
@Autowiredprivate TestRestTemplate restTemplate;
@Testpublic void exampleTest() {
String body = restTemplate.getForObject("/", String.class);assertThat(body).isEqualTo("Hello World");
}}
You have an application serverYou have the IoC container
Knowing Your D
ependenciescom.example:demo:jar:0.0.1-SNAPSHOT+- org.springframework.boot:spring-boot-starter:jar:1.4.1.RELEASE:compile| +- org.springframework.boot:spring-boot:jar:1.4.1.RELEASE:compile| | \- org.springframework:spring-context:jar:4.3.3.RELEASE:compile| | +- org.springframework:spring-aop:jar:4.3.3.RELEASE:compile| | +- org.springframework:spring-beans:jar:4.3.3.RELEASE:compile| | \- org.springframework:spring-expression:jar:4.3.3.RELEASE:compile| +- org.springframework.boot:spring-boot-autoconfigure:jar:1.4.1.RELEASE:compile| +- org.springframework.boot:spring-boot-starter-logging:jar:1.4.1.RELEASE:compile| | +- ch.qos.logback:logback-classic:jar:1.1.7:compile| | | \- ch.qos.logback:logback-core:jar:1.1.7:compile| | +- org.slf4j:jcl-over-slf4j:jar:1.7.21:compile| | +- org.slf4j:jul-to-slf4j:jar:1.7.21:compile| | \- org.slf4j:log4j-over-slf4j:jar:1.7.21:compile| +- org.springframework:spring-core:jar:4.3.3.RELEASE:compile| \- org.yaml:snakeyaml:jar:1.17:runtime\- org.springframework.boot:spring-boot-starter-test:jar:1.4.1.RELEASE:test
+- org.springframework.boot:spring-boot-test:jar:1.4.1.RELEASE:test+- org.springframework.boot:spring-boot-test-autoconfigure:jar:1.4.1.RELEASE:test+- com.jayway.jsonpath:json-path:jar:2.2.0:test| +- net.minidev:json-smart:jar:2.2.1:test| | \- net.minidev:accessors-smart:jar:1.1:test| | \- org.ow2.asm:asm:jar:5.0.3:test| \- org.slf4j:slf4j-api:jar:1.7.21:compile+- junit:junit:jar:4.12:test+- org.assertj:assertj-core:jar:2.5.0:test+- org.mockito:mockito-core:jar:1.10.19:test| \- org.objenesis:objenesis:jar:2.1:test+- org.hamcrest:hamcrest-core:jar:1.3:test+- org.hamcrest:hamcrest-library:jar:1.3:test+- org.skyscreamer:jsonassert:jar:1.3.0:test| \- org.json:json:jar:20140107:test\- org.springframework:spring-test:jar:4.3.3.RELEASE:test
Bill Of MaterialsKeep library versions in ONE place
• spring-boot-dependencies• io.spring.platform:platform-bom
Declare dependencies without <version>:<dependency>
<groupId>org.springframework</groupId><artifactId>spring-context</artifactId>
</dependency>
Versioning Matters
Spring Project Versioning
{number}.{release_type}
{number} => {major}.{minor}.{micro}
Semantic Versioning
MAJOR.MINOR.PATCH
https://github.com/spring-projects/spring-build-gradle/wiki/Spring-project-versioning
No breaking changes at this level??
Release TrainGrouping individual projects into one entity.
spring-data-releasetrain• Arora, Baggage, Codd, Dijkstra, Evans, Fowler, Gosling, Ingalls
spring-cloud-dependencies• Angel, Britxon, Camden
spring-cloud-stream-dependencies• 1.0, Brooklyn
Define Your Own BOMExcept referring to the BOM, no dependencies version should be used in projects.
Define properties for version, unless:<parent>
<groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.3.8.RELEASE</version>
</parent>
<properties><spring-boot.version>1.4.1.RELEASE</spring-boot.version>
</properties>
Maven, Maven?!Mystic version number 2.1.1?
--- maven-dependency-plugin:2.8:tree (default-cli) @ compost-case-web ---com.cht.compost:compost-case-web:jar:0.2.0-SNAPSHOT+- com.cht.commons:cht-commons-web:jar:0.3.0-SNAPSHOT:compile| +- ...| +- org.webjars:jquery:jar:2.1.1:compile (version managed from 1.11.0-1)| +- org.webjars:angular-ui-utils:jar:0.1.0-1:compile| | +- ...| | \- (org.webjars:jquery:jar:2.1.1:compile –| | version managed from 1.6.2; omitted for duplicate)| +- org.webjars:ng-grid:jar:2.0.11:compile| | +- ...| | \- (org.webjars:jquery:jar:2.1.1:compile –| | version managed from 1.8.3; omitted for duplicate)| +- org.webjars:bootstrap:jar:3.2.0:compile| | \- (org.webjars:jquery:jar:2.1.1:compile –| | version managed from 1.11.1; omitted for duplicate)\- ...
Keep a CHANGELOGDon’t let your friends dump git logs into changelog
http://keepachangelog.com/en/0.3.0/
# Change LogAll notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]### Added- zh-CN and zh-TW translations from @tianshuo.- tr-TR translation from @karalamalar.
### Changed- Start versioning based on the current English version at 0.3.0 to helptranslation authors keep things up-to-date.
## [0.3.0] - 2015-12-03...
Meta-Annotations and Composed Annotations
Annotations on annotation everywhere
https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model
@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(excludeFilters = @Filter(
type = FilterType.CUSTOM,classes = TypeExcludeFilter.class))
public @interface SpringBootApplication {
@AutoConfigurationPackage@Import(EnableAutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration {
Define @ConfigurationPropertiesWhenever Possible
It’s type-safe, IDE-friendly.And more expressive than:
@lombok.Data@Component@ConfigurationProperties(prefix = "connection")public class ConnectionProperties {
private String username = "anonymous";
@NotNullprivate InetAddress remoteAddress;
}
@Value("${connection.username:anonymous}")
Name Your Property Seriously
There are only two hard things in Computer Science: cache invalidation and naming things.
- Phil Karlton
Renaming Your Property
Just like refactoring method names.
@Deprecated@DeprecatedConfigurationProperty(
reason ="Property deprecated in Jackson 2.7",
replacement ="spring.jackson.default-property-inclusion")
public Include getSerializationInclusion() {return getDefaultPropertyInclusion();
}
AutoConfigurationMETA-INF/spring.factories
Nothing special but @Configuration.
Serves as fallback after normal @Configurations been processed.
# Auto Configureorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.example.autoconfigure.MyAutoConfiguration
@ConditionalOn*Eliminating all @Configurations will not work.
Use built-in annotations where possible:@ConditionalOnBean@ConditionalOnClass@ConditionalOnMissingBean@ConditionalOnMissingClass@ConditionalOnProperty
…
@ProfileDefine profiles for properties,not for @Configurations or @Beans.1. You can modify or override properties more easily.2. You can always define property like my.feature-for-
the-profile.enabled to achieve the same goal.3. ProfileCondition is not a SpringBootCondition.
@Orders Matter
Hints for Spring Boot.• @AutoConfigureAfter• @AutoConfigureBefore
Take built-in AutoConfiguration as Anchor• Override built-in configuration by invalidate its Condition.• Register beans and pass them into auto configuration.• Refine Spring Boot auto configured beans.
Learning From Spring Boot
Spring Boot is an Expert at using libraries
But you still have to know them with <3• Not every operation is idempotent or cumulative, WebSecurityConfigurerAdapter for example.
Doing Well as A MonolithicPackage as WAR
POM.xml<packaging>war</packaging>
@SpringBootApplicationpublic class Application
extends SpringBootServletInitializerimplements WebApplicationInitializer {
...}
JBoss EAP
JBoss EAP v6.0 – 6.2• Have to remove embedded server.
JBoss EAP v6.x• spring.jmx.enabled=false• server.servlet-path=/*
• http://stackoverflow.com/a/1939642• Multipart request charset encoding value is wrong.• Have to downgrade JPA and Hibernate.
JBoss EAP v7• Trying…
Oracle WebLogic Server
WebLogic 11g and below• Not supported.
WebLogic 12c• Filter registration logic is WRONG!
• https://github.com/spring-projects/spring-boot/issues/2862#issuecomment-99461807
• Have to remove embedded server.• Have to downgrade JPA and Hibernate.• Have to specify <wls:prefer-application-packages/> in weblogic.xml.
IBM WebSphere Application Server
WebSphere AS v8.5.5• Have to remove embedded server.• Have to downgrade JPA and Hibernate.
From Spring FrameworkTo Spring Boot
1. Create intermediate project incorporating Spring Boot.
2. Remove functions duplicated to Spring Boot.
3. Pull up @Configuration as AutoConfiguration.
4. Extract application properties.
放飯!