Download - spring.io를 통해 배우는 spring 개발사례
![Page 1: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/1.jpg)
spring.io를 통해 배우는 spring 개발사례
spring.io Summary QnAIntro Client Site External
![Page 2: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/2.jpg)
자기소개
이대환 SK planetData Service 개발팀
Email : [email protected]
Twitter : JazzyRedface
spring.io Summary QnAIntro Client Site External
![Page 3: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/3.jpg)
이자리에 나온 이유
• 스프링 처음 접했을때
• 불편해, 환경설정도 어렵고....(CRUD 빨리 해보고싶은데....)
• 좀 이제 익숙해지고 알아갈때쯤에
• 이게 정말 최선의 웹개발을 위한 구조인걸까?
spring.io Summary QnAIntro Client Site External
![Page 4: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/4.jpg)
거의 1년이 지나갈 즈음에.....
spring.io Summary QnAIntro Client Site External
![Page 5: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/5.jpg)
spring 2gxspring.io 사이트의 reference
app 소개발표
spring.io Summary QnAIntro Client Site External
![Page 6: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/6.jpg)
Sagan project
• 스프링 개발팀이 참여한 spring.io의 레퍼런스 앱 프로젝트
• 2013년 7월에 git repository에서 첫 커밋 시작
• 2013년 SpringOne에서 spring.io사이트 첫 선을 보임
• 2014년 SpringOne에서 spring.io(sagan project) 오픈소스로 공개
spring.io Summary QnAIntro Client Site External
![Page 7: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/7.jpg)
spring.io Summary QnAIntro Client Site External
sagan ├── sagan-client (클라이언트 모듈) ├── sagan-common (공통 모듈) ├── sagan-indexer (검색 모듈) ├── sagan-site (웹 어플리케이션 모듈)
전체 프로젝트 구조
![Page 8: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/8.jpg)
spring.io
sagan-site
GET http://spring.io
ElephantSQL
호스팅
검색
가이드/블로그 연동
Spring Boot
http://www.slideshare.net/SpringCentral/inside-spring-iospringone2gx2014
Summary QnAIntro Client Site External
![Page 9: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/9.jpg)
Why open source?
• 예제/샘플 앱 문제
• 수많은 예제들... 돌아가지 않는 예제들.....
• 오래된 코드/라이브러리 사용
• 레퍼런스 앱 문제
• 어디다가 쓸수 있다는건지?
• 이거 확장은 가능한걸까?
• 실무 또는 상용에서 진짜로 써먹을수 있어?
spring.io Summary QnAIntro Client Site External
![Page 10: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/10.jpg)
그럼 우리가 좋은 예를 보여주자!
• 오픈소스화해서 좋은 참고가 되도록
• github.com/spring-io/sagan
• spring.io/blog
• open sourcing spring.io
• zero downtime deployments
• client-side architecture
• upgrading to JDK8
spring.io Summary QnAIntro Client Site External
![Page 11: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/11.jpg)
sagan-client
spring.io Summary QnAIntro Client Site External
![Page 12: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/12.jpg)
Sagan은 왜 Client를 분리 한거지?
• 다양한 javascript library들에 의존성이 존재(Test system, Build System, Modularization)
• Front-end관련 이슈 및 환경들을 분리시킴으로서, Front-end 개발자 또는 다른 개발자들에게 훨씬 나은 개발환경을 제공해 줄 수 있다고 판단.
spring.io Summary QnAIntro Client Site External
![Page 13: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/13.jpg)
Gulpjs
• 프론트엔드 빌드 툴 (스프링에서 Maven/gradle)
• Minify, Uglify, Concatenation, Code quality, Test Runner, Server, Watch 등의 일들을 수행함.
spring.io Summary QnAIntro Client Site External
![Page 14: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/14.jpg)
spring.io
// a.js test
var name = "redface";
function getAge(age) {
return name + " : " + age;
}
console.log(name);
용량 108 bytes
// b.js test
var isCool = true;
console.log(isCool);
용량 55 bytes
// a.js test
var name = "redface";
function getAge(age) {
return name + " : " + age;
}
console.log(name);
// b.js test
var isCool = true;
console.log(isCool);
용량 162 bytes
function getAge(o){return name+" : "+o}var name="redface";console.log(name);var isCool=!0;console.log(isCool);
+ =파일 두개를 합쳐서 하나로 만들고
합쳐친 파일에서 공백/주석 없에고 코드를 난독화한다.
용량 110 bytes
Summary QnAIntro Client Site External
![Page 15: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/15.jpg)
Grunt VS Gulpjs
• Config based
• 많은 플러그인 지원
• 양이 많으면 읽기가 좀 힘듬
• Code(stream) based
• 상대적으로 좀 적다
• 코드베이스라서 읽기가 편함함
spring.io Summary QnAIntro Client Site External
![Page 16: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/16.jpg)
gulp.task('minify', function(){
return gulp.src('src/*.js')
.pipe(concat('all.js'))
});
grunt.initConfig({
concat: {
'dist/all.js': ['src/*.js']
}
});
Syntax 비교
spring.io Summary QnAIntro Client Site External
![Page 17: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/17.jpg)
개인의 선호도에 따라서 선택하자
spring.io Summary QnAIntro Client Site External
![Page 18: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/18.jpg)
Modularization
• 브라우져에서 로드하는 파일들은 영역 구분이 없다. (자바에서 만약 모든것을 static으로 개발한다면?)
• 그렇다고 작지도 않은... 덩치큰 자바스크립트 파일들을 필요할때만(private하게) 불러서 쓰고싶다.
spring.io Summary QnAIntro Client Site External
![Page 19: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/19.jpg)
<!doctype html>
<html>
<head>
<title>TEST</title>
</head>
<body>
<script src=“a.js”></script>
<script src=“b.js”></script>
<script src=“c.js”></script>
<script src=“d.js”></script>
</body>
</html>
spring.io
var name = “멍청아";
function test(name) {
return name;
}
var name = "멋있어요";
function test(name) {
return name;
}
Summary QnAIntro Client Site External
console.log(test(name));
console.log(test(name));
1
2
![Page 20: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/20.jpg)
curl.js
• 모듈을 정의하고 로드를 할 수 있게 해주는 AMD계열 자바스크립트 라이브러리
spring.io Summary QnAIntro Client Site External
http://en.wikipedia.org/wiki/Asynchronous_module_definition
http://en.wikipedia.org/wiki/CommonJS
![Page 21: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/21.jpg)
Webapp안에 없는데....
spring.io Summary QnAIntro Client Site External
![Page 22: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/22.jpg)
sagan-client . ├── build ├── dist │ ├── css │ ├── font-custom │ ├── google79a200664ce5ab8e.html │ ├── img │ ├── lib │ ├── newsletter.html │ ├── robots.txt │ ├── run.js │ └── run.js.map ├── gulpfile.js └── src ├── app ├── css ├── feature ├── font-custom ├── google79a200664ce5ab8e.html ├── img ├── lib ├── newsletter.html ├── platform ├── robots.txt └── run.js
spring.io
sagan-site . ├── src │ ├── it │ │ └── java │ ├── main │ │ ├── java │ │ ├── webapp │ │ └── resources │ └── test
빌드된 client 결과물
여기에 client code가 없다?
Summary QnAIntro Client Site External
![Page 23: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/23.jpg)
Bye bye src/main/webapp
• Standalone : 파일 리소스 경로를 직접 설정
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.saganPath.isEmpty()) {
registry.addResourceHandler("/**")
.addResourceLocations("file:///" + this.saganPath + "/sagan-client/src/")
.setCachePeriod(0);
}
}
spring.io Summary QnAIntro Client Site External
![Page 24: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/24.jpg)
Bye bye src/main/webapp
• Production : 빌드시, webjar로 묶어서 classpath로 제공
jar {
from 'dist'
eachFile { details ->
details.path = details.path.startsWith('META-INF') ?: 'static/'+details.path
}
includeEmptyDirs = false
}
spring.io Summary QnAIntro Client Site External
![Page 25: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/25.jpg)
WebJar란 무엇인가?
• 클라이언트 리소스들이 jar 파일로 패키징된것
• https://www.youtube.com/watch?t=2129&v=71NVb3vMvMc
spring.io Summary QnAIntro Client Site External
![Page 26: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/26.jpg)
우리는 왜 Client를 분리해야할까?
spring.io
• 누가 개발할지 모르는 프론트엔드 영역을 백엔드 개발자들만 잘 아는 환경 안에 두는건 유연성이 떨어진다. 요즘은 프론트엔드/백엔드 각자 전문화되는 영역으로 발전하고있고, 프론트엔드가 개발될때 백엔드에 의존하는것은 유연성이 떨어진다.예) 자바 프로젝트 내에 html/css/js코드가 섞이면, 자체 컴파일/테스트/코드 검수 등등을 자체 빌드툴을 통해서 하지 스프링 빌드툴에 종속받지 않는다.
Summary QnAIntro Client Site External
얕게 조금 더 생각해보자
![Page 27: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/27.jpg)
sagan-site
spring.io Summary QnAIntro Client Site External
![Page 28: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/28.jpg)
수많은 환경 설정들....
spring.io Summary QnAIntro Client Site External
![Page 29: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/29.jpg)
때로는 열심히 설정을 해도....
spring.io Summary QnAIntro Client Site External
![Page 30: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/30.jpg)
Spring Boot
spring.io Summary QnAIntro Client Site External
http://www.slideshare.net/sungyongjung/springcamp2014springboot?related=1
![Page 31: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/31.jpg)
@EnableAutoConfiguration
spring.io Summary QnAIntro Client Site External
![Page 32: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/32.jpg)
@EnableAutoConfiguration
spring.io
# JACKSON (JacksonProperties)
spring.jackson.date-format= # Date format string (e.g. yyyy-MM-dd HH:mm:ss), or a fully-qualified date format class name (e.g. com.fasterxml.jackson.databind.util.ISO8601DateFormat)
spring.jackson.property-naming-strategy= # One of the constants on Jackson's PropertyNamingStrategy (e.g. CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES) or the fully-qualified class name of a PropertyNamingStrategy subclass
spring.jackson.deserialization.*= # see Jackson's DeserializationFeature
spring.jackson.generator.*= # see Jackson's JsonGenerator.Feature
spring.jackson.mapper.*= # see Jackson's MapperFeature
spring.jackson.parser.*= # see Jackson's JsonParser.Feature
spring.jackson.serialization.*= # see Jackson's SerializationFeature
# THYMELEAF (ThymeleafAutoConfiguration)
spring.thymeleaf.check-template-location=true
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.excluded-view-names= # comma-separated list of view names that should be excluded from resolution
spring.thymeleaf.view-names= # comma-separated list of view names that can be resolved
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html # ;charset=<encoding> is added
spring.thymeleaf.cache=true # set to false for hot refresh
Summary QnAIntro Client Site External
![Page 33: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/33.jpg)
설정을 추가/변경하고 싶으면
sagan-site . ├── src │ ├── it │ │ └── java │ ├── main │ │ ├── java │ │ └── resources │ │ └── application.yml │ └── test
spring.io
spring:
thymeleaf:
cache: false
• resources 경로 하위에서 appplication.yml 추가 설정
• 바뀌는 설정이 있으면 default설정은 disabled, 바뀐 설정은 enabled
Summary QnAIntro Client Site External
![Page 34: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/34.jpg)
별도의 환경 설정을 원한다면
spring.io
@EnableAutoConfiguration
public class SiteConfig {
@Bean
public ViewResolver thymeleafViewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
//viewResolver.setTemplateEngine(templateEngine());
viewResolver.setCharacterEncoding(CHARSET);
viewResolver.setCache(false);
viewResolver.addStaticVariable("baseUrl", “http://localhost:8080");
return viewResolver;
}
}
Summary QnAIntro Client Site External
![Page 35: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/35.jpg)
설정하기 귀찮은 톰캣
spring.io Summary QnAIntro Client Site External
![Page 36: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/36.jpg)
심지어 멀티프로젝트라면....
spring.io Summary QnAIntro Client Site External
![Page 37: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/37.jpg)
Embedded Tomcat 제공
• public static void main entry-point 실행시, 자동으로 embedded tomcat실행
• Embedded Jetty도 사용 가능
https://spring.io/blog/2014/03/07/deploying-spring-boot-applications
spring.io Summary QnAIntro Client Site External
![Page 38: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/38.jpg)
JDK7 to JDK8
• Lambda Expressions
• Stream API
• JodaTime -> LocalDate
spring.io Summary QnAIntro Client Site External
![Page 39: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/39.jpg)
외부 연동 요소들
ElephantSQL(DB)application 모니터링
검색
WebService
spring.io
캐싱CDN 소통
소스저장소/버전관리
Summary QnAIntro Client Site External
![Page 40: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/40.jpg)
spring.io
New Relic
• 모니터링 서비스
• 트랜잭션 모니터링을 통해서 어떤 경로에서 부하가 많이 걸리거나 느린지 확인
• 원인이 파악이 되면 외부 서비스(Cloud Services)를 통해서 해결 예) CloudFlare, ElasticSearch, RedisCloud
Summary QnAIntro Client Site External
![Page 41: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/41.jpg)
요약
• Front-end는 프로젝트를 분리 하고 파일들은 모듈화해서(curl.js) gulpjs같은 빌드 툴로 관리하자
• Back-end는 빠른 설정/구현을 위해 spring-boot를 쓰고 임베딩된 기본 지원들을 활용하자(embedded tomcat, h2)
• 간결한 코드작성을 위해 jdk8에서 지원하는 기능을 활용하자(lambda expressions, stream api)
• 외부연동 서비스들을 최대한 활용하자(pivotal.io, elephantDB, elastic search, new relic)
spring.io Summary QnAIntro Client Site External
![Page 42: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/42.jpg)
잠깐...그런데 너무 많은데....?
• 필요한것만 써보시거나 “저런게 있구나” 정도로만 알고 계셔도 좋습니다 .
• 이러한 최신 트렌드가 항상 답은 아니에요, 본인이 받아들일 수 있는것만 해보세요.
• 저도 저거 나온거 싹 다 써봤냐구요? 아니요, 그러나 노력중입니다.
spring.io Summary QnAIntro Client Site External
![Page 43: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/43.jpg)
Q & A
spring.io Summary QnAIntro Client Site External
![Page 44: spring.io를 통해 배우는 spring 개발사례](https://reader030.vdocuments.net/reader030/viewer/2022013102/55a713131a28ab47358b45b4/html5/thumbnails/44.jpg)
끝
spring.io Summary QnAIntro Client Site External