자바 플랫폼을 위한 오픈 소스 애플리케이션 프레임워크
Spring IoC Container에 의해서 관리되는 객체
간단하게 말하면 자바 객체
객체에 대한 생성 및 생명주기를 관리할 수 있는 기능 제공
컨트롤의 제어권이 사용자가 아니라 외부 소스(framework, services, 다른 components)에 있다.
컴포넌트(component) : 독립적인 모듈
모듈(module) : 기능(함수)별로 여럿을 하나로 정리/모으거나 분할하는 것
객체의 생성과 사용을 분리
Apple 객체를 직접 생성 -> Fruit 클래스는 Apple에 의존적이다.
public class Fruit {
private Apple apple = new Apple();
}
DI는 필요한 객체를 외부로부터 받아서 사용
public class Fruit {
private Apple apple;
@Autowired
public Fruit(Apple apple){
this.apple = apple;
}
}
생성자를 통한 주입을 권장
- 생성자가 1개일 경우 @Autowired 생략가능
- 생성자가 2개 이상일 경우 생성자 중 하나 이상에 @Autowired 달아야함
why?
- 순환참조가 일어 났을 경우 애플리케이션이 실행되지 않고 오류 출력
- 필드를 final로 선언하여 Immutability하게 사용 가능
불변객체(Immutability Object)?
final 선언자를 통해 변수를 변경할 수 없도록 제한.
생성자를 통해 최초 초기화 가능
트랜잭션이나 로깅, 보안과 같이 여러 모듈에서 공통적으로 사용하는 기능의 경우 해당 기능을 분리하여 관리할 수 있다.
Aspect : 부가 기능을 모듈화. PointCut(>=1)+Advice
Target : 핵심 로직을 구현하는 클래스, Aspect를 적용하는 대상
Advice : Target에게 제공할 부가기능을 담은 모듈
JoinPoint : Advice가 적용될 수 있는 위치(Spring에서는 Method)
PointCut : Advice를 적용할 JoinPoint를 선별하는 작업 또는 그 기능을 정의한 모듈
Proxy : Advice가 적용되었을 때 만들어지는 객체
Spring AOP Proxy : JDK 동적 프록시, CGLIB 프록시
Spring Boot : CGLIB(Code Generator Library)
Weaving : Advice를 핵심 로직 코드에 적용하는 것
Advice와 target이 결합되어 프록시 객체를 만드는 과정
@Aspect
: AOP 기능을 하는 클래스에 반드시 추가해야할 어노테이션
execution
: PointCut을 지정하는 문법으로 AspectJ 언어 문법 사용
execution(리턴타입 클래스이름.메소드이름(매개변수))
* : All
.. : 개수 상관없이 All
ex1) execution(* com.example.demo.EventService.createEvent(..))
ex2) execution(void com.example.demo.*.*(*))
사용 예시
EventService는 Interface로 생략
@Component
public class SampleEventService implements EventService{
@Override
public void createEvent() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Create an event");
}
@Override
public void publishEvent() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("publish");
}
@Override
public void finishEvent() {
System.out.println("finish");
}
}
@Aspect
@Component
public class PerfAspect {
//joinpoint : @Around, pointcut : execution
@Around("execution(* com.example.demo.EventService.*(..))") //EventService 인터페이스의 모든 메소드 실행,
public Object logPerf(ProceedingJoinPoint joinPoint) throws Throwable{
long begin = System.currentTimeMillis();
Object result = joinPoint.proceed();
log.info(String.valueOf("Time : "+(System.currentTimeMillis() - begin)));
return result;
}
}
테스트 환경에서 실행해보면
@SpringBootTest
public class EventServiceTest {
@Autowired
EventService eventService;
@Test
public void aop(){
eventService.createEvent();
eventService.publishEvent();
eventService.finishEvent();
}
}
JoinPoint | 설명 |
---|---|
Before | 타깃 오브젝트의 메소드 실행 전에 동작 |
After | 타깃 오브젝트의 메소드 실행 후에 동작 |
AfterReturning | 정상적으로 종료한 경우 동작 |
AfterThrowing | 예외가 발생한 뒤 동작 |
Around | 타깃 오브젝트의 메소드가 호출 되는 전 과정에서 동작 (실행 전후, 예외 발생 등) |
@Around에서만 ProceedingJoinPoint, 나머지는 JoinPoint
proceed()
: 비즈니스 메소드 실행
Pointcut | 설명 |
---|---|
execution | 메서드 기준 |
within | 특정한 타입(클래스) 기준 |
bean | 스프링 빈 이름 |
this | 주어진 인터페이스를 구현한 객체를 대상 |
args | 특정한 파라미터를 가지는 대상 |
@annotation | 특정한 어노테이션이 적용된 대상 |
자바 언어 사양 외에 어떠한 제한에도 묶이지 않은 자바 오브젝트
최소한의 설정으로 단독 실행 가능한 스프링 애플리케이션을 빠르게 생성
@SpringBootApplication
은 다음 3가지 어노테이션을 쓰는 것과 같다. @SpringBootConfiguration
, @EnableAutoConfiguration
, @ComponentScan
Spring Boot 설정을 나타내는 어노테이션.
Application.java를 Config 파일로 인식.
@SpringBootApplication
을 사용하면 자동으로 ApplicationContext을 생성해준다.
ApplicationContext 이란?
- Spring에서의 Container
- implements Beanfacory
- Bean 저장소, heap에 저장
미리 정의 되어 있는 Bean들을 가져와서 등록한다.
Where?
External Libraies - spring-boot-autoconfgure - META-INF - spring.factories 파일에 정의되어 있다.
해당 어노테이션이 있는 위치부터 @Component @Configuration @Repository @Service @Controller @RestController
가 붙어 있는 클래스들을 찾아 Bean으로 등록한다.
@SpringBootApplication
은 프로젝트의 최상단 위치 권장
Spring Boot Starter를 사용하면 간편하게 dependency를 제공
그림과 같이 test를 사용하기 위한 모든 라이브러리들과 버전을 자동으로 추가해준다.
Spring Boot에서 제공하는 starter
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-starter
Spring Boot 기본 내장 서버는 Tomcat
지원 하는 내장 서버 : Tomcat, Jetty, Undertow, Netty
spring.factories에서 확인가능