โถ 3์ผ ๊ณํ
=> ๊ณต๋ถ ๊ด๋ จ
1) ์์ (18์ผ ์์ ) ๋ด์ฉ ๋ณต์ต
2) MVC ๊ฐ์ ๊ฒฐ์
3) ์คํ๋ง ๊ธฐ์ ์๊ฐ
4) MVC ๊ฐ์ ์๊ฐ
=> ์ทจ์ค
1) ๋ฆฌํฉํ ๋ง ๋ง๋ฌด๋ฆฌ ํ ๊น ํธ์ฌ
2) ๋ฏธํก ์ง๋ฌธ ๋ต๋ณ ์ฑ์ฐ๊ธฐ(ํ ๋ฌธ์ฅ์ผ๋ก ์ ๋ฆฌ)
3) ์๊ฐ ๊ฐ์ ๋ด์ฉ ๋ ธ์ ์ ๋ฆฌ
โถ ๋ฌธ์ ์ ๋ฆฌ
1. JoinPoint & PointCut์ ๊ฐ๋ ํผ๋
์กฐ์ธํฌ์ธํธ๊ฐ ๋ฉํ์ ์ธ ์ ๋ณด๋ผ๊ณ ์๊ฐํ๋ฉด ๋๊ณ ํฌ์ธํธ์ปท์ด ์ข ๋ ๊ตฌ์ฒด์ ์ธ ์ ์ฉ ์ง์ ์ด๋ค!
2. MVC ๋ฆฌํฉํ ๋ง์์ Computer ๊ฐ์ฒด ์ฃผ์ ์์ ์ ๋ฌธ์
โถ ๊ฐ์ธ ๊ณต๋ถ
๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ ์ถ์ํ: Converter์ Formatter
public class EventConverter {
public static class StringToEventConverter implements Converter<String, Event> {
@Override
public Event convert(String source) {
return new Event(Integer.parseInt(source));
}
public static class EventToStringConverter implements Converter<Event, String>{
@Override
public String convert(Event source) {
return source.getId().toString();
}
}
}
}
=> Event, String Type๊ฐ์ ์ปจ๋ฒํ ํ๋ ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ํ ๋ชจ์ต
@Component
public class AppRunner implements ApplicationRunner {
@Autowired
EventService eventService;
@Override
public void run(ApplicationArguments args) throws Exception {
eventService.createEvent();
eventService.publishEvent();
eventService.deleteEvent();
}
}
=> service ๊ฐ์ฒด๋ก ๋ฉ์๋ ํธ์ถ
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface PerfLogging {
}
=> ํ๊ฒ ๋ฉ์๋๋ฅผ ์ํ ์๋ํ ์ด์ ์ ์
@Retention์ ์์ฑ
1. Runtime ์ ๊น์ง ์ ์ง
2. Class ๋ฐ์ดํธ ์ฝ๋ ๋ก๋ ๋ ๋๊น์ง ์ ์ง
3. Source ์์ค ์ฝ๋ ์ํ ์ ์ง
โ ๊ฐ์ ์ ๋ฆฌ โ
๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ ์ถ์ํ: Converter์ Formatter
Converter
โ S ํ์ ์ T ํ์ ์ผ๋ก ๋ณํํ ์ ์๋ ๋งค์ฐ ์ผ๋ฐ์ ์ธ ๋ณํ๊ธฐ.
โ ์ํ ์ ๋ณด ์์ == Stateless == ์ฐ๋ ๋์ธ์ดํ
โ ConverterRegistry์ ๋ฑ๋กํด์ ์ฌ์ฉ
public class StringToEventConverter implements Converter<String, Event> {
@Override
public Event convert(String source) {
Event event = new Event();
event.setId(Integer.parseInt(source));
return event;
}
}
Formatter
โ PropertyEditor ๋์ฒด์
โ Object์ String ๊ฐ์ ๋ณํ์ ๋ด๋นํ๋ค.
โ ๋ฌธ์์ด์ Locale์ ๋ฐ๋ผ ๋ค๊ตญํํ๋ ๊ธฐ๋ฅ๋ ์ ๊ณตํ๋ค. (optional)
โ FormatterRegistry์ ๋ฑ๋กํด์ ์ฌ์ฉ
public class EventFormatter implements Formatter<Event> {
@Override
public Event parse(String text, Locale locale) throws ParseException {
Event event = new Event();
int id = Integer.parseInt(text);
event.setId(id);
return event;
}
@Override
public String print(Event object, Locale locale) {
return object.getId().toString();
}
}
ConversionService
โ ์ค์ ๋ณํ ์์ ์ ์ด ์ธํฐํ์ด์ค๋ฅผ ํตํด์ ์ฐ๋ ๋-์ธ์ดํํ๊ฒ ์ฌ์ฉํ ์ ์์.
โ ์คํ๋ง MVC, ๋น (value) ์ค์ , SpEL์์ ์ฌ์ฉํ๋ค.
โ DefaultFormattingConversionService
โ FormatterRegistry
โ ConversionService
โ ์ฌ๋ฌ ๊ธฐ๋ณธ ์ปด๋ฒํฐ์ ํฌ๋งคํฐ ๋ฑ๋ก ํด ์ค.
์คํ๋ง ๋ถํธ
โ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ธ ๊ฒฝ์ฐ์ DefaultFormattingConversionSerivce๋ฅผ ์์ํ์ฌ ๋ง๋ WebConversionService๋ฅผ ๋น์ผ๋ก ๋ฑ๋กํด ์ค๋ค.
โ Formatter์ Converter ๋น์ ์ฐพ์ ์๋์ผ๋ก ๋ฑ๋กํด ์ค๋ค
SpEL (์คํ๋ง Expression Language)
์คํ๋ง EL์ด๋?
โ ๊ฐ์ฒด ๊ทธ๋ํ๋ฅผ ์กฐํํ๊ณ ์กฐ์ํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
โ Unified EL๊ณผ ๋น์ทํ์ง๋ง, ๋ฉ์๋ ํธ์ถ์ ์ง์ํ๋ฉฐ, ๋ฌธ์์ด ํ ํ๋ฆฟ ๊ธฐ๋ฅ๋ ์ ๊ณตํ๋ค.
โ OGNL, MVEL, JBOss EL ๋ฑ ์๋ฐ์์ ์ฌ์ฉํ ์ ์๋ ์ฌ๋ฌ EL์ด ์์ง๋ง, SpEL์ ๋ชจ๋ ์คํ๋ง ํ๋ก์ ํธ ์ ๋ฐ์ ๊ฑธ์ณ ์ฌ์ฉํ EL๋ก ๋ง๋ค์๋ค.
โ ์คํ๋ง 3.0 ๋ถํฐ ์ง์.
SpEL ๊ตฌ์ฑ
โ ExpressionParser parser = new SpelExpressionParser()
โ StandardEvaluationContext context = new StandardEvaluationContext(bean)
โ Expression expression = parser.parseExpression(“SpEL ํํ์”)
โ String value = expression.getvalue(context, String.class)
๋ฌธ๋ฒ
โ #{“ํํ์"}
โ ${“ํ๋กํผํฐ"}
โ ํํ์์ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง ์ ์์ง๋ง, ๋ฐ๋๋ ์ ๋จ. โ #{${my.data} + 1}
โ ๋ ํผ๋ฐ์ค ์ฐธ๊ณ
์ค์ ๋ก ์ด๋์ ์ฐ๋?
โ @Value ์ ๋ ธํ ์ด์
โ @ConditionalOnExpression ์ ๋ ธํ ์ด์
โ ์คํ๋ง ์ํ๋ฆฌํฐ
โ ๋ฉ์๋ ์ํ๋ฆฌํฐ, @PreAuthorize, @PostAuthorize, @PreFilter, @PostFilter โ XML ์ธํฐ์ ํฐ URL ์ค์ โ ...
โ ์คํ๋ง ๋ฐ์ดํฐ
โ @Query ์ ๋ ธํ ์ด์
โ Thymeleaf โ ...
์คํ๋ง AOP: ๊ฐ๋ ์๊ฐ
Aspect-oriendted Programming (AOP)์ OOP๋ฅผ ๋ณด์ํ๋ ์๋จ์ผ๋ก, ํฉ์ด์ง Aspect๋ฅผ ๋ชจ๋ํ ํ ์ ์๋ ํ๋ก๊ทธ๋๋ฐ ๊ธฐ๋ฒ.
AOP ์ฃผ์ ๊ฐ๋
โ Aspect์ Target
โ Advice
โ Join point์ Pointcut
AOP ๊ตฌํ์ฒด
โ https://en.wikipedia.org/wiki/Aspect-oriented_programming
โ ์๋ฐ โ AspectJ โ ์คํ๋ง AOP
Aspect-oriented programming - Wikipedia
Programming paradigm In computing, aspect-oriented programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. It does so by adding behavior to existing code (an advice) without modifyi
en.wikipedia.org
AOP ์ ์ฉ ๋ฐฉ๋ฒ
โ ์ปดํ์ผ
โ ๋ก๋ ํ์
โ ๋ฐํ์
์คํ๋ง AOP: ํ๋ก์ ๊ธฐ๋ฐ AOP
์คํ๋ง AOP ํน์ง
โ ํ๋ก์ ๊ธฐ๋ฐ์ AOP ๊ตฌํ์ฒด
โ ์คํ๋ง ๋น์๋ง AOP๋ฅผ ์ ์ฉํ ์ ์๋ค.
โ ๋ชจ๋ AOP ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ๊ฒ์ด ๋ชฉ์ ์ด ์๋๋ผ, ์คํ๋ง IoC์ ์ฐ๋ํ์ฌ ์ํฐํ๋ผ์ด์ฆ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๊ฐ์ฅ ํํ ๋ฌธ์ ์ ๋ํ ํด๊ฒฐ์ฑ ์ ์ ๊ณตํ๋ ๊ฒ์ด ๋ชฉ์ .
ํ๋ก์ ํจํด
โ ์? (๊ธฐ์กด ์ฝ๋ ๋ณ๊ฒฝ ์์ด) ์ ๊ทผ ์ ์ด ๋๋ ๋ถ๊ฐ ๊ธฐ๋ฅ ์ถ๊ฐ
โ ๊ธฐ์กด ์ฝ๋๋ฅผ ๊ฑด๋๋ฆฌ์ง ์๊ณ ์ฑ๋ฅ์ ์ธก์ ํด ๋ณด์. (ํ๋ก์ ํจํด์ผ๋ก)
๋ฌธ์ ์
โ ๋งค๋ฒ ํ๋ก์ ํด๋์ค๋ฅผ ์์ฑํด์ผ ํ๋๊ฐ?
โ ์ฌ๋ฌ ํด๋์ค ์ฌ๋ฌ ๋ฉ์๋์ ์ ์ฉํ๋ ค๋ฉด?
โ ๊ฐ์ฒด๋ค ๊ด๊ณ๋ ๋ณต์กํ๊ณ ...
๊ทธ๋์ ๋ฑ์ฅํ ๊ฒ์ด ์คํ๋ง AOP
โ ์คํ๋ง IoC ์ปจํ ์ด๋๊ฐ ์ ๊ณตํ๋ ๊ธฐ๋ฐ ์์ค๊ณผ Dynamic ํ๋ก์๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ๋ฌ ๋ณต์กํ ๋ฌธ์ ํด๊ฒฐ.
โ ๋์ ํ๋ก์: ๋์ ์ผ๋ก ํ๋ก์ ๊ฐ์ฒด ์์ฑํ๋ ๋ฐฉ๋ฒ
โ ์๋ฐ๊ฐ ์ ๊ณตํ๋ ๋ฐฉ๋ฒ์ ์ธํฐํ์ด์ค ๊ธฐ๋ฐ ํ๋ก์ ์์ฑ. โ CGlib์ ํด๋์ค ๊ธฐ๋ฐ ํ๋ก์๋ ์ง์.
โ ์คํ๋ง IoC: ๊ธฐ์กด ๋น์ ๋์ฒดํ๋ ๋์ ํ๋ก์ ๋น์ ๋ง๋ค์ด ๋ฑ๋ก ์์ผ์ค๋ค.
โ ํด๋ผ์ด์ธํธ ์ฝ๋ ๋ณ๊ฒฝ ์์. โ AbstractAutoProxyCreator implements BeanPostProcessor
์คํ๋ง AOP: @AOP
์ ๋ ธํ ์ด์ ๊ธฐ๋ฐ์ ์คํ๋ง @AOP ์์กด์ฑ ์ถ๊ฐ
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
์ ์คํฉํธ ์ ์
โ @Aspect
โ ๋น์ผ๋ก ๋ฑ๋กํด์ผ ํ๋๊น (์ปดํฌ๋ํธ ์ค์บ์ ์ฌ์ฉํ๋ค๋ฉด) @Component๋ ์ถ๊ฐ.
ํฌ์ธํธ์ปท ์ ์
โ @Pointcut(ํํ์)
โ ์ฃผ์ ํํ์
โ execution โ @annotation โ bean
โ ํฌ์ธํธ์ปท ์กฐํฉ
โ &&, ||, !
์ด๋๋ฐ์ด์ค ์ ์
โ @Before
โ @AfterReturning
โ @AfterThrowing
โ @Around
์ฐธ๊ณ
โ https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aoppointcuts
Null-safety
์คํ๋ง ํ๋ ์์ํฌ 5์ ์ถ๊ฐ๋ Null ๊ด๋ จ ์ ๋ ธํ ์ด์
โ @NonNull
โ @Nullable
โ @NonNullApi (ํจํค์ง ๋ ๋ฒจ ์ค์ )
โ @NonNullFields (ํจํค์ง ๋ ๋ฒจ ์ค์ )
๋ชฉ์
โ (ํด์ ์ง์์ ๋ฐ์) ์ปดํ์ผ ์์ ์ ์ต๋ํ NullPointerException์ ๋ฐฉ์งํ๋ ๋ชฉ์
โ GitHub
โถ ์์ ๋ด์ฉ
Spring MVC
Controller ํด๋์ค
- ํด๋ผ์ด์ธํธ ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ํด๋์ค - ์นํ๋ก๊ทธ๋จ@Request Mapping ์๋ํ ์ด์ ์ ํด๋์ค์ ์ ์ธํ๋ฉด Controller ํด๋์ค์ ๋ชจ๋ ์์ฒญ ์ฒ๋ฆฌ ๋ฉ์๋์ ์์ฒญ URL ์ฃผ์์๋ถ๋ถ์ ๊ณตํต์ ์ผ๋ก ํฌํจ๋๋ URL ์ฃผ์๋ฅผ ์ค์ ๊ฐ๋ฅ
MyBatis Framework์์ ๋ก๊ทธ๋ฅผ ์ ๊ณต๋๋ Spring ๋ก๊ทธ ๊ตฌํ์ฒด๋ก ๊ธฐ๋ก๋๋๋ก ์ค์ ํ๋ ๋ฐฉ๋ฒ
1. Log4Jdbc Log4j2 JDBC4 ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ๋ก์ ํธ์ ๋น๋ ์ฒ๋ฆฌ - pom.xml
2. DataSource ๊ด๋ จ ํด๋์ค๋ฅผ spring bean์ผ๋ก ๋ฑ๋กํ bean ์๋ฆฌ๋จผํธ์์ driverClassName ํ๋๊ฐ๊ณผ URL ํ๋๊ฐ์ ๋ณ๊ฒฝํ์ฌ ์ธ์ ์ ์ฒ๋ฆฌ - root-context.xml
3. [src/main/resources] ํด๋์ log4jdbc.log4j2.properites ํ์ผ ์์ฑ
4. [src/main/resources] ํด๋์ log4j.xml ํ์ผ์์ ๋ก๊ทธ ์ด๋ฒคํธ์ ๋ํ ๊ธฐ๋ก ์ค์
- jdbc.sqltiming : SQL ๋ช ๋ น ์คํ์๊ฐ(ms) ๊ธฐ๋ก
- jdbc.audit : ResultSet ๊ด๋ จ ์ ๋ณด๋ฅผ ์ ์ธํ ๋ชจ๋ JDBC ๊ด๋ จ ์ ๋ณด ๊ธฐ๋ก
- jdbc.resultset : ResultSet ๊ด๋ จ ์ ๋ณด๋ฅผ ํฌํจํ ๋ชจ๋ JDBC ๊ด๋ จ ์ ๋ณด ๊ธฐ๋ก
- jdbc.resultsettable : ResultSet ๊ด๋ จ ์ ๋ณด๋ฅผ ํ ์ด๋ธ(ํ) ํ์์ผ๋ก ๊ธฐ๋ก
- jdbc.connection : Connection ๊ด๋ จ ์ ๋ณด๋ฅผ ๊ธฐ๋ก - Open or Close
Spring Framework๋ฅผ ์ด์ฉํ์ฌ ํ ์คํธ ํ๋ก๊ทธ๋จ์ ์์ฑํด ๋ชจ๋(๋จ์ ํ๋ก๊ทธ๋จ) ํ ์คํธ ํ๋ ๋ฐฉ๋ฒ
1. junit ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ spring-test ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ๋ก์ ํธ์ ๋น๋ ์ฒ๋ฆฌ - pom.xml
⇒ junit ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ spring-test ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ scope ์๋ฆฌ๋จผํธ ์ฃผ์ ์ฒ๋ฆฌ
2. [src/test/resources] ํด๋์ log4j.xml ํ์ผ ๋ณ๊ฒฝ
3. [src/test/java] ํด๋์ ํ ์คํธ ํด๋์ค ์์ฑ - ํ ์คํธ ๋ฉ์๋ ์ด์ฉํ์ฌ ๋ชจ๋ ํ ์คํธ
pom.xml
https://mvnrepository.com/artifact/org.bgee.log4jdbc-log4j2/log4jdbc-log4j2-jdbc4
- DAO ๊ด๋ จ Framework์์ ๋ฐ์๋๋ ๋ก๊ทธ๋ฅผ Spring Log ๊ตฌํ์ฒด์๊ฒ ์ ๋ฌํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
Test
- ํ
์คํธ ํ๋ก๊ทธ๋จ์ DAO ํด๋์ค ๋๋ Service ํด๋์ค์ ๋ฉ์๋๋ฅผ ๊ฒ์ฌํ ๋ชฉ์ ์ผ๋ก ์์ฑ
- ํ ์คํธ ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์คํํ๊ธฐ ์ํ ํด๋์ค(Clazz)๋ฅผ ์ค์ ํ๋ ์๋ํ ์ด์
- value ์์ฑ : ํ ์คํธ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ธฐ ์ํ ํด๋์ค(clazz)๋ฅผ ์์ฑ๊ฐ์ผ๋ก ์ค์ - ๋ค๋ฅธ ์์ฑ์ด ์๋ ๊ฒฝ์ฐ ์์ฑ๊ฐ๋ง ์ค์
- SpringJUnit4ClassRunner : Spring Container (ApplicationContext ๊ฐ์ฒด)๋ฅผ ์์ฑํ์ฌ Spring Bean์ ์ ๊ณตํ์ฌ ํ ์คํธ ํ๋ก๊ทธ๋จ์ ์คํํ๋ ํด๋์ค
- ํ ์คํธ ํด๋์ค์์ ์ฌ์ฉ๋ Spring Bean์ด ๋ฑ๋ก๋ Bean Configuration File ์๋ํ ์ด์
- locations ์์ฑ : Bean Configuration File์ ๋ฐฐ์ด์ ์์๋ก ์ค์ ํ์ฌ ์์ฑ๊ฐ์ผ๋ก ์ค์
- ⇒ Bean Configuration File ๊ฒฝ๋ก๋ file ์ ๋์ด๋ฅผ ์ฌ์ฉํ์ฌ ํ์ผ ์์คํ ๊ฒฝ๋ก๋ก ํํ
- ํ ์คํธ ๋ฉ์๋๋ฅผ ์ค์ ํ๋ ์๋ํ ์ด์
- ⇒ Runner ํด๋์ค์ ์ํด ํธ์ถ๋์ด ๋ช ๋ น์ด ์คํ๋๋ ๋ฉ์๋
- WebApplicationContext ๊ฐ์ฒด(Spring Container)๋ฅผ ์ด์ฉํ์ฌ Spring Bean์ ๊ด๋ฆฌํ๋๋ก ์ค์ ํ๋ ์๋ํ ์ด์
- ์์ฒญ๊ณผ ์๋ต์ ๊ฐ์์ผ๋ก ์ ๊ณตํ๊ธฐ ์ํ ํด๋์ค
- ํ ์คํธ ๋ฉ์๋ ํธ์ถ ์ ์คํ๋ ๋ช ๋ น์ ์์ฑํ ๋ฉ์๋์ ์ค์ ํ๋ ์๋ํ ์ด์ - ์ด๊ธฐํ ์์
- MockMvcBuilder ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๋ฉ์๋
- build() : MockMvc ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ๋ฉ์๋
- ๊ฐ์์ผ๋ก ์นํ๋ก๊ทธ๋จ์ ์์ฒญํ๋ ๋ฉ์๋
- ⇒ ResultActions ๊ฐ์ฒด ๋ฐํ (์์ฒญ์ ๋ํ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ ๊ฐ์ฒด)
- MockMvcRequestBuilders.get(String urlTemplate, Object... uriVars)
- ⇒RequestBuilder ๊ฐ์ฒด ๋ฐํ (์นํ๋ก๊ทธ๋จ์ ์์ฒญ์ ๋ณด๋ฅผ ์ ์ฅํ ๊ฐ์ฒด)
- ResultActions.addReturn() : ์์ฒญ ์ฒ๋ฆฌ ๋ฉ์๋์ ๊ฒฐ๊ณผ๋ฅผ MvcResult ๊ฐ์ฒด๋ก ๋ฐํํ๋ ๋ฉ์๋
- @RunWith
'Legacy' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
2022.04.18 ์ค๋์ ๊ธฐ๋ก (0) | 2022.04.18 |
---|---|
2022.04.16 ์ ๊ธฐ๋ก (0) | 2022.04.16 |
2022.03.17์ ๊ธฐ๋ก (2) | 2022.03.17 |
2022.03.16์ ๊ธฐ๋ก (0) | 2022.03.16 |
2022.03.15์ ๊ธฐ๋ก (0) | 2022.03.15 |