/images/profile.png

logback μ„€μ •ν•˜κΈ°

μžλ°” 개발자라면 ν•œλ²ˆμ―€μ€ λ“€μ–΄λ΄€κ³ , ν•œλ²ˆμ―€μ€ μ‚¬μš©ν–ˆμ„λ²•ν•œ logger 둜 log4jκ°€ μžˆμ„κ²ƒμ΄λ‹€. ν•˜μ§€λ§Œ μ΅œκ·Όλ“€μ–΄ logbackμ΄λΌλŠ”κ²ƒμ„ μ•Œκ²Œλ˜μ—ˆκ³ , μ™œ logback을 μ‚¬μš©ν•΄μ•Ό ν•˜λŠ” μ΄μœ λΌλŠ” 글이 μžˆμ„μ •λ„λ‘œ μ—¬λŸ¬ μΈ‘λ©΄μ—μ„œ κ°œμ„ μ΄ λœλ“― ν•˜λ‹€. (링크) μ΄λ²ˆμ— μž‘μ„±ν•  κΈ€μ˜ λͺ©μ μ€ logback을 μ„€μ •ν•˜κ³  μ–΄λ–»κ²Œ μ‚¬μš©ν•˜λŠ”μ§€μ— λŒ€ν•΄ μž‘μ„±ν•΄ 보고자 ν•œλ‹€. β€» κ³΅μ‹μ‚¬μ΄νŠΈ : https://logback.qos.ch/ pom.xml mavenꡬ쑰라고 κ°€μ •ν–ˆμ„λ•Œ logback Dependencyλ₯Ό κ°€μ Έμ˜€κΈ° μœ„ν•΄μ„œλŠ” μ•„λž˜μ™€ 같이 pom.xml 에 μ„€μ •ν•΄ μ£Όλ©΄ λœλ‹€. <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.7</version> <!--버전은 상황에 따라 --> </dependency> 둜그레벨 ERROR, WARN, INFO, DEBUG or TRACE # logback μ„€μ •νŒŒμΌ 일반적으둜 logback.xml μ΄λΌλŠ” μ΄λ¦„μœΌλ‘œ λ§Œλ“€μ–΄ src/main/resources/μ•„λž˜μ— μœ„μΉ˜ν•˜κ²Œ λœλ‹€. Spring-Boot ν™˜κ²½μ—μ„œλŠ” logback-spring.xml μ΄λΌλŠ” μ΄λ¦„μœΌλ‘œ μ„€μ •ν•΄μ•Ό ν•˜λŠ”λ° logback.xml둜 μ„€μ •ν•˜λ©΄ μŠ€ν”„λ§λΆ€νŠΈκ°€ μ„€μ •ν•˜κΈ° 전에 둜그백 κ΄€λ ¨ν•œ 섀정을 ν•˜κΈ° λ•Œλ¬Έμ— μ œμ–΄ν•  μˆ˜κ°€ μ—†κ²Œ λœλ‹€. ( κ³΅μ‹μ‚¬μ΄νŠΈ 메뉴얼 : https://logback.qos.ch/documentation.html ) <?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/defaults.xml" /> <include resource="org/springframework/boot/logging/logback/console-appender.xml" /> <!-- λ³€μˆ˜ 지정 --> <property name="LOG_DIR" value="/logs" /> <property name="LOG_PATH_NAME" value="${LOG_DIR}/data.log" /> <!-- FILE Appender --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH_NAME}</file> <!-- μΌμžλ³„λ‘œ 둜그파일 μ μš©ν•˜κΈ° --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH_NAME}.%d{yyyyMMdd}</fileNamePattern> <maxHistory>60</maxHistory> <!-- μΌμžλ³„ λ°±μ—…νŒŒμΌμ˜ 보관기간 --> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5p] [%F]%M\(%L\) : %m%n</pattern> </encoder> </appender> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5p] [%F]%M\(%L\) : %m%n</pattern> </layout> </appender> <!-- TRACE > DEBUG > INFO > WARN > ERROR, λŒ€μ†Œλ¬Έμž ꡬ뢄 μ•ˆν•¨ --> <!-- profile 을 μ½μ–΄μ„œ appender 을 μ„€μ •ν• μˆ˜ μžˆλ‹€.(phase별 νŒŒμΌμ„ μ•ˆλ§Œλ“€μ–΄λ„ λ˜λŠ” 쒋은 κΈ°λŠ₯) --> <springProfile name="local"> <root level="DEBUG"> <appender-ref ref="FILE" /> <appender-ref ref="STDOUT" /> </root> </springProfile> <springProfile name="real"> <root level="INFO"> <appender-ref ref="FILE" /> <appender-ref ref="STDOUT" /> </root> </springProfile> </configuration> java μ½”λ”©μ—μ„œμ˜ λ‘œκΉ… μ‹€μ œ μ‚¬μš©μ€ λ‹€μŒκ³Ό 같이 LoggerFactoryλ₯Ό μ΄μš©ν•΄μ„œ μ‚¬μš©ν•˜κ±°λ‚˜ Lombokμ–΄λ…Έν…Œμ΄μ…˜μ„ ν™œμš©ν•˜λ©΄ μ‹¬ν”Œν•˜κ²Œ μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€. LoggerFactory μ‚¬μš© import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Foo { static final Logger logger = LoggerFactory.getLogger(Foo.class); public void test() { logger.debug("ID : {}", "foo"); } } Lombok μ–΄λ…Έν…Œμ΄μ…˜ μ‚¬μš© import lombok.extern.slf4j.Slf4j; @Slf4j public class Foo { public void test() { log.debug("ID : {}", "foo"); } } 마치며 일반적인 μ›Ή μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œλŠ” WASμ—μ„œ λ‘œκΉ…μ„ λ”°λ‘œ κ΄€λ¦¬ν•˜κ³  있기 λ•Œλ¬Έμ— file 둜 λ‘œκΉ…μ„ ν•  ν•„μš”λŠ” 없을것 κ°™λ‹€.(일반 jar ν˜•νƒœμ—μ„œλŠ” 파일 λ‘œκΉ…μ΄ ν•„μš” ν• μˆ˜λ„…) μ°Έκ³ μ‚¬μ΄νŠΈ http://yookeun.github.io/java/2015/11/10/log4jtologback/ http://java.ihoney.pe.kr/397 https://logback.qos.ch/

μžλ°” 8 Date

μ΄μ œκΉŒμ§€ λ‚΄ κΈ°μ–΅μœΌλ‘œλŠ” Date κ΄€λ ¨ 클래슀λ₯Ό μ•„λž˜μ²˜λŸΌ 점차 λ°”κΏ”μ¨μ˜¨κ±Έλ‘œ 기얡이 λ‚œλ‹€. java.util.Date > java.util.Calendar > org.joda.time 그런데 java 8 λ²„μ „μ—μ„œ 기쑴에 μžˆμ—ˆλ˜ λ¬Έμ œλ“€μ„ κ°œμ„ ν•΄μ„œ λ‚˜μ™”λ‹€κ³  ν•œλ‹€. (넀이버 HellowWorld ν¬μŠ€νŒ… μ°Έκ³ ) JSR-310 μ΄λΌλŠ” ν‘œμ€€λͺ…μ„Έλ‘œ. μ§€κΈˆλΆ€ν„°λŠ” JAVA 8 μ—μ„œ μ œκ³΅ν•˜λŠ” API둜 λ‚ μ§œ 연산을 μ–΄λ–»κ²Œ ν•˜λŠ”μ§€μ— λŒ€ν•΄ μ•Œμ•„λ³΄κ³ μž ν•œλ‹€. (λ¬Όλ‘  μˆ˜λ§Žμ€ λ‚ μ§œ μ—°μ‚° 방법을이 μžˆμ§€λ§Œ 자주 μ“°μ΄λŠ” λΆ€λΆ„λ“€ μœ„μ£Όλ‘œ μ •λ¦¬ν•΄λ³΄μž.) Date > String (format) LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); String > Date (format) LocalDateTime.parse("2017-01-01 12:30:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); λ‚ μ§œ/μ‹œκ°„ 증감 LocalDateTime localDateTime = LocalDateTime.of(2017, 1, 1, 10, 0, 0); localDateTime.plusDays(1); // 일 localDateTime.plusMonths(1); // μ›” localDateTime.plusHours(1); // μ‹œκ°„ localDateTime.plusWeeks(1); // μ£Ό localDateTime.minusYears(1); // λ…„ localDateTime.minusMinutes(1); // λΆ„ 더 λ‹€μ–‘ν•œ λ‚΄μš©λ“€μ€ μ•„λž˜ URL μ—μ„œ 확인이 κ°€λŠ₯ν•˜λ‹€. https://docs.oracle.com/javase/tutorial/datetime/iso/overview.html

Spring Transactional μ„€μ • 및 μ£Όμš”μ†μ„±

μ§€λ‚œλ²ˆμ—λŠ” νŠΈλžœμž­μ…˜μ˜ 섀정값에 λŒ€ν•΄ μ•Œμ•„λ³Έ λ°” μžˆλ‹€. [ Spring Transaction μ˜΅μ…˜ ] 이번 ν¬μŠ€νŒ…μ—μ„œλŠ” μ‹€μ œλ‘œ μŠ€ν”„λ§ ν™˜κ²½μ—μ„œ μ–΄λ–€μ‹μœΌλ‘œ μ„€μ •ν•΄μ•Ό @Transactional μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν• μˆ˜ μžˆλŠ”μ§€, 그리고 μ–΄λ–€ 속성듀이 μžˆλŠ”μ§€μ— λŒ€ν•΄ μ•Œμ•„λ³΄κ³ μž ν•œλ‹€.μ„€μ • κΈ°μ‘΄ xmlλ°©μ‹μ—μ„œλŠ” λ‹€μŒκ³Ό 같이 섀정을 ν•œλ‹€. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> 혹, JavaConfig λ°©μ‹μœΌλ‘œ μ„€μ •ν•˜κΈ° μœ„ν•΄μ„œλŠ” λ‹€μŒκ³Ό 같이 μ„€μ •ν•œλ‹€. @EnableTransactionManagement public class AppConfig { ... @Bean public PlatformTransactionManager transactionManager() throws URISyntaxException, GeneralSecurityException, ParseException, IOException { return new DataSourceTransactionManager(dataSource()); } } μœ„μ™€κ°™μ΄ 섀정을 ν•΄μ£Όλ©΄ νŠΈλžœμž­μ…˜μ„ μ„€μ •ν•˜κ³ μž ν•˜λŠ” κ³³ μ–΄λ””μ„œλ“  @Transactional μ–΄λ…Έν…Œμ΄μ…˜μ„ μ§€μ •ν•΄μ„œ 적용이 κ°€λŠ₯ν•˜λ‹€. public class UserService{ @Transactional public boolean insertUser(User user){ ... } } μ£Όμš”μ†μ„± @Transactional μ–΄λ…Έν…Œμ΄μ…˜μ˜ μ£Όμš”μ†μ„±μ€ λ‹€μŒκ³Ό κ°™λ‹€. 속성 μ„€ λͺ… μ‚¬μš© 예 isolation Transaction의 isolation Level. λ³„λ„λ‘œ μ •μ˜ν•˜μ§€ μ•ŠμœΌλ©΄ DB의 Isolation Level을 따름. @Transactional(isolation=Isolation.DEFAULT) propagation νŠΈλžœμž­μ…˜ μ „νŒŒκ·œμΉ™μ„ μ •μ˜ , Default=REQURIED @Transactional(propagation=Propagation.REQUIRED) readOnly ν•΄λ‹Ή Transaction을 읽기 μ „μš© λͺ¨λ“œλ‘œ 처리 (Default = false) @Transactional(readOnly = true) rollbackFor μ •μ˜λœ Exception에 λŒ€ν•΄μ„œλŠ” rollback을 μˆ˜ν–‰ @Transactional(rollbackFor=Exception.class) noRollbackFor μ •μ˜λœ Exception에 λŒ€ν•΄μ„œλŠ” rollback을 μˆ˜ν–‰ν•˜μ§€ μ•ŠμŒ. @Transactional(noRollbackFor=Exception.class) timeout μ§€μ •ν•œ μ‹œκ°„ 내에 ν•΄λ‹Ή λ©”μ†Œλ“œ μˆ˜ν–‰μ΄ μ™„λ£Œλ˜μ§€ μ•Šμ€ 경우 rollback μˆ˜ν–‰. -1일 경우 no timeout (Default = -1) @Transactional(timeout=10) 마치며 자칫 잘λͺ»ν–ˆλ‹€κ°€λŠ” μ›μΉ˜μ•ŠλŠ” νŠΈλžœμž­μ…˜μœΌλ‘œ 잘λͺ»λœ κ²°κ³Όλ₯Ό μ΄ˆλž˜ν• μˆ˜ μžˆκΈ°λ•Œλ¬Έμ— 기본값은 μˆ™μ§€ν•˜λŠ”κ²Œ 쒋을것 κ°™λ‹€.

spring4μ—μ„œ json view ν™œμš©ν•˜κΈ°(with @ResponseBody)

μˆ˜λ§Žμ€ λΈ”λ‘œκ±°λΆ„λ“€μ˜ 도움을 λ°›κ³ μž ꡬ글링을 ν•΄μ„œ μ μš©μ„ ν•΄λ΄€μ§€λ§Œ λ„ˆλ¬΄λ§Žμ€ μ‚½μ§ˆμ„ ν–ˆλ‹€.(ν•΄λ΄€λ˜ 방식은 jsonViewResolver λ₯Ό λ”°λ‘œ μ„€μ •ν•΄λ³΄κ±°λ‚˜, @RequestMapping μ˜΅μ…˜μ„ λ°”κΏ”λ³΄λŠ” μˆ˜μ€€..) νŠΉνžˆλ‚˜ Spring섀정방식이 μ˜ˆμ „ λ°©μ‹μ΄μ˜€λ˜ xml이 μ•„λ‹Œ javaconfigμ˜€κΈ° λ•Œλ¬Έμ— λ”μš±λ” μžλ£Œκ°€ μ—†μ—ˆκ³ .. ν•œμ°Έμ„ μ‚½μ§ˆν•˜λ‹€ 해결을 ν•˜μ—¬ ν¬μŠ€νŒ…ν•˜κ²Œ λœλ‹€. μš°μ„  ν™˜κ²½μ€ spring 4.3.4.RELEASE, Maven, jdk8μž„μ„ λ°νžŒλ‹€. pom.xml jackson-mapper-asl을 μ΄μš©ν•΄μ„œ ν•˜λΌλŠ” λΈ”λ‘œκ±°λ“€λ„ μžˆμ—ˆμ§€λ§Œ, 아무리해도(λ­”κ°€ Spring버전과 λ§žμ§€ μ•ŠλŠ”λ“― ν–ˆλ‹€.) 잘 μ•ˆλ˜μ–΄ μ•„λž˜μ™€ 같은 dependencyλ₯Ό μ£Όμ—ˆλ‹€. <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.1</version> </dependency> Controller μ•„λž˜μ™€κ°™μ΄ @ResponseBody μ–΄λ…Έν…Œμ΄μ…˜μ„ μ„€μ •ν•΄μ£Όκ³  리턴은 ν•΄λ‹Ή λͺ¨λΈμ„ λ„˜κΈ°λ©΄ λœλ‹€. @RequestMapping(value="/test") @ResponseBody public Map<String, Object> test(){ Map<String, Object> map = new HashMap<String, Object>(); map.put("1", "111"); map.put("2", 222); return map; } 그리고 ν˜ΈμΆœμ„ 해보면 κΈ°λŒ€ν–ˆλ˜κ²ƒμ²˜λŸΌ 이쁘게 jsonν˜•νƒœλ‘œ λ‚˜μ˜¨λ‹€. { "1": "111", "2": 222 } λ¬Όλ‘ , list λ‚˜ array, 일반 객체도 κ°€λŠ₯ν•˜λ‹€. 정리 μ‚½μ§ˆμ„ 끝에 μ•Œκ²Œλœ 사싀(?)을 μ •λ¦¬ν•΄λ³΄μž. λ‹€λ₯ΈμΈ‘λ©΄μ—μ„œ 뢄석을 해보면. @ResponseBody을 μ΄μš©ν•˜μ—¬ view 에 json ν˜•νƒœλ‘œ λ‚˜νƒ€λ‚΄κ³ μž ν•  경우 κ°€λŠ₯ν•œ 상황은 toString으둜 ν–ˆμ„λ•Œ jsonν˜•νƒœλ‘œ λ‚˜μ˜¬μˆ˜ 있으면 κ°€λŠ₯ν•˜λ‹€. μ˜ˆλ‘œλ“€μ–΄ μ•„λž˜μ²˜λŸΌ ν΄λž˜μŠ€μ— Lombok μ–΄λ…Έν…Œμ΄μ…˜μΈ @Dataκ°€ λΆ™μœΌλ©΄ μžλ™μœΌλ‘œ toString을 μ˜€λ²„λΌμ΄λ”© ν•΄μ£ΌκΈ° λ•Œλ¬Έμ— ν•΄λ‹Ή 클래슀λ₯Ό λ¦¬ν„΄ν•˜κ²Œλ˜λ©΄ μžλ™μœΌλ‘œ json μ²˜λ¦¬κ°€ λœλ‹€. @Data public Student{ private String id; private String name; ... } @ResponseBody을 뢙이고 List<Student>λ₯Ό λ¦¬ν„΄ν•˜κ²Œ 되면 μ—λŸ¬κ°€ λ‚˜λŠ”λ°, 이럴경우 별도 라이브러리λ₯Ό μΆ”κ°€ν•΄μ€˜μ•Ό μžλ™μœΌλ‘œ λ³€ν™˜λ˜μ–΄ json ν˜•νƒœλ‘œ λ‚˜μ˜¬μˆ˜ 있게 λœλ‹€. (list.toString을 ν•˜λ©΄ jsonν˜•νƒœκ°€ μ•„λ‹Œ μ΄μƒν•œ λ¬Έμžν˜•νƒœλ‘œ λ‚˜μ˜€κΈ° λ•Œλ¬Έ… Map같은것도 λ§ˆμ°¬κ°€μ§€ 이유둜 별도 라이브러리λ₯Ό μΆ”κ°€ν•΄μ€˜μ•Ό μ •μƒμ μœΌλ‘œ λ‚˜μ˜¨λ‹€.) 마치며 λ‹¨μˆœνžˆ @ResponseBodyλ₯Ό μ‚¬μš©ν•΄μ„œ json으둜 λ¦¬ν„΄ν•˜λ €λ©΄ μ–΄λ–€ 라이브러리λ₯Ό μΆ”κ°€ν•΄μ•Όν•œλ‹€ 둜 μƒκ°ν–ˆλ˜κ²ƒμ—μ„œ, 이것저것 ν…ŒμŠ€νŠΈ ν•œ κ²°κ³Ό toString을 ν• μˆ˜ μžˆμ–΄μ•Ό ν•˜κ³  κ·Έ 값이 jsonν˜•νƒœμ΄λ©΄ κ°€λŠ₯ν•˜λ‹€ 둜 결둠이 μ§€μ–΄μ‘Œλ‹€. ν™•μ‹€νžˆ μž₯λ‹˜ 코끼리 λ§Œμ§€λ“―μ΄ ‘κ·ΈλŸ°κ°€λ³΄λ‹€’ν•˜κ³  λ„˜μ–΄κ°€λ©΄ μ‚½μ§ˆμ΄ μ§„μ§œ λΆˆν•„μš”ν•œ μ‚½μ§ˆμ΄ λ˜λŠ”κ²ƒ κ°™λ‹€. ꡬ글링을 해보고, ν…ŒμŠ€νŠΈλ₯Ό ν•΄λ΄μ„œ, 결둠적으둜 λ‚΄κ²ƒμœΌλ‘œ λ§Œλ“œλŠ” μŠ΅κ΄€μ„ κ°€μ Έμ•Ό κ² λ‹€.

jsp include

1. λ””λ ‰ν‹°λΈŒλ°©μ‹ <%@ include file="~~"%> 정적 include 방식, μΈν΄λ£¨λ“œ λ˜λŠ” λ‚΄μš©μ΄ λ‹¨μˆœν•˜κ²Œ ν…μŠ€νŠΈλ‘œ ν¬ν•¨λ˜μ–΄ 컴파일이 λœλ‹€. (λ³΅μ‚¬λœλ‹€λŠ” λŠλ‚Œ) μ£Όμ˜ν• μ μ€ 비둝 ν¬ν•¨λ˜λŠ” νŽ˜μ΄μ§€λΌ ν•˜λ”λΌλ„ ν•œκΈ€μ„ μ œλŒ€λ‘œ μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄μ„œλŠ” ν¬ν•¨λ˜μ–΄μ§€λŠ” jsp파일 상단에 인코딩 λͺ…μ‹œλ₯Ό ν•΄μ€˜μ•Ό ν•œλ‹€. ν¬ν•¨λ˜μ–΄μ§€λŠ” jsp λ‚΄μš©μ΄ 변경이 될 경우 ν•΄λ‹Ή jspλ₯Ό μ‚¬μš©ν•˜λŠ” jspλ₯Ό κ°•μ œλ‘œ λ³€κ²½(touch) ν•΄μ€˜μ„œ λ‹€μ‹œ 컴파일이 되게 ν•΄μ•Όν•˜λŠ” λΆˆνŽΈν•¨μ΄ μžˆλ‹€. 정적 방식이기 λ•Œλ¬Έμ— μ˜ˆλ‘œλ“€μ–΄ μ „μ—­λ³€μˆ˜λ₯Ό μΈν΄λ£¨λ“œ λ˜λŠ” jspμ—μ„œ μ§€μ •ν•˜κ²Œ 되면 μƒμœ„jspμ—μ„œ μ‚¬μš©μ΄ κ°€λŠ₯ν•˜κ²Œ λœλ‹€. 2. μ•‘μ…˜νƒœκ·Έ 방식 <jsp:include page="~~"/> 동적 include 방식, ν¬ν•¨ν•˜λŠ” λ¬Έμ„œμ™€ 상관없이 λ™μ μœΌλ‘œ 컴파일 λœλ‹€. (μ™„μ „νžˆ λ³„λ„λ‘œ λ™μž‘ν•˜κΈ° λ•Œλ¬Έμ— λ³€μˆ˜λ₯Ό λ™μ‹œμ— μ‚¬μš©ν•˜λ €λ©΄ λ”°λ‘œ νŒŒλΌλ―Έν„°λ‘œ λ„˜κ²¨μ€˜μ•Ό ν•œλ‹€.) flush μ˜΅μ…˜μ€ μš”μ²­νλ¦„μ΄ λ„˜μ–΄κ°€λ©΄μ„œ ν˜„μž¬κΉŒμ§€ νŽ˜μ΄μ§€μ˜ κ²°κ³Όλ₯Ό 좜λ ₯ν•  것인지 말것인지λ₯Ό κ²°μ •ν•˜λŠ”κ²ƒμ΄λ‹€. 일반적으둜 false둜 μ„€μ •ν•œλ‹€. <jsp:param>λ₯Ό μ΄μš©ν•˜μ—¬ νŒŒλΌλ―Έν„°λ₯Ό μ „μ†‘ν• μˆ˜ μžˆλ‹€. <jsp:include page="..." flush="false"> <jsp:param name="name" value="이름" /> <jsp:param name="pageName" value="νŽ˜μ΄μ§€μ΄λ¦„"/> </jsp:include> 3. JSTL 방식 <c:import url="~~" /> JSTL(JSP Standard Tag Library) νƒœκ·Έμ€‘μ˜ ν•˜λ‚˜ 컴파일 되고 λ™μž‘ν•˜λŠ” 방식은 μ•‘μ…˜νƒœκ·Έ<jsp:include page="~~"/>와 κ°™μŒ ν˜„μž¬ μ»¨ν…Œμ΄λ„ˆ μ•ˆμ— μžˆλŠ” μžμ›μ™Έμ— λ‹€λ₯Έ μ™ΈλΆ€ μžμ›λ„ 포함이 κ°€λŠ₯ν•˜λ‹€. <c:import url="http://www.google.com/"/> μ•„λž˜μ™€ 같이 보닀 더 λ‹€μ–‘ν•œ μ˜΅μ…˜μ΄ μ œκ³΅λœλ‹€ <c:import! url="μ½μ–΄μ˜¬ URL" var="μ½μ–΄μ˜¬ 데이터λ₯Ό μ €μž₯ν•  λ³€μˆ˜λͺ…" scope="λ³€μˆ˜μ˜ 곡유 λ²”μœ„" varReader="λ¦¬μ†ŒμŠ€μ˜ λ‚΄μš©μ„ Reader 객체둜 μ½μ–΄μ˜¬ λ•Œ μ‚¬μš©" charEncoding="μ½μ–΄μ˜¨ λ°μ΄ν„°μ˜ 캐릭터셋 지정" />

2017 λ²„ν‚·λ¦¬μŠ€νŠΈ

μ˜¬ν•΄λ„ 어김없이(?) 1μ›” 1일이 λ˜μ–΄ ν•΄λ§žμ΄(해돋인지 ν•΄λ§žμΈμ§€ ν–‡κ°ˆλ¦¬μ§€λ§Œ, μƒˆν•΄ 첫날뢀터 λ³΅μž‘ν•΄μ§€κΈ° μ‹«λ‹Ή =ㅁ=)λ₯Ό λ‹€λ…€μ˜€κ³  κΉŒνŽ˜μ—μ„œ μƒˆν•΄ κ³„νšμ„ μ„Έμ›Œλ³Έλ‹€. 정말 μ§€ν‚¬μˆ˜ μžˆλŠ” κ³„νšλ“€, ν˜„μ‹€μ μΈ λΆ€λΆ„λ“€λ§Œ κ³ λ €ν•΄μ„œ 써내렀 κ°€λ³΄μž. 절반 μ΄μƒλ§Œμ΄λΌλ„ μ§€ν‚¬μˆ˜λ§Œ μžˆλ‹€λ©΄ κ·Έλ‚˜λ§ˆ 닀행이라고 생각! κΈ°μˆ λΈ”λ‘œκ·Έ μš΄μ˜ν•˜κΈ° : μ›” 2회 posting λ‚΄κ°€ μ•„λŠ”μ§€μ‹μ΄ μ–Όλ§ŒνΌμΈμ§€, 보여주기식이 μ•„λ‹Œ λ‚΄ 머릿속에 자리작고 μžˆλŠ” 뢀뢄듀을 μ •λ¦¬ν•΄μ„œ 기둝화 ν•˜λŠ” μ΄λ¦„ν•˜μ•Ό κΈ°μˆ λΈ”λ‘œκ·Έλ₯Ό μž‘μ„±ν•˜λŠ”κ±°λ‹€. 2주에 μ΅œμ†Œ ν•˜λ‚˜μ”©, μ΄λ ‡κ²Œ 되면 ν•œλ‹¬μ— μ΅œμ†Œ 2post, 1년이면 μ•½ 20post. μž‘λ‹€κ³  해도 마λƒ₯ μž‘κ²Œλ§Œ λŠκ»΄μ§€μ§€ μ•Šμ„ λΆ„λŸ‰μ΄λ‹€. μ‚¬μ†Œν•œκ±° ν•˜λ‚˜λΌλ„. 이λ₯Όν…Œλ©΄ μ„œλ²„ μ„€μΉ˜λ‚˜ μŠ€ν”„λ§μ˜ κΈ°λ³Έ μ„€μ • κ΄€λ ¨λœ 것듀도. κΈ€μ“°λŠ” μ—°μŠ΅λ„ ν•˜κ³  쒋은 κΈ°νšŒκ°€ 될것 κ°™λ‹€. 4λŒ€κ°• μ’…μ£Ό : μ˜μ‚°κ°•, 1λ°•2μΌμ½”μŠ€ 2014년에 ν•œκ°•(λΆν•œκ°•, λ‚¨ν•œκ°•), 2015년에 κΈˆκ°•, 2016λ…„μ—λŠ” λͺ»κ°”λ‹€. 4λŒ€κ°• μ’…μ£Όμ˜ λͺ©ν‘œκ°€ κ°‘μžκΈ° μ‹œλ“€μ–΄μ§„ μž‘λ…„μ΄λΌ 생각이 λ“ λ‹€. μš°μ—¬κ³‘μ ˆ μ‚°μ „μˆ˜μ „ λ‹€κ²ͺ은 λ‚΄ μžμ „κ±° λΆ•λΆ•μ΄μ—κ²Œ λ―Έμ•ˆν•˜μ§€ μ•ŠκΈ°μœ„ν•΄μ„œλΌλ„ μ˜¬ν•΄ μ—¬λ¦„μ—λŠ” κΌ­ μ˜μ‚°κ°•μ΄λ‚˜ 낙동강 ν•˜λ‚˜λ₯Ό κ³„νšμž‘μ•„ 1λ°•2일 μ½”μŠ€λ‘œ 닀녀와야겠닀. 음, λŒ€λž΅ 5μ›”? μ•„λ§ˆ μ˜μ‚°κ°•μ„ κ°€κ²Œλ κ²ƒκ°™λ‹€. μ΄λ²ˆμ—λŠ” λ¬΄λ¦¬ν•˜μ§€ μ•Šκ³  1λ°•2μΌμ½”μŠ€λ‘œ.. λ…μ„œ : μ›” 전곡1ꢌ, 전곡외1ꢌ μž‘λ…„μ— λ‚΄ μž…μ—μ„œ λ‚˜μ™”λ˜ 이야기듀쀑에 ν•œμ‹¬μŠ€λŸ½κ²Œ(?)λ‚˜μ˜¨ λ©˜νŠΈμ€‘ κ°€μž₯ λ§Žμ΄λ‚˜μ™”λ˜ μ±…μ’€μ½μž μ˜¬ν•΄μ—λŠ” 정말 λ§Žμ΄λŠ” 아닐지라도 μžμ£Όμ½λŠ” μŠ΅κ΄€μ„ κΈΈλŸ¬μ•Όκ² λ‹€. ν•œλ‹¬μ— 전곡책 ν•œκΆŒ, κΈ°νƒ€μ„œμ  ν•œκΆŒ. 얇은책+읽고싢은책 λΆ€ν„° 읽기 μ‹œμž‘ν•΄μ„œ λ‚΄λ…„ 1μ›”1μΌλ•ŒλŠ” λ‚΄ 책상 ν•œμΌ μ— μžλ¦¬μž‘κ³ μžˆλŠ” μ±…μž₯을 가득 λ©”μ›Œλ³΄κ³ μ‹Άλ‹€. μ•„, λ¬Όλ‘  λ‹€ 읽은 μ±…λ“€λ‘œλ§Œ. μ—¬ν–‰+사진 : ν•œλ‹¬μ— ν•œλ²ˆμ΄μƒ μ—¬ν–‰κ°€κΈ° ν•΄μ™Έλ“  κ΅­λ‚΄λ“ , μ˜¬ν•΄λŠ” 정말 많이 닀녀와야겠닀. κ°€λ³κ²Œ λ‹ΉμΌμΉ˜κΈ°λΆ€ν„° μ‹œμž‘ν•΄μ„œ 갈수만 μžˆλ‹€λ©΄ 해외여행도. λ¬Όλ‘  μ˜¬ν•΄λ„ μ•Όκ·Όκ³Όμ˜ 싸움은 κ³„μ†λ ν…Œμ§€λ§Œ 주말 μž κΉμ΄λΌλ„ μ‹œκ°„μ„ λ‚΄μ„œ 두달에?μ•„λ‹ˆ ν•œλ‹¬μ— ν•œλ²ˆμ΄λΌλ„ νœ΄κ°€λ₯Ό μ¨μ„œλΌλ„ κ°€κΉŒμš΄κ³³μ— νžλ§ν•˜λŸ¬ λ‹€λ…€μ˜€κ³  μ‹Άλ‹€. κ°€μ„œ μž‘λ…„μ— μ‚° μΉ΄λ©”λΌλ‘œ 사진도 이것저것 많이 찍고 쒋은좔얡 많이 λ§Œλ“€κ³ μ˜€κ³  μ‹Άλ‹€. μ €μΆ•+a : κ·Όκ²€μ ˆμ•½μ˜ μƒν™œν™”, κ²½μ œκ³΅λΆ€ λ‚˜λ¦„ μ›”κΈ‰μ˜ 60%이상을 μ €μΆ•ν•˜λŠ” 쀑이닀. 그치만 상황이 상황인지라 μ§€κΈˆλ„ λ§Œμ‘±ν•˜μ§€ λͺ»ν•œλ‹€. 천μž₯에 κ΅΄λΉ„ 달아놓고 κ°„μž₯찍어 λ¨ΉλŠ”λ‹€λŠ”κ²Œ μ•„λ‹ˆλΌ μ•„λ‚„μˆ˜ μžˆλŠ” 뢀뢄듀은 μ΅œλŒ€ν•œ μ•„λΌλ©΄μ„œ μ‚΄μžλŠ”κ±°λ‹€. 아침에 νƒμ‹œ 타지말고 쑰금 일찍 μΌμ–΄λ‚˜μ„œ λ²„μŠ€λ₯Ό νƒ„λ‹€λ˜μ§€, λ²„μŠ€λ₯Ό 타지말고 쑰금일찍 μΌμ–΄λ‚˜μ„œ μžμ „κ±°λ₯Ό νƒ„λ‹€λ˜μ§€(사싀 μžμ „κ±°λ₯Ό 타면 ν‡΄κ·Όν• λ•Œ 더 λΉ λ₯΄κ³  νŽΈν•˜κ²Œ 올수 μžˆμœΌλ‹ˆ) μƒν™œμ†μ—μ„œ μ ˆμ•½ν• μˆ˜ μžˆλŠ” 뢀뢄듀을 μ°Ύκ³ , λͺΈμ— 베도둝 μŠ΅κ΄€ν™” μ‹œμΌœμ•Όκ² λ‹€. 그리고 μ£Όμ‹μ΄λ‚˜ νŽ€λ“œ λ“± νˆ¬μžμ— λŒ€ν•΄μ„œλ„ 이제 곡뢀λ₯Ό 해봐야겠닀. (λ…μ„œν•˜μžλŠ”κ±°λž‘ λΉ„μŠ·ν•œ 이야기) μ €κΈˆλ¦¬μ‹œλŒ€ 마λƒ₯ μ €μΆ•λ§Œ ν•˜λ‹€λ³΄λ©΄ νž˜λ“ κ±΄ λˆ„κ΅¬λ‚˜ λ‹€ μ•„λŠ”μ΄μ•ΌκΈ°. 일에 μΉ˜μ—¬ μƒν™œμ— μΉ˜μ—¬ ν•‘κ³„λŒ€μ§€λ§κ³  λ°°μ›Œκ°€λ©΄μ„œ μ±™κ²¨λ³΄μž. μš΄λ™ : μžμœ ν˜•λ§ˆμŠ€ν„°, λͺΈμ§± 항상 ν•˜λŠ” μ΄μ•ΌκΈ°μ§€λ§Œ 건강보닀 μ€‘μš”ν•œκ±΄ μ—†λ‹€κ³  μƒκ°ν•œλ‹€. μ˜¬ν•΄μ—λ„ 병원가지 μ•ŠλŠ” λ‚˜λ₯Ό λ§Œλ“€κΈ° μœ„ν•΄ ν—¬μŠ€ + λ°°λ“œλ―Όν„΄ + 라이딩 은 ν•„μˆ˜κ³  κ°€λŠ₯ν•˜λ©΄ μˆ˜μ˜λ„ λ°°μ›Œμ„œ μžμœ ν˜• μ •λ„λŠ” ν• μˆ˜μžˆλŠ” λ‚˜λ₯Ό λ§Œλ“€κ³  μ‹Άλ‹€. κ·Έλž˜μ„œ λ‹€λ“€ λ§ν•˜λŠ” λͺΈμ§±λ„ 되보고 μ‹Άκ³  μžμ‹ μžˆκ²Œ ν•΄λ³€κ°€μ—μ„œ μƒμ˜λ₯Ό νƒˆμ˜ν• μˆ˜μžˆλŠ”(?!) κ±΄κ°•ν•œ λ‚΄κ°€ λ˜λ„λ‘ λ…Έλ ₯ν•΄μ•Όκ² λ‹€. λ΄‰μ‚¬ν™œλ™ν•˜κΈ° : 연탄배달, μžμ›λ΄‰μ‚¬ μž‘λ…„μ— ν•˜λ €λ‹€κ°€ λͺ»ν•œ λ΄‰μ‚¬ν™œλ™ μ˜¬ν•΄λŠ” κΌ­ ν•΄μ•Όκ² λ‹€. κ°€κΉκ²Œ ν• μˆ˜μžˆμ„λ²•ν•œκ²Œ 연탄배달, 이건 1월달 λ‚΄λ‘œ κΌ­! ν•΄μ„œ λ΄‰μ‚¬λΌλŠ”κ²ƒκ³Ό λ‚˜λˆ”μ΄λΌλŠ” 행볡을 느껴보고 μ‹Άλ‹€. μ§€κΈˆ μƒκ°λ‚˜λŠ”κ±΄ μžμ›λ΄‰μ‚¬ 같은것도 해보고 μ‹Άκ³  무보수 μ•Œλ°”(?) 같은것도 해보고싢닀. λ‚˜μ΄λ“€λ©΄ λͺ»ν• , μ–Έμ œ ν•΄λ³΄κ² λ‚˜. κ°€κΉŒμš΄, λ¨Ό μ‚¬λžŒλ“€ λ§Œλ‚˜κΈ° λ§ˆμ§€λ§‰μœΌλ‘œ, μžŠκ³ μžˆμ—ˆλ˜ μ€‘μš”ν•œ 행동. λ°”λ‘œ μ‚¬λžŒλ“€ λ§Œλ‚˜κΈ°λ‹€. λ°”μ˜λ‹€λŠ” 핑계 ν•˜λ‚˜λ§ŒμœΌλ‘œ λ“±ν•œμ‹œν•œ λ‚΄ μ†Œμ€‘ν•œ μ‚¬λžŒλ“€. 아무리 연봉을 많이 λ°›κ³  일을 μž˜ν•œλ‹€κ³  νšŒμ‚¬μ—μ„œ μž˜λ‚˜κ°„λ‹€ 할지라도, λ‚΄ 곁엔 λ‚˜λ₯Ό μƒκ°ν•΄μ£ΌλŠ” μ†Œμ€‘ν•œ μ‚¬λžŒλ“€μ΄ μžˆκΈ°μ— λ‚΄κ°€ μžˆμ„μˆ˜ μžˆλŠ”κ²ƒ κ°™λ‹€. κ°€κΉŒμš΄ μ‚¬λžŒλ“€λΆ€ν„° μ‹œμž‘ν•΄μ„œ μ˜€λž¬λ™μ•ˆ λͺ»λ΄€λ˜ μ‚¬λžŒλ“€λ„ ν•˜λ‚˜λ‘˜μ”© μ—°λ½ν•˜λ©΄μ„œ μ§€λ‚΄λŠ” μ—¬μœ λ₯Ό κ°€μ Έμ•Ό κ² λ‹€. ν• μˆ˜ μžˆμ„κΉŒ? λΌλŠ” 생각보닀 ν•˜λ‚˜λ‘˜μ”© μžŠμ§€λ§κ³ , λ†“μΉ˜μ§€ 말고 ν•˜λ£¨λ₯Ό, 이번주λ₯Ό, μ΄λ²ˆλ‹¬μ„ μ κ²€ν•˜κ³  μ‹€μ²œν•΄ λ‚˜κ°€λ³΄μž. 올 ν•œν•΄λ„ μ—΄μ‹¬νžˆ μ΅œμ„ μ„ λ‹€ν•΄ 살것!

2016 회고

2016λ…„, 내겐 정말 μˆ˜λ§Žμ€ 일듀이 μžˆμ—ˆκ³  κ·Έ μ–΄λŠλ•Œλ³΄λ‹€ (μ „μ—­ ν›„λ‘œ) λ―ΈμΉœλ“―μ΄ νšŒμ‚¬μ— μ§‘μ€‘ν–ˆλ˜ μ‹œκ°„λ“€λ‘œ κΈ°μ–΅λ‚œλ‹€. λ¬΄μž‘μ • λ‹€κ°€μ˜€λŠ” μƒˆν•΄λ₯Ό λ§žμ΄ν•˜λŠ”κ²ƒλ„ μ’‹μ§€λ§Œ 올 ν•œν•΄λ₯Ό λ˜λŒμ•„λ³΄λŠ” μ‹œκ°„μ„ κ°–κ³ , λ‚˜λ₯Ό λ‹€μ‹œ μ κ²€ν•΄λ³΄λŠ” μ°¨μ›μ—μ„œ 일λͺ… ‘회고’λ₯Ό ν•΄λ³ΌκΉŒ ν•œλ‹€. νšŒμ‚¬ 정말 μ—΄μ‹¬νžˆ ν–ˆλ‹€. μž˜ν–ˆλŠ”μ§€λŠ”… 잘 λͺ¨λ₯΄κ² λ‹€. λ‚œ μž˜ν•œκ²ƒ κ°™λ‹€. λ¬Όλ‘  λ‚΄ ν•˜λ£¨μ€‘μ— κ°€μž₯λ§Žμ€ μ‹œκ°„μ„ μŸμ€κ²ƒλ„ μžˆμ§€λ§Œ μž‘λ…„μ— 많이 ν•˜μ§€ λͺ»ν•˜λ˜κ²ƒμ„ ‘날씨’λΌλŠ” μ„œλΉ„μŠ€λ₯Ό ν™€λ‘œ λ§‘μœΌλ©΄μ„œ 정말 λ§Žμ€κ²ƒμ„ 배우고 결과물도 ν›„νšŒν•˜μ§€ μ•Šμ„λ§ŒνΌ λ‚˜μ˜¨κ²ƒ κ°™λ‹€. μ§€λ‚˜κ³ λ³΄λ©΄ ꡬ지 ν•˜μ§€ μ•Šμ•„λ„ 월급은 λ˜‘κ°™μ΄ λ‚˜μ˜¬ν…Œκ³ , μ‹œν‚€μ§€λ„ μ•Šμ•˜λŠ”λ° κ·Έμ‹œκ°„μ— μž μ„ 더 잀으면 ν•˜λŠ” 생각도 λ“€μ§€λ§Œ ν›„νšŒν•˜μ§€ μ•ŠλŠ”λ‹€. 아무도 μ—†λŠ” 사무싀 λ‚˜ν˜Όμž 12μ‹œλ„˜μ–΄μ„œ 퇴근을 해도 μ¦κ±°μ› μœΌλ‹ˆκΉŒ, κ·Έκ±°λ©΄ 됬닀. λͺ¨λ°”일 κ°œνŽΈμ΄λΌλŠ” 큰 업무λ₯Ό λ¬΄μ‚¬νžˆ(?) ν•΄μ³λ‚΄κ³ λŠ” μ‚¬λ‚΄μ—μ„œ 쑰직(μ„œλΉ„μŠ€)을 λ³€κ²½ν• μˆ˜ μžˆλŠ” κΈ°νšŒκ°€ λ˜μ–΄ λ‚˜ν™€λ‘œ 지원, λ‹€ν–‰μŠ€λŸ½κ²Œλ„ 합격을 ν•΄μ„œ μ§€κΈˆμ€ λ„€μ΄λ²„νŽ˜μ΄ 와 κ΄€λ ¨λœ 일을 ν•˜κ³ μžˆλŠ” 쀑이닀. κΈ°μ‘΄ μ„œλΉ„μŠ€μš΄μ˜μ„ ν•˜λ©΄μ„œ λŠλΌμ§€ λͺ»ν–ˆλ˜, 초기 섀계뢀터 μ‹œμž‘ν•˜μ—¬ μ–΄λ–€ κΈ°μˆ μŠ€νƒμ„ 쓸것인가에 λŒ€ν•œ 선택뢀터 λ‹€μ–‘ν•œ μ‹œν–‰μ°©μ˜€λ₯Ό 톡해 이제 ν•œ 두달 λ˜μ—ˆλŠ”λ° 정말 많이 배우고 μžˆλ‹€. λ„ˆλ¬΄ νž˜λ“€μ§€λ§Œ λ„ˆλ¬΄ ν–‰λ³΅ν•˜λ‹€. 돌이켜보면 μž‘μ‹¬μ‚ΌμΌλ‘œ 개발 κ΄€λ ¨λœ 곡뢀λ₯Ό λ“±ν•œμ‹œ ν•œκ²Œ λ„ˆλ¬΄ ν›„νšŒκ°€ λœλ‹€. λ°”μ˜λ‹€λŠ” μ΄μœ ν•˜λ‚˜λ§ŒμœΌλ‘œ (μ†”μ§νžˆ λ°”μ˜λ‹€λŠ”κ±΄ 핑계닀) κΈ°λŠ₯κ΅¬ν˜„μ—λ§Œ 신경을 μ¨μ™”λŠ”λ°, λ‚΄λ…„λΆ€ν„°λŠ” ν• μˆ˜λ§Œ μžˆλ‹€λ©΄ 업무 μ™Έμ μœΌλ‘œ λ‚˜λ§Œμ˜ 개발트리λ₯Ό μ„Έμ›Œλ³΄κ³  μ‹Άλ‹€. 건강 일주일에 ν•œλ²ˆ 이상 μ˜€μ „μ—” λ°°λ“œλ―Όν„΄, 저녁엔 ν—¬μŠ€μž₯μ—˜ κ°€λ €κ³  λ…Έλ ₯ν–ˆλ‹€. κ·Έ κ²°κ³Όμ˜€μ„κΉŒ, μ‚¬λž‘λ‹ˆ λΊ€κ±° λ§κ³ λŠ” 병원을 λ‹¨ν•œλ²ˆλ„ μ•ˆκ°”λ‹€. 감기쑰차 걸리지 μ•ŠλŠ”κ²Œ 닀행이라고 μƒκ°ν•˜μ§€λ§Œ, μš”μ¦˜λ“€μ–΄(야근이 λ§Žμ•„μ Έμ„œμΈμ§€) 책상에 μ•‰μ•„μžˆλŠ” μžμ„Έκ°€ λΆˆλŸ‰ν•΄μ„œ 거뢁λͺ©μ΄ λ˜κ°€κ³  μžˆλ‹€. νΌλ‘€λŸ¬λ„ κ΅¬λΉ„ν–ˆκ³  μ–΄κΉ¨ νŽ΄μ§€λΌκ³  λ°΄λ“œλ„ κ΅¬μž…ν•΄μ„œ μ‚¬μš©μ€ ν•˜λŠ”λ° 잘 μ‹€μ²œμ΄ μ•ˆλ˜λŠ” 쀑이닀. μž‘λ…„μ— μžμ „κ±°λ₯Ό μžƒμ–΄λ²„λ¦¬λ‹€ λ˜μ°Ύκ³ λŠ” μžμ „κ±°λ₯Ό λ“±ν•œμ‹œ ν•˜κ²Œ λ˜λŠ”κ²ƒ κ°™λ‹€. μ΄λ˜ν•œ 핑계겠지. λ‚΄λ…„μ—” κΌ­ 4λŒ€κ°•μ€‘ ν•˜λ‚˜ 작고 μ’…μ£Όν•œλ²ˆ ν•΄μ•Όκ²Ÿλ‹€. κΈ°ν•„μ½”.. μ•„λ§žλ‹€ μˆ˜μ˜λ„. γ… γ…  물에 뜨질 μ•ŠμœΌλ‹ˆ 큰일이닀… μ‚¬λžŒκ΄€κ³„ 학ꡐ선후배동기 및 동아리 μ‚¬λžŒλ“€, κ΅°λŒ€ 동기듀 및 μ†ŒλŒ€μ›λ“€ κ³Ό μ„ μž„ μž₯ꡐ뢄듀, 기타 λ“±λ“±… μ˜¬ν•΄ λ“€μ–΄μ„œμΈμ§€. 연락에 λ„ˆλ¬΄ λ¬΄μƒ‰ν• λ§ŒνΌ 잊고 μ‚΄μ•˜λ˜κ²ƒ κ°™λ‹€. μ§€λ‚˜κ³ λ³΄λ©΄ λ‹€λ₯Έκ³³μ— μ‹ κ²½μ“΄λ‹€κ³  연락을 λͺ»ν–ˆλ‹€κ³  핑계λ₯Ό λŒ€κ³  μžˆλŠ” λ‚˜μ΄μ§€λ§Œ, 또 ν•œνŽΈμœΌλ‘œλŠ” κ·Έ 연락 10λΆ„ μ‹œκ°„μ΄ μ—†λ‹€λŠ”κ±΄ … μ—­μ‹œλ‚˜ 핑계닀. λ‚˜λ₯Ό 도와주고 λ‚˜λ₯Ό λ―Ώμ–΄μ£Όκ³  λ‚˜λ₯Ό μƒκ°ν•΄μ£ΌλŠ” μ‚¬λžŒλ“€μ„ μ‘°κΈˆμ΄λΌλ„ 더 μ‹ κ²½μ¨μ„œ μ—°λ½ν•˜κ³  μ°Ύμ•„ λ΅™λŠ” μ‹œκ°„μ„ λ‚΄λ…„λΆ€ν„°μ„œλΌλ„ κ°€μ Έμ•Όκ² λ‹€. 마치며 일단 첫번째둜 λ‚΄λ…„λΆ€ν„° 할일은, 기술 λΈ”λ‘œκ·Έλ₯Ό μš΄μ˜ν•˜λŠ”κ²ƒμ΄λ‹€. μ†”μ§νžˆ 두달전 이 gitHub λ₯Ό μ΄μš©ν•΄μ„œ λΈ”λ‘œκ·Έλ₯Ό λ§Œλ“€κΈ΄ ν–ˆμ§€λ§Œ κ·Έλ‹₯ ν¬μŠ€νŒ…λ„ λͺ»ν–ˆκ³  방치 μˆ˜μ€€μ΄μ˜€μœΌλ‹ˆ… 적어도 ν•œλ‹¬μ— ν•œλ‘κ°œ μ •λ„λŠ” ν¬μŠ€νŒ… 해보렀고 λ…Έλ ₯ν•΄μ•Όκ²Ÿλ‹€. κΈ€μ“°λŠ”κ²Œ νž˜λ“€κ³  μ‹œκ°„μ΄ 많이 λ“€μ–΄κ°€λŠ” μž‘μ—…μ΄μ§€λ§Œ, 돌이켜 μƒκ°ν•˜λ©΄ λ‹€ λ‚΄ μžμ‚°μ΄κ³  λ‚˜λ₯Ό λ‹€μ‹œ λ°”λΌλ³Όμˆ˜ μžˆλŠ” κΈ°νšŒλ‹ˆκΉŒ. κΌ­ κΈ°μˆ λΈ”λ‘œκ·Έλ§Œμ΄ μ•„λ‹Œ, ν•˜λ£¨λ₯Ό κΈ°λ‘ν•˜λŠ” 무언가λ₯Ό ν•΄μ•Όκ² λ‹€. 막상 ν•œν•΄λ₯Ό λŒμ΄μΌœλ³΄λ‹ˆ κ·Έλ•ŒλŠ” λ­ν–ˆλŠ”μ§€ 기얡도 μ•ˆλ‚˜λ„€.. λ‘λ²ˆμ§Έλ‘œλŠ” μ§€ν‚¬μˆ˜ μžˆλŠ” κ³„νšμ„ μž‘λŠ”κ²ƒμ΄λ‹€. 올 ν•œν•΄ λͺ©ν‘œμ€‘에 이룬건 10κ°œμ€‘μ— 단 λ‘κ°œ… (그쀑에 λ…Έλž˜λŒ€νšŒλ‚˜κ°€κΈ°, μŠ€μΏ λ²„λ‹€μ΄λΉ™ ν•˜κΈ°, μžμœ ν˜• λ§ˆμŠ€ν„°ν•˜κΈ°λ„ μžˆλ‹€;;) λΆ€λ„λŸ½λ‹€.. 2016λ…„, λ‚˜λΌλ„ λ’€μˆ­μˆ­ ν•˜κ³  μ •μ‹ μ—†λ˜ ν•œν•΄μ˜€μ§€λ§Œ λ‚˜λ¦„ 의미있던 μ‹œκ°„λ“€μ„ 보낸것 κ°™μ•„ 닀행이라 μƒκ°ν•œλ‹€. 음,. 10μ λ§Œμ μ— 8점?? 2017λ…„! λ‹€μ‹œν•œλ²ˆ μΌμ–΄μ„œμž! ν™”μ΄νŒ…!!

Spring Transaction μ˜΅μ…˜

상황 μŠ€ν”„λ§ ν™˜κ²½μ—μ„œ 일반적으둜 DAO λ‚˜ BO λ ˆλ²¨μ—μ„œ λ‹€μŒκ³Ό 같이 코딩을 ν•˜κ²Œ λœλ‹€. @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public int method(int i) throws Exception { return sqlMapClient.delete("~~~~"); } λ¬΄λΆ„λ³„ν•˜κ²Œ Ctrl+C,V μ‹ κ³΅μœΌλ‘œ νŠΈλžœμž­μ…˜ μ–΄λ…Έν…Œμ΄μ…˜μ„ κ°€μ Έλ‹€κ°€ μ‚¬μš©ν• μˆ˜λ„ μžˆκ² μœΌλ‚˜, 각 값듀이 μ–΄λ–€ μ—­ν™œμ„ μ•„λŠ”μ§€μ— λŒ€ν•΄ μ•Œκ³  λ„˜μ–΄κ°ˆ ν•„μš”μ„±μ΄ μžˆλ‹€. @Transactional μš°μ„  ν•΄λ‹Ή μ–΄λ…Έν…Œμ΄μ…˜μ„ μ μš©ν•˜λ©΄ 적용된 클래슀 λ˜λŠ” λ©”μ†Œλ“œμ— νŠΈλžœμž­μ…˜μ΄ μ μš©λœλ‹€. λ”°λΌμ„œ 둜직 흐름에 λ§žμΆ”μ–΄ μ „μ²΄μ μœΌλ‘œ νŠΈλžœμž­μ…˜μ„ μ μš©ν• κ²ƒμΈμ§€, μ•„λ‹ˆλ©΄ νŠΉμ • λ©”μ†Œλ“œμ— μ μš©ν• κ²ƒμΈμ§€ μ „λž΅μ„ 잘 μ„Έμ›Œμ•Ό ν•œλ‹€. isolation κ²©λ¦¬μˆ˜μ€€μ΄λΌλŠ” μ˜΅μ…˜μ΄λ‹€. νŠΈλžœμž­μ…˜μ—μ„œ 일관성이 μ—†λŠ” 데이터λ₯Ό ν—ˆμš©ν•˜λ„λ‘ ν•˜λŠ” μˆ˜μ€€μ„ λ§ν•˜λŠ”λ° μ˜΅μ…˜μ€ λ‹€μŒκ³Ό κ°™λ‹€. READ_UNCOMMITTED (level 0) νŠΈλžœμž­μ…˜μ— μ²˜λ¦¬μ€‘μΈ ν˜Ήμ€ 아직 μ»€λ°‹λ˜μ§€ μ•Šμ€ 데이터λ₯Ό λ‹€λ₯Έ νŠΈλžœμž­μ…˜μ΄ μ½λŠ” 것을 ν—ˆμš© μ–΄λ–€ μ‚¬μš©μžκ°€ AλΌλŠ” 데이터λ₯Ό BλΌλŠ” λ°μ΄ν„°λ‘œ λ³€κ²½ν•˜λŠ” λ™μ•ˆ λ‹€λ₯Έ μ‚¬μš©μžλŠ” BλΌλŠ” 아직 μ™„λ£Œλ˜μ§€ μ•Šμ€(Uncommitted ν˜Ήμ€ Dirty) 데이터 Bλ₯Ό 읽을 수 μžˆλ‹€. Dirty read : μœ„μ™€ 같이 λ‹€λ₯Έ νŠΈλžœμž­μ…˜μ—μ„œ μ²˜λ¦¬ν•˜λŠ” μž‘μ—…μ΄ μ™„λ£Œλ˜μ§€ μ•Šμ•˜λŠ”λ°λ„ λ‹€λ₯Έ νŠΈλžœμž­μ…˜μ—μ„œ λ³Ό 수 μžˆλŠ” ν˜„μƒμ„ dirty read 라고 ν•˜λ©°, READ UNCOMMITTED κ²©λ¦¬μˆ˜μ€€μ—μ„œλ§Œ μΌμ–΄λ‚˜λŠ” ν˜„μƒ READ_COMMITTED (level 1) dirty read 방지 : νŠΈλžœμž­μ…˜μ΄ μ»€λ°‹λ˜μ–΄ ν™•μ •λœ λ°μ΄ν„°λ§Œμ„ μ½λŠ” 것을 ν—ˆμš© μ–΄λ– ν•œ μ‚¬μš©μžκ°€ AλΌλŠ” 데이터λ₯Ό BλΌλŠ” λ°μ΄ν„°λ‘œ λ³€κ²½ν•˜λŠ” λ™μ•ˆ λ‹€λ₯Έ μ‚¬μš©μžλŠ” ν•΄λ‹Ή 데이터에 μ ‘κ·Όν•  수 μ—†λ‹€. REPEATABLE_READ (level 2) νŠΈλžœμž­μ…˜μ΄ μ™„λ£Œλ  λ•ŒκΉŒμ§€ SELECT λ¬Έμž₯이 μ‚¬μš©ν•˜λŠ” λͺ¨λ“  데이터에 shared lock이 κ±Έλ¦¬λ―€λ‘œ λ‹€λ₯Έ μ‚¬μš©μžλŠ” κ·Έ μ˜μ—­μ— ν•΄λ‹Ήλ˜λŠ” 데이터에 λŒ€ν•œ μˆ˜μ •μ΄ λΆˆκ°€λŠ₯ν•˜λ‹€. μ„ ν–‰ νŠΈλžœμž­μ…˜μ΄ 읽은 λ°μ΄ν„°λŠ” νŠΈλžœμž­μ…˜μ΄ μ’…λ£Œλ  λ•ŒκΉŒμ§€ ν›„ν–‰ νŠΈλžœμž­μ…˜μ΄ κ°±μ‹ ν•˜κ±°λ‚˜ μ‚­μ œν•˜λŠ” 것을 λΆˆν—ˆν•¨μœΌλ‘œμ¨ 같은 데이터λ₯Ό 두 번 μΏΌλ¦¬ν–ˆμ„ λ•Œ 일관성 μžˆλŠ” κ²°κ³Όλ₯Ό 리턴함 SERIALIZABLE (level 3) μ™„λ²½ν•œ 읽기 일관성 λͺ¨λ“œλ₯Ό 제곡 λ°μ΄ν„°μ˜ 일관성 및 λ™μ‹œμ„±μ„ μœ„ν•΄ MVCC(Multi Version Concurrency Control)을 μ‚¬μš©ν•˜μ§€ μ•ŠμŒ(MVCCλŠ” 닀쀑 μ‚¬μš©μž λ°μ΄ν„°λ² μ΄μŠ€ μ„±λŠ₯을 μœ„ν•œ 기술둜 데이터 쑰회 μ‹œ LOCK을 μ‚¬μš©ν•˜μ§€ μ•Šκ³  λ°μ΄ν„°μ˜ 버전을 관리해 λ°μ΄ν„°μ˜ 일관성 및 λ™μ‹œμ„±μ„ λ†’μ΄λŠ” 기술) νŠΈλžœμž­μ…˜μ΄ μ™„λ£Œλ  λ•ŒκΉŒμ§€ SELECT λ¬Έμž₯이 μ‚¬μš©ν•˜λŠ” λͺ¨λ“  데이터에 shared lock이 κ±Έλ¦¬λ―€λ‘œ λ‹€λ₯Έ μ‚¬μš©μžλŠ” κ·Έ μ˜μ—­μ— ν•΄λ‹Ήλ˜λŠ” 데이터에 λŒ€ν•œ μˆ˜μ • 및 μž…λ ₯이 λΆˆκ°€λŠ₯ν•˜λ‹€. propagation ( μ „νŒŒμ˜΅μ…˜) REQUIRED : λΆ€λͺ¨ νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ μ‹€ν–‰ν•˜λ©° λΆ€λͺ¨ νŠΈλžœμž­μ…˜μ΄ 없을 경우 μƒˆλ‘œμš΄ νŠΈλžœμž­μ…˜μ„ 생성 REQUIRES_NEW : λΆ€λͺ¨ νŠΈλžœμž­μ…˜μ„ λ¬΄μ‹œν•˜κ³  무쑰건 μƒˆλ‘œμš΄ νŠΈλžœμž­μ…˜μ΄ 생성 SUPPORT : λΆ€λͺ¨ νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ μ‹€ν–‰ν•˜λ©° λΆ€λͺ¨ νŠΈλžœμž­μ…˜μ΄ 없을 경우 nontransactionally둜 μ‹€ν–‰ MANDATORY : λΆ€λͺ¨ νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ μ‹€ν–‰λ˜λ©° λΆ€λͺ¨ νŠΈλžœμž­μ…˜μ΄ 없을 경우 μ˜ˆμ™Έκ°€ λ°œμƒ NOT_SUPPORT : nontransactionally둜 μ‹€ν–‰ν•˜λ©° λΆ€λͺ¨ νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ 싀행될 경우 μΌμ‹œ 정지 NEVER : nontransactionally둜 μ‹€ν–‰λ˜λ©° λΆ€λͺ¨ νŠΈλžœμž­μ…˜μ΄ μ‘΄μž¬ν•œλ‹€λ©΄ μ˜ˆμ™Έκ°€ λ°œμƒ NESTED : ν•΄λ‹Ή λ©”μ„œλ“œκ°€ λΆ€λͺ¨ νŠΈλžœμž­μ…˜μ—μ„œ 진행될 경우 λ³„κ°œλ‘œ μ»€λ°‹λ˜κ±°λ‚˜ 둀백될 수 있음. λ‘˜λŸ¬μ‹Ό νŠΈλžœμž­μ…˜μ΄ 없을 경우 REQUIRED와 λ™μΌν•˜κ²Œ μž‘λ™ no-rollback-for - μ˜ˆμ™Έμ²˜λ¦¬ (κΈ°λ³Έκ°’ : μ—†μŒ) νŠΉμ • μ˜ˆμ™Έκ°€ λ°œμƒν•˜λ”λΌλ„ λ‘€λ°±λ˜μ§€ μ•Šλ„λ‘ μ„€μ • μŠ€ν”„λ§ λ°°μΉ˜μ—μ„œμ˜ νŠΈλžœμž­μ…˜ (λ‚΄κ°€ λ‹Ήν–ˆλ˜(?) 문제) μŠ€ν”„λ§ λ°°μΉ˜μ—μ„œλŠ” Tasklet μ—μ„œ 기본적으둜 step λ‹¨μœ„ νŠΈλžœμž­μ…˜μ„ μ§€μ›ν•˜κ³  μžˆλ‹€κ³  ν•œλ‹€. 기본적으둜 job이 ν•˜λ‚˜μ˜ tasklet 의 step 으둜 μ‹€ν–‰ν•˜λ‹€λ³΄λ‹ˆ λͺ…μ‹œμ μ΄μ§„ μ•Šμ§€λ§Œ λ‚΄λΆ€μ μœΌλ‘œ 전체 νŠΈλžœμž­μ…˜μœΌλ‘œ 걸렀있게 λœλ‹€. λ‚˜κ°™μ€ job λ‚΄ DAO delete λ©”μ†Œλ“œμ—μ„œ @Transactional 섀정을 ν•˜κ³  κ·Έ DAO λ©”μ†Œλ“œλ₯Ό λ°˜λ³΅λ¬Έμ— μ˜ν•΄ delete ν•˜λŠ” λ‘œμ§μ„ μˆ˜ν–‰ν•˜λŠ” 뢀뢄이 μžˆμ—ˆλŠ”λ° λΆ€λͺ¨μ˜ νŠΈλžœμž­μ…˜(taskletμ—μ„œ μ„€μ •λœ νŠΈλžœμž­μ…˜)으둜 인해 dao λ₯Ό λͺ‡λ²ˆ ν˜ΈμΆœν•˜λ˜ jobλ‹¨μœ„λ‘œ νŠΈλ Œμ μ…˜μ΄ 걸리게 λ˜μ—ˆλ‹€. (κ²°κ΅­ νŠΈλžœμž­μ…˜μ€ 반볡문이 λ‹€ λλ‚˜μ•Ό 적용이 λœλ‹€λŠ”μ .) κ·ΈλŸ¬λ‹€λ³΄λ‹ˆ 가끔 DB Query Lock이 κ±Έλ ΈλŠ”λ° DBλ ˆλ²¨μ—μ„œ undologλ₯Ό λ‚¨κΈ°λŠ”κ²Œ λ„ˆλ¬΄ λ¬΄κ±°μ›Œμ Έ lock이 λ°œμƒ λ”°λΌμ„œ μ „νŒŒμ˜΅μ…˜μ„ μˆ˜μ •ν•΄μ„œ ν•΄λ‹Ή 문제λ₯Ό ν•΄κ²°ν•˜μ˜€λ‹€. # κΈ°μ‘΄ begin delete < for 반볡문 commit # μ „νŒŒμ˜΅μ…˜ μˆ˜μ • (κΈ°μ‘΄ REQUIRES μ—μ„œ REQUIRES_NEW 으둜 μˆ˜μ •) for begin delete commit for end

λ””μžμΈνŒ¨ν„΄-싱글톀

λ””μžμΈ νŒ¨ν„΄μ€‘μ— κ°€μž₯ 잘 μ•Œλ €μ§„ 싱글톀 에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄κ³ μž ν•œλ‹€. λ©€ν‹° μŠ€λ ˆλ“œ ν™˜κ²½μ—μ„œ 자주 μ΄μš©λ˜λŠ” νŒ¨ν„΄μ΄λΌκ³ λ§Œ λ“€μ—ˆλŠ”λ° 이번 기회λ₯Ό 톡해 μ œλŒ€λ‘œ μ •λ¦¬ν•΄λ³΄μž 싱글톀이 무엇인가 싱글톀(Singleton)은 μ •ν™•νžˆ ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ§Œ μƒμ„±λ˜λŠ” ν΄λž˜μŠ€μ΄λ‹€. 라고 μ΄νŽ™ν‹°λΈŒ μžλ°”μ—μ„œ μ •μ˜λ˜μ–΄μžˆλ‹€. 즉, λ”± ν•˜λ‚˜λ§Œ μƒμ„±ν•˜κ³  이λ₯Ό μ—¬κΈ°μ €κΈ°μ„œ μ‚¬μš©ν•˜λŠ” νŒ¨ν„΄μ΄λΌ μƒκ°ν•˜λ©΄ 될듯 ν•˜λ‹€. μ‹±κΈ€ μŠ€λ ˆλ“œ ν™˜κ²½μ—μ„œλŠ” λ‹Ήμ—°νžˆ μΈμŠ€ν„΄μŠ€λ₯Ό κ³΅μœ ν•  상황이 μ—†κ² μ§€λ§Œ λŒ€λΆ€λΆ„ λ©€ν‹° μŠ€λ ˆλ“œ ν™˜κ²½μ΄κΈ° λ•Œλ¬Έμ— 싱글톀 νŒ¨ν„΄μ€ μ•„μ£Ό μ€‘μš”ν•œ 뢀뢄이닀. μ•„μ£Ό 고전적인 방법 (μœ„ν—˜ν•œ 방법) public class Singleton { private static Singleton uniqueInstance; private Singleton(){} public static Singleton getInstance(){ if (uniqueInstance == null){ uniqueInstance = new Singleton(); } return uniqueInstance; } } μœ„μ™€ 같은 μƒν™©μ—μ„œ ifμ ˆμ„ λ„λ‹¬ν•˜λŠ” μ‹œμ μ΄ 각 μŠ€λ ˆλ“œλ§ˆλ‹€ λ‹€λ₯Όκ²½μš° λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆλ‹€.(κ΅λ¬˜ν•œ μ‹œμ μ— 객체가 1개 이상 λ°˜ν™˜λ  여지가 있음) 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œλŠ” λ‹€μŒκ³Ό 같이 getInstance()λ₯Ό 동기화 ν•΄μ£Όλ©΄ λœλ‹€. ν•˜μ§€λ§Œ λΆˆν•„μš”ν•˜κ²Œ 동기화 ν•˜λŠ” μ˜€λ²„ν—€λ“œλ§Œ μ¦κ°€ν•˜κ²Œ λœλ‹€. public class Singleton { private static Singleton uniqueInstance; private Singleton(){} public static synchronized Singleton getInstance(){ if (uniqueInstance == null){ uniqueInstance = new Singleton(); } return uniqueInstance; } } public static μΈμŠ€ν„΄μŠ€λ‘œ 생성 public static final LocalCache sharedObject = new LocalCache(); private LocalCache() { } μ΄μ½”λ“œλŠ” κ°„λ‹¨ν•˜λ‹€λŠ” μž₯점이 μžˆλŠ” λ°˜λ©΄μ— μœ μ—°ν•˜μ§€ λͺ»ν•œ 뢀뢄이 μžˆλ‹€. (μ•„λž˜ μ΄μ–΄μ„œ μ„€λͺ…) private static final μΈμŠ€ν„΄μŠ€λ‘œ 생성 private static final LocalCache sharedObject = new LocalCache(); private LocalCache() { } public static LocalCache getInstance() { return sharedObject ; } μ΄λ ‡κ²Œ ν•˜λ©΄ factory λ©”μ†Œλ“œλ₯Ό 톡해 객체λ₯Ό λ°˜ν™˜λ°›κ³ , λ°˜ν™˜ λ°›λŠ” μ‹œμ μ— λ‹€μ–‘ν•œ μž‘μ—…λ“€μ„ ν• μˆ˜ μžˆλ‹€. enum 으둜 생성 public enum LocalCacheEnum { LocalCache; //etc another functions } 잘 μ‚¬μš©ν•˜μ§€λŠ” μ•Šμ§€λ§Œ κ°€μž₯ 쒋은 μ„Έλ²ˆμ§Έ 방법인 enum으둜 클래슀λ₯Ό λ§Œλ“œλŠ” 방법이라고 ν•œλ‹€. λ³΅μž‘ν•œ μ§λ ¬ν™”λ‚˜ λ¦¬ν”Œλ ‰μ…˜(reflection) μƒν™©μ—μ„œλ„ 직렬화가 μžλ™μœΌλ‘œ μ§€μ›λ˜κ³ , μΈμŠ€ν„΄μŠ€κ°€ μ—¬λŸ¬κ°œ 생기지 μ•Šλ„λ‘ ν™•μ‹€ν•˜κ²Œ 보μž₯해쀀단닀. (by effective java) 그럼 μ–΄λ””μ„œ μ‚¬μš©λ κΉŒ static 으둜 μ„ μ–Έν•΄μ„œ κ³΅ν†΅μ μœΌλ‘œ μ‚¬μš©λ˜λŠ” λΆ€λΆ„μ΄λ‚˜ ν™˜κ²½μ„€μ • λ‚΄μš©μ΄ λ³€κ²½λ˜λ©΄ λ‹€λ₯Έ ν΄λž˜μŠ€μ—μ„œλ„ κ·Έ 뢀뢄이 λ˜‘κ°™μ΄ μ μš©λ˜μ–΄ μ‹€ν–‰λ˜μ–΄μ•Ό ν• λ•Œ 자주 μ‚¬μš©λ˜λŠ” 뢀뢄을 μ‹±κΈ€ν†€μœΌλ‘œ λ§Œλ“€μ–΄ μƒμ„±λ˜λŠ” μ‹œκ°„μ„ μ€„μΌλ•Œ μŠ€ν”„λ§μ—μ„œμ˜ DB컀λ„₯μ…˜ 둜직

hexo ν™˜κ²½ κ΅¬μΆ•ν•˜κΈ°

κ°œμš” μ΄μ „ν¬μŠ€νŒ… μ—μ„œ 이야기 ν•œκ²ƒκ³Ό 같이 μ–΄λŠκ³³μ—μ„œλ“ μ§€(집 λ˜λŠ” νšŒμ‚¬ λ“±) λΈ”λ‘œκ·Έ ν¬μŠ€νŒ…μ„ ν• μˆ˜ μžˆλŠ” ν™˜κ²½μ„ λ§Œλ“€κ³  μ‹Άμ—ˆλ‹€. (git을 μ΄μš©ν•΄μ„œ.) κ·Έλž˜μ„œ git repository λ₯Ό λ‘κ°œλ₯Ό λ§Œλ“€μ—ˆκ³ , ν•˜λ‚˜λŠ” μ‹€μ œ λΈ”λ‘œκ·Έμ„œλ²„λ‘œ μ΄μš©ν•˜κ³  ν•˜λ‚˜λŠ” λΈ”λ‘œκ·Έλ₯Ό ν¬μŠ€νŒ…ν•˜λŠ” hexo ν™˜κ²½μ„ μ €μž₯ν•˜κ²Œ λœλ‹€. μ§€κΈˆλΆ€ν„° 이야기 ν•  λ‚΄μš©μ€ hexoν™˜κ²½μ„ git repository μ—μ„œ pull λ°›μ•„μ„œ ν™˜κ²½κ΅¬μ„±ν•˜λŠ” 뢀뢄을 이야기 ν•˜λ €κ³  ν•œλ‹€. ν™˜κ²½κ΅¬μ„± hexoμ„€μΉ˜μ™€ gitμ„€μΉ˜λŠ” λ˜μ–΄μžˆλ‹€κ³  κ°€μ •. λ¨Όμ € ꡬ성할 폴더λ₯Ό μƒμ„±ν•˜κ³  이 폴더에 hexo ν™˜κ²½μ„ κ΅¬μ„±ν•˜κ² λ‹€κ³  초기 μ…‹νŒ…μ„ ν•œλ‹€ mkdir blog hexo init blog 그리고 hexoν™˜κ²½μ„ μ €μž₯ν•΄λ‘” repositoryλ₯Ό 가져와야 ν•˜λ―€λ‘œ git섀정을 ν•œλ‹€ cd blog/ git init git remote add origin https://github.com/taetaetae/hexo.git git fetch ν•„μš”μ—†λŠ”μ΄ˆκΈ°μ…‹νŒ…μ΄ λ˜λŠ” νŒŒμΌμ€ μ§€μš°κ³  rm source/_posts/hello-world.md rm -r themes/landscape/ #ν•΄λ‹Ή ν…Œλ§ˆλ₯Ό μ‚¬μš©ν•˜κ³  μžˆλ‹€λ©΄ μ§€μšΈν•„μš”κ°€ μ—†λ‹€. hexoν™˜κ²½ repository λ₯Ό pullλ°›λŠ”λ‹€ git reset --hard origin/master git pull origin master huemanν…Œλ§ˆμ˜ 검색 κΈ°λŠ₯을 μ‚¬μš©ν•œλ‹€λŠ” κ°€μ •ν•˜μ— ν•„μš”ν•œ ν”ŒλŸ¬κ·ΈμΈκ³Ό, λ‚˜μ€‘μ— deploy ν• λ•Œ ν•„μš”ν•œ ν”ŒλŸ¬κ·ΈμΈμ„ μ„€μΉ˜ν•΄μ€€λ‹€ npm install hexo-deployer-git --save npm install -S hexo-generator-json-content μ΄λ ‡κ²Œ 되면 기쑴처럼 ν™˜κ²½μ„€μ •μ΄ 마무리 되고, ν¬μŠ€νŒ…μ„ ν• μˆ˜ 있게 λœλ‹€. μΆ”κ°€ canonical 속성 npm install –save hexo-auto-canonical μ‚¬μ΄νŠΈλ§΅ 속성 npm install hexo-generator-seo-friendly-sitemap –save feed 속성 npm install hexo-generator-feed –save