1. Spring의 역할
- 객체를 통합 관리해서 new 등의 키워드를 생략 -> 프로그램이 간단하고 빨라짐
- 비즈니스 로직에 더 집중할 수 있게 됨
2. 주요 어노테이션/메서드
2-1. @Import
- 설정 클래스를 지정 -> 여러 설정 클래스를 한 개의 소스코드 파일에 넣을 수 있음
- 여러 설정 클래스를 넣기 위해서는 @Import{} 형태로 묶어준다
- AnnocationConfigApplicationContext를 사용하지 않도록 할 수 있음
2-2. getBean()
- Bean을 가져오는 메서드
- 가능성 있는 문제점
- 존재하지 않는 Bean 사용 -> NoSuchBeanDefinitionException
- Bean의 실제 타입과 지정 타입이 다름 -> Type Mismatch
- 지정한 타입의 Bean이 존재하지 않음 -> Cannot be resolved to a type
- 같은 타입 Bean이 2개 이상 존재 -> NoUniqueBeanDefinition
- 참고 사항
- 특정 타입 Bean 객체가 하나만 존재한다면 Type만으로 Bean을 사용할 수 있음
- 의존성 주입 대상 객체 모두를 Bean으로 만들 필요는 없다
2-3. @Autowired
- 의존 객체 필드에 @Autowired 어노테이션을 붙임으로써 의존 주입 과정을 생략할 수 있음
- Setter 기반 의존성 주입
- Setter 메서드에 @Autowired를 붙여서 해당 메서드로 의존성을 주입하는 방법
- Autowired 대상이 Bean이여야 함
- 일치하는 Bean이 없는 경우, 기본 생성자로 변경
- Exception encountered during context initialization 오류 발생
- 일치하는 Bean이 2개 이상인 경우, 자동 주입 대상 Bean이 2개 이상이 되어 오류 발생
- Exception encountered during context initialization 오류 발생
- @Qualifier 어노테이션으로 자동 주입 대상 Bean을 한정지을 수 있음
- 자동 주입 대상이 필수가 아니라면 어노테이션 사용 시 required=false로 지정한다
2-4. ComponentScan
- 컴포넌트 스캔 시 Bean 충돌이 발생할 수 있음
- 이 경우, Bean의 이름을 명시적으로 설정해야 함
3. Spring Bean 객체의 라이프사이클
3-1. 전 과정
객체 생성 -> 의존 설정 -> 초기화 -> 소멸(소멸 중 초기화/소멸 과정 작업)
3-2. 메서드 사용하기
3-2-1. Disposable 인터페이스
3-2-2. InitializingBean 인터페이스
- afterPropertiesSet() -> 초기화 시
3-3. @Bean 어노테이션의 initMethod와 destroyMethod 속성 사용하기
- initMethod는 초기화 시, destroyMethod는 소멸 시 사용
- Bean에 각 속성에서 설정할 내용을 등록하고, Bean 등록 시 옵션
3-4. Bean 스코프 정의하기
3-4-1. Singleton 범위
- 기본값
- @Scope("singleton")
- @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
3-4-2. Prototype 범위
- 새 인스턴스가 요청될 때마다 객체가 만들어짐
- @Scope("prototype")
- @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
3-4-3. Singleton vs Prototype
- 싱글톤의 연결은 한번만 이루어지지만 프로토타입의 연결은 2번 호출됨 -> 인스턴스가 개별적으로 호출되므로
- 싱글톤은 close() 메서드가 호출되지만 프로토타입은 그렇지 않음
- 즉, 프로토타입의 라이프사이클은 완전하지 않다
- 프로토타입의 Bean 객체 소멸 처리는 개발자기 직접 해야 함
4. AOP
4-1. 정의
- Aspect-Oriented Programming
- 애플리케이션의 핵심 비즈니스와 공통적인 기능(횡단 관심사)를 분리해서 모듈화하는 방법
- 로깅, 보안(인증, 인가), 트랜잭션 관리 등의 횡단 관심사를 분리하는 방법
4-2. 주요 개념
4-2-1. 횡단 관심사
- 비즈니스 로직과는 별개
- 여러 모듈에서 공통적으로 사용하는 기능
- 별도로 설정하지 않으면 동일 코드가 반복될 수 있음
4-2-2. Aspect
- 횡단 관심사를 모듈화한 것
- 한 개 이상의 Point Cut과 Advice가 조합됨
4-2-3. Join Point
- Aspect가 적용될 수 있는 실행 지점
- 메서드 호출, 객체 생성, 필드 접근 단계 등 -> 단, Spring에서는 메서드 호출 단계만 가능
4-2-4. Pointcut
- Aspect가 적용될 특정 Join Point를 정의한 것
- Join Point의 서브셋을 필터링
- 정규식, AspectJ 등으로 어느 Join Point를 사용할 지 결정함
4-2-5. Advice
- Pointcut에서 정의한 특정 Join Point에서 수행될 실제 작업
- 언제 실행될지 정의
- Spring에서는 5개 종류로 구분
- Before Advice(@Before): 대상 메서드가 실행되기 전
- After returning advice(@AfterReturing): 대상 메서드가 성공적으로 실행되고, 결과값이 반환된 후
- After throwing advice(@AfterThrowing): 대상 메서드에 예외가 발생했을 때
- After advice(@After): 대상 메서드의 정상 실행 여부와 관계 없이 무조건 실행
- Around advice(@Around): 대상 메서드의 호출 전후, 예외 발생 등 모든 시점
4-2-6. Weaving
- Aspect를 실제 대상 객체에 적용해서 비즈니스 로직과 결합하는 과정
- 컴파일 시점, 로드 시점, 런타임에 수행될 수 있음
4-3. 프록시 객체
- 핵심 기능을 구현하지 않음
- 여러 객체에 공통적으로 적용할 수 있는 기능임
4-4. 구현 방법(요약)
- Aspect를 사용할 클래스에 @Aspect 어노테이션을 적용
- @Pointcut 어노테이션으로 공통 기능을 적용할 Pointcut 정의
@Pointcut("execution(public * package_nane"(...))")
- AOP 설정 시 스프링 설정 클래스에 @EnableAspectJAutoProxy 어노테이션 추가가 필요
4-5. Proty Pattern
- Spring 실행 시점에서 비즈니스 로직과 AOP를 결합하는 패턴
- 작업을 수행하는 프록시가 delegate의 메서드를 작동하게함
- delegate: 생성자를 통해 변수로 선언
- proxy: delegate의 기능과 그 외 기능으로 구성, 메서드에서 실행하는 대상
- Join Point로 프록시 패턴과 유사한 동작을 가능하게 함
- 이를 위해 @Aspect, @EnableAspectJAutoProxy 등의 어노테이션이 요구됨
4-6. 하나의 Pointcut에 여러 Advice 적용하기
- Advice의 적용 순서와 설정 클래스의 Bean의 정의 순서는 동일 순서
- 순서를 수동으로 지정하려면 @Order 어노테이션을 @Aspect 어노테이션에 적용
- Pointcut의 재사용을 포기하는 대신 execution 명시자를 직접 지정할 수도 있음
4-7. @Pointcut을 다른 클래스에서 활용하기
- 메서드를 public으로 선언 -> Pointcut을 사용할 클래스에서 @Pointcut 어노테이션이 불필요해짐
- 여러 Aspect에서 사용되는 경우, 별도 클래스 파일로 Pointcut을 관리할 수 있음