스프링 프레임워크
1. 스프링 프레임워크란?
(Spring Framework)
1) 의존 주입(Dependency Inject : DI) 지원
2) AOP(Aspect-Oriented Programming) 지원
- 관점 지향 프로그래밍 / 관점 - 개발자의 공통적인 처리 부분
- 프록시(proxy) : 대신하다, 대리하다.
3) MVC 웹 프레임워크 제공
4) JDBC, JPA 연동, 선언적 트랜잭션 처리 등 DB 연동 지원 / Spring Data
JPA(Java Persistence API - ORM 표준 설계)
5) 스프링 데이터, 스프링 시큐리티 - 인증(로그인), 인가(통제), 스프링 배치
2. 스프링 프로젝트 생성하기
spring-context 의존성
spring6
3. 스프링은 객체 컨테이너
IoC - Inversion Of Control : 제어의 역전
- 개발자가 해야되는 객체의 관리 -> 스프링 컨테이너가 대신 수행
- 다양한 방식으로 객체 관리


ㄴ 설정방식(어떤 방식으로 설정하겠다)
ㄴ 첫번째를 주로 많이 사용 = 스프링 컨테이너
-> 에노테이션 방식으로 설정하겠다
Class AnnotationConfigApplicationContext
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/AnnotationConfigApplicationContext.html

4. 스프링 DI(Dependency Injection - 의존주입)
1) 의존(Dependency)

2) DI를 통한 의존 처리
3) DI와 의존 객체 변경의 유연함
5. 객체 조립기
스프링 DI 설정 및 사용
- 스프링을 이용한 객체 조립과 사용
- DI 방식1 : 생성자 방식
- DI 방식2 : 세터 메서드 방식
- @Configuration
- @Bean
6. 두 개 이상의 설정 파일 사용하기
1) 생성자 매개변수
AnnotationConfigApplicationContext(Class<?>... componentClasses)
AnnotationConfigApplicationContext(String... basePackages)
2) @Import
- 설정 클래스에서 다른 설정클래스를 포함 시킬 때
의존 자동 주입
1. @Autowired
- 의존성을 주입해야되는 객체임을 알려주는 애노테이션
- 스프링 컨테이너안에 있는 관리객체이면 의존성을 주입해준다
= 스프링 컨테이너안에 있는 관리객체가 아니면 의존성 주입 안됨
1) 멤버변수 위에 정의
2) setter 메서드 위에 정의
3) Optional 정의된 멤버 변수, 메서드의 매개변수에 있어도 주입
4) 자동 스캔 적용(@ComponentScan)시
- @Autowired 미 적용 방식
- 생성자의 매개변수로 정의 / 기본생성자가 정의 되지 않아야 한다.

ㄴ 컨테이너안에서 객체를 꺼내서 주입
2. 일치하는 빈이 없는 경우
- 스프링 컨테이너안에 있는 관리객체이면 의존성을 주입해준다
= 스프링 컨테이너안에 있는 관리객체가 아니면 의존성 주입 안됨
3. @Qualifier
- @Qualifier = 기본한정자
- @Qualifier("메서드명")
- 빈의 이름을 직접 지정
- 빈에 자료형이 같은 메서드가 있는 경우 어떤 객체를 꺼내올지 헷갈리게 됨 -> @Qualifier를 통해 이름을 직접 지정
4. 빈 이름과 기본 한정자
- @Bean : 메서드 명
- @Qualifier : 변경한 이름
- 클래스명(자동스캔의 경우) -> 앞 첫문자는 소문자
ex) class JoinService -> joinService

5. @Autowired 애노테이션의 필수 여부
- required
- true - 기본 값, 주입 받는 객체는 반드시 스프링 컨테이너에 생성되어 있어야 한다.
- false - 주입받는 객체x -> setter 메서드 호출x, 의존성 주입x
- required : true
- 없을 수 있는 주입 받는 객체 @Nullable 에노테이션을 적용해도 필수 여부 해제...
- 메서드 호출o, 없는 의존성에 null을 대입
컴포넌트 스캔
1. @Component
2. @ComponentScan
- 스프링 컨테이너가 자동으로 스캔할 패키지 범위 설정
예시)


3. 기본 스캔 대상
- @Component : 구성요소
- @Service : 큰 기능
- 두개다 같은 기능을하지만 의미적인 차이구분을 위해 분개됨
특정 기능과 관련된 애노테이션
- @Configuration
- @Controller
- @RestController
- @ControllerAdvice
- @RestControllerAdvice
- @Aspect
- @Repository : DAO에 주로 정의
4. 컴포넌트 스캔에 따른 충돌 처리
1) 빈 이름 충돌
- 클래스명만 빈의 이름으로 고려
- 다른 패키지에 있는 동일한 이름의 클래스가 있으면 충돌 발생
빈의 이름
- 메서드명
- 클래스명
- @Qualifier로 지정한 이름
exam01.member.dao.MemberDao - 빈 이름 : memberDao
exam01.member.dao.sub.MemberDao - 빈 이름 : memberDao
예시)

2) 수동 등록한 빈과 충돌
- 수동등록 빈 vs 수동등록 빈 : 오류
- 수동등록빈 vs 자동 스캔 빈 : 수동등록 빈 -> 자동 스캔 빈은 배제됨
- 수동등록빈 : 설정 클래스에서 @Bean애노테이션 아래에 정의한 메서드
3) excludeFilters
참고) Ant 패턴 - aspectJweaver
- 의존성
implementation 'org.aspectj:aspectjweaver:1.9.22.1'
예시) 애노테이션으로 배제(ANNOTATION)






예시) 클래스명으로 배재(ASSIGNABLE_TYPE)



예시) 정규표현식으로 배재(REGEX)

예시) Ant 패턴 배재(REGEX)

정리






ㄴ final인경우 무조건 초기화를 해주어야 하는 상황 -> 보통 초기화는 객체 생성시 초기화를 해 줌

ㄴ 이런식으로 초기화 해 줌

ㄴ 초기화가 필요한 아이들을 알아서 초기화 해 줌
-> final : 생성자 매개변수에 추가 벗 상수의 특징상 값을 변경 할 수 없음
생성자 매개변수에 항상 추가해주면서 값을 변경하려면 어떻게? @NonNull사용

ㄴ 롬복 (아 롬복이 뭐였더라....)
ㄴ 상수(final)가 아니더라도 생성자 매개변수에 추가해주는 애노테이션 @NonNull


ㄴ 빈의 이름 바꾸기


스프링 컨테이너의 역할
1. 객체 생성
- 설정을 확인하고 찐 스캔하고 객체를 생성해주는 역할
- 스캔 기본 대상에 해당하는 클래스이면 -> 객체 생성
2. 의존성 주입
- 객체조립기 통해서 의존성 주입해주는 것도 ㄱㅊ다!! -> IOC
- @Autowired
1) 멤버변수 위
2)
3)
4) 다만 기본생성자가 없어야지만 의존성을 주입해 줌 + 자동스캔범위일대만 가능
1~3) @Autowired 애노테이션 활용해 의존성 주입
4) @Autowired 애노테이션 없이 의존성 주입해주는 방식 예시) 4번 방식
ㄴ 근데 의존성이 100개이면 어떡함?
-> 롬복
스프링 설정
@Configuration 애노테이션이 붙어있는 클래스
AppCtx - 객체를 생성하는건 아님!!! 설정만(스캔 범위...)
@Bean 애노테이션 : 메서드명 위에 -> 수동 등록 빈
@ComponentScan()
★객체생성은 스프링 컨테이너가!!!★
★ ★
7/8 2교시 스타트 수업 때 정리해 주신 내용
빈 라이프 사이클과 범위
1. 컨테이너 초기화 : 빈 객체의 생성, 의존 주입, 초기화
2. 컨테이너 종료 : 빈 객체의 소멸
3. 빈 객체의 라이프 사이클
1) 객체 생성 -> 의존 설정 -> 초기화 -> 소멸
-
객체생성
-
의존 설정 : 의존성 주입 = 객체가 완전히 생성된 단계
-
초기화 : 객체가 완전히 생성되고 조립된 다음에 처리할 작업을 정의하면 실행되는 단계
-
소멸 : 소멸 전에 처리할 작업을 정의하면 실행되는 단계
ex) cts.close() : 객체 소멸
ex) 자원 해제...
-
스프링 컨테이너 생성 시 진행되는 부분(객체 생성 -> 의존설정 -> 초기화)
2) InitializingBean 인터페이스
- afterPropertiesSet 메서드
- 초기화 단계시에 실행 된다.
- 객체가 완전히 조립되고 생성 된 후에 처리할 작업을 정의
- InitializingBean 인터페이스의 추상메서드
= afterPropertiesSet 메서드
= 필수적으로 설정해야 할 메서드
예시)




InitializingBean 인터페이스의 afterPropertiesSet 메서드
= 추상메서드 = 필수적으로 설정해야 할 메서드

ㄴ 1번 시점에 호출 됨
ㄴ 스프링 컨테이너 생성 시 진행되는 부분(객체 생성 -> 의존설정 -> 초기화)

ㄴ 1번 시점에 호출 됨을 증명
3) DisposableBean 인터페이스
- destroy 메서드
- 컨테이너에 있는 객체가 소멸되기 전에 실행
- 주로 객체 소멸 전에 할 작업
ex) 자원 해제 등...
- DisposableBean 인터페이스의 추상메서드
= destroy 메서드
= 필수적으로 설정해야 할 메서드
예시)

ㄴ ctx.close(); : 이 시점 직전에 호출됨

ㄴ 증거
4. 빈 객체의 초기화와 소멸 : 커스텀 메서드
- 외부 라이브러리, 자바 JDK 기본 클래스, 스프링 프레임워크 기본 클래스 등등...
- 우리가 정의하지 못하기 때문에
- 왜? 우리가 건드릴 수 없는 = 변경할 수 없는 외부코드임(자바코드도 없음)
- 수동등록 빈⭕ 자동스캔❌
- 외부에 받은 클래스는 자동스캔이 안되서 수동등록 해주어야 함(@Bean)
1) initMethod
- InitializingBean :: afterPropertiesSet 메서드와 동일 시점에 호출
2) destroyMethod

예시)

ㄴ 보드서비스2외부에서 가져온 클래스

ㄴ 외부에서 가져온 클래스는 자동등록 안되서 수동등록 해 줌

ㄴ 같은 시점이다

ㄴ 같은 시점이다

ㄴ 외부클래스에 정의된 메서드가 시점에 맞게 실행되게 설정해줌
5. 빈 객체의 생성과 관리 범위
@Scope
- 클래스위 정의가능
- 메서드위 정의가능
- @Scope("singleton") : 정의하지 않아도 기본은 싱글톤 패턴으로 관리
- @Scope("prototype") : 매번 조회 시 마다 새로운 객체를 생성
- 스프링 객체 관리 기능은 기본적으로 싱글톤 일때 정상적으로 동작
- prototype : 일부 기능에 제한 조건
예시)

