spring.io를 통해 배우는 spring 개발사례

44
spring.io를 통해 배우는 spring 개발사례 spring.io Summary QnA Intro Client Site External

Upload: daehwan-lee

Post on 16-Jul-2015

1.817 views

Category:

Software


3 download

TRANSCRIPT

Page 1: spring.io를 통해 배우는 spring 개발사례

spring.io를 통해 배우는 spring 개발사례

spring.io Summary QnAIntro Client Site External

Page 2: spring.io를 통해 배우는 spring 개발사례

자기소개

이대환 SK planetData Service 개발팀

Email : [email protected]

Twitter : JazzyRedface

spring.io Summary QnAIntro Client Site External

Page 3: spring.io를 통해 배우는 spring 개발사례

이자리에 나온 이유

• 스프링 처음 접했을때

• 불편해, 환경설정도 어렵고....(CRUD 빨리 해보고싶은데....)

• 좀 이제 익숙해지고 알아갈때쯤에

• 이게 정말 최선의 웹개발을 위한 구조인걸까?

spring.io Summary QnAIntro Client Site External

Page 4: spring.io를 통해 배우는 spring 개발사례

거의 1년이 지나갈 즈음에.....

spring.io Summary QnAIntro Client Site External

Page 5: spring.io를 통해 배우는 spring 개발사례

spring 2gxspring.io 사이트의 reference

app 소개발표

spring.io Summary QnAIntro Client Site External

Page 6: spring.io를 통해 배우는 spring 개발사례

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 개발사례

spring.io Summary QnAIntro Client Site External

sagan ├── sagan-client (클라이언트 모듈) ├── sagan-common (공통 모듈) ├── sagan-indexer (검색 모듈) ├── sagan-site (웹 어플리케이션 모듈)

전체 프로젝트 구조

Page 8: spring.io를 통해 배우는 spring 개발사례

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 개발사례

Why open source?

• 예제/샘플 앱 문제

• 수많은 예제들... 돌아가지 않는 예제들.....

• 오래된 코드/라이브러리 사용

• 레퍼런스 앱 문제

• 어디다가 쓸수 있다는건지?

• 이거 확장은 가능한걸까?

• 실무 또는 상용에서 진짜로 써먹을수 있어?

spring.io Summary QnAIntro Client Site External

Page 10: spring.io를 통해 배우는 spring 개발사례

그럼 우리가 좋은 예를 보여주자!

• 오픈소스화해서 좋은 참고가 되도록

• 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 개발사례

sagan-client

spring.io Summary QnAIntro Client Site External

Page 12: spring.io를 통해 배우는 spring 개발사례

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 개발사례

Gulpjs

• 프론트엔드 빌드 툴 (스프링에서 Maven/gradle)

• Minify, Uglify, Concatenation, Code quality, Test Runner, Server, Watch 등의 일들을 수행함.

spring.io Summary QnAIntro Client Site External

Page 14: spring.io를 통해 배우는 spring 개발사례

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 개발사례

Grunt VS Gulpjs

• Config based

• 많은 플러그인 지원

• 양이 많으면 읽기가 좀 힘듬

• Code(stream) based

• 상대적으로 좀 적다

• 코드베이스라서 읽기가 편함함

spring.io Summary QnAIntro Client Site External

Page 16: spring.io를 통해 배우는 spring 개발사례

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 개발사례

개인의 선호도에 따라서 선택하자

spring.io Summary QnAIntro Client Site External

Page 18: spring.io를 통해 배우는 spring 개발사례

Modularization

• 브라우져에서 로드하는 파일들은 영역 구분이 없다. (자바에서 만약 모든것을 static으로 개발한다면?)

• 그렇다고 작지도 않은... 덩치큰 자바스크립트 파일들을 필요할때만(private하게) 불러서 쓰고싶다.

spring.io Summary QnAIntro Client Site External

Page 19: spring.io를 통해 배우는 spring 개발사례

<!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 개발사례

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 개발사례

Webapp안에 없는데....

spring.io Summary QnAIntro Client Site External

Page 22: spring.io를 통해 배우는 spring 개발사례

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 개발사례

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 개발사례

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 개발사례

WebJar란 무엇인가?

• 클라이언트 리소스들이 jar 파일로 패키징된것

• https://www.youtube.com/watch?t=2129&v=71NVb3vMvMc

spring.io Summary QnAIntro Client Site External

Page 26: spring.io를 통해 배우는 spring 개발사례

우리는 왜 Client를 분리해야할까?

spring.io

• 누가 개발할지 모르는 프론트엔드 영역을 백엔드 개발자들만 잘 아는 환경 안에 두는건 유연성이 떨어진다. 요즘은 프론트엔드/백엔드 각자 전문화되는 영역으로 발전하고있고, 프론트엔드가 개발될때 백엔드에 의존하는것은 유연성이 떨어진다.예) 자바 프로젝트 내에 html/css/js코드가 섞이면, 자체 컴파일/테스트/코드 검수 등등을 자체 빌드툴을 통해서 하지 스프링 빌드툴에 종속받지 않는다.

Summary QnAIntro Client Site External

얕게 조금 더 생각해보자

Page 27: spring.io를 통해 배우는 spring 개발사례

sagan-site

spring.io Summary QnAIntro Client Site External

Page 28: spring.io를 통해 배우는 spring 개발사례

수많은 환경 설정들....

spring.io Summary QnAIntro Client Site External

Page 29: spring.io를 통해 배우는 spring 개발사례

때로는 열심히 설정을 해도....

spring.io Summary QnAIntro Client Site External

Page 30: spring.io를 통해 배우는 spring 개발사례

Spring Boot

spring.io Summary QnAIntro Client Site External

http://www.slideshare.net/sungyongjung/springcamp2014springboot?related=1

Page 31: spring.io를 통해 배우는 spring 개발사례

@EnableAutoConfiguration

spring.io Summary QnAIntro Client Site External

Page 32: spring.io를 통해 배우는 spring 개발사례

@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 개발사례

설정을 추가/변경하고 싶으면

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 개발사례

별도의 환경 설정을 원한다면

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 개발사례

설정하기 귀찮은 톰캣

spring.io Summary QnAIntro Client Site External

Page 36: spring.io를 통해 배우는 spring 개발사례

심지어 멀티프로젝트라면....

spring.io Summary QnAIntro Client Site External

Page 37: spring.io를 통해 배우는 spring 개발사례

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 개발사례

JDK7 to JDK8

• Lambda Expressions

• Stream API

• JodaTime -> LocalDate

spring.io Summary QnAIntro Client Site External

Page 39: spring.io를 통해 배우는 spring 개발사례

외부 연동 요소들

ElephantSQL(DB)application 모니터링

검색

WebService

spring.io

캐싱CDN 소통

소스저장소/버전관리

Summary QnAIntro Client Site External

Page 40: spring.io를 통해 배우는 spring 개발사례

spring.io

New Relic

• 모니터링 서비스

• 트랜잭션 모니터링을 통해서 어떤 경로에서 부하가 많이 걸리거나 느린지 확인

• 원인이 파악이 되면 외부 서비스(Cloud Services)를 통해서 해결 예) CloudFlare, ElasticSearch, RedisCloud

Summary QnAIntro Client Site External

Page 41: spring.io를 통해 배우는 spring 개발사례

요약

• 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 개발사례

잠깐...그런데 너무 많은데....?

• 필요한것만 써보시거나 “저런게 있구나” 정도로만 알고 계셔도 좋습니다 .

• 이러한 최신 트렌드가 항상 답은 아니에요, 본인이 받아들일 수 있는것만 해보세요.

• 저도 저거 나온거 싹 다 써봤냐구요? 아니요, 그러나 노력중입니다.

spring.io Summary QnAIntro Client Site External

Page 43: spring.io를 통해 배우는 spring 개발사례

Q & A

spring.io Summary QnAIntro Client Site External

Page 44: spring.io를 통해 배우는 spring 개발사례

spring.io Summary QnAIntro Client Site External