Spring 기본2

김정훈·2024년 7월 7일

Spring

목록 보기
2/24

스프링 DI 설정 및 사용

1. 스프링을 이용한 객체 조립과 사용

2. DI 방식1 : 생성자 방식

3. DI 방식2 : 세터 메서드 방식

4. @Configuration

5. @Bean

객체로 관리할 요소

6. 두 개 이상의 설정 파일 사용하기

1) 생성자 매개변수

2) @Import

의존 자동 주입

1. @Autowired

의존성을 주입해야되는

2. 일치하는 빈이 없는 경우

3. @Qualifier

4. 빈 이름과 기본 한정자

5. @Autowired 애노테이션의 필수 여부

컴포넌트 스캔

1. @Component

2. @ComponentScan

지정한 패키지 범위를 기본 스캔 대상 스캔 👉 객체 생성

3. 기본 스캔 대상

  • @Component
  • @Service
  • @Controller
  • @RestController
  • @ControllerAdvice
  • RestControllerAdvice
  • @Aspect
  • @Configuration
  • @Repository : DAO에 주로 정의

4. 컴포넌트 스캔에 따른 충돌 처리

1) 빈 이름 충돌

클래스명만 빈의 이름으로 고려
해결방안 @Repository("memberDao2")

2) 수동 등록한 빈과 충돌

수동 등록 빈이 우선

  • 자동 스캔 빈 memberDao
  • 수동 등록 빈 (@Bean) - memberDao(우선 적용)

3) excludeFilters

컴포넌트 스캔 내부에는 excludeFilters이 정의 되어있다. 자동스캔범위에 있는 객체를 배제

ManualBean

@Target(ElementType.TYPE) //클래스명, 인터페이스명 위에
@Retention(RetentionPolicy.RUNTIME)
public @interface ManualBean {
}

AppCtx
1. 애노테이션 FilterType.ANNOTATION
2. 클래스 FilterType.ASSIGNABLE_TYPE
3. 정규표현식 FilterType.REGEX
4. aspectJ FilterType.ASPECTJ : 의존성을 추가해야함.

@Configuration
@ComponentScan(basePackages="member", excludeFilters=@ComponentScan.Filter(type=FilterType.ANNOTATION, classes = ManualBean.class))
@ComponentScan(basePackages = "member", excludeFilters = @ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE, classes = {MemberDao.class, JoinValidator.class}))
@ComponentScan(basePackages = "member", excludeFilters = @ComponentScan.Filter(type= FilterType.REGEX, pattern = "member\\.*Dao"))
@ComponentScan(basePackages = "member", excludeFilters = @ComponentScan.Filter(type= FilterType.ASPECTJ, pattern = "member..*Dao"))
public class AppCtx{ }

MemberDao
MemberDao클래스는 @ManualBean이기 때문에 자동스캔 범위에서 배제된다.

@ManualBean
@Repository
public class MemberDao { // memberDao - 빈 이름

    private static Map<String, Member> members = new HashMap<>();

    public void register(Member member) {
        members.put(member.getEmail(), member);
    }

    public Member get(String email) {
        return members.get(email);
    }

    public List<Member> getList() {
        List<Member> data = new ArrayList<>(members.values());

        return data;
    }
}

Ant 패턴 - aspectJweaver

의존성

implementation 'org.aspectj:aspectjweaver:1.9.22.1'

빈 라이프 사이클과 범위

1. 컨테이너 초기화

빈 객체의 생성, 의존 주입, 초기화

2. 컨테이너 종료

빈 객체의 소멸

3. 빈 객체의 라이프 사이클

객체 생성 -> 의존 설정 -> 초기화 -> 소멸

  • 초기화 : 객체가 완전히 생성되고 조립된 다음에 처리할 작업을 정의하면 실행되는 단계
  • 소멸(ctx.close() - 객체 소멸) : 소멸전에 처리할 작업을 정의하면 실행되는 단계

스프링 컨테이너 생성시 진행 되는 부분(객체 생성 👉 의존 설정 👉 초기화)

본인이 만든 클래스만 적용이 가능하다

1) InitializingBean 인터페이스

  • afterPropertiesSet 메서드 : 초기화 단계시에 실행 된다. (객체가 완전히 조립되고 생성 된 후에 처리할 작업을 정의)

2) DisposableBean 인터페이스

  • destory 메서드 : 컨터이너에 있는 객체가 소멸되기 전에 실행 (주로 객체 소멸전에 할 적업 예) 자원해체 등...)

출력결과
afterPropertiesSet()
글쓰기
DisposableBean()


BoardService

@Service
public class BoardService implements InitializingBean, DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean()");
    }
    public void write(){
        System.out.println("글쓰기");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet()");
    }
}

Test

public class Ex02 {
    @Test
    void test1(){
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppCtx.class); //afterPropertiesSet()은이때 실행됨
        BoardService service = ctx.getBean(BoardService.class);
        service.write();
        ctx.close(); //destroy()은 이때 실행된다.
    }
}

4. 빈 객체의 초기화와 소멸

  • 커스텀 메서드
  • 외부 라이브러리, 자바 JDK 기본 클래스, 스프링 프레임워크 기본 클래스 등등 : 수동으로 빈객체를 등록해야한다.

1) initMethod

initalizingBean : afterPropertiesSet 메서드와 동일 시점에 호출

2) destroyMethod

DisposableBean : destroy 메서드와 동일 시점에 호출

5. 빈 객체의 생성과 관리 범위

@Scope : 클래스명, 메스드명 위에 정의 가능

  • @Scope("singleton") : 정의하지 않아도 기본은 싱글톤 패턴으로 관리
  • @Scope("prototype") : 매번 조회시마다 새로운 객체를 생성
    • 스프링 객체 관리 기능은 기본적으로 싱글톤 일때 정상동작
    • prototype : 일부 기능에 제한 조건
	@Scope("prototype") //매번 새로운 객체를 생성
    @Bean(initMethod = "init", destroyMethod = "destroy") //외부에서 가져왔다고 가정했기 때문에 수동으로 지정해야한다.
    public BoardService2 boardService2(){
        return new BoardService2();
    }
    
    @Test
    void test1(){
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppCtx.class);
	BoardService2 s1 = ctx.getBean(BoardService2.class);
	BoardService2 s2 = ctx.getBean(BoardService2.class);
	System.out.println(s1 == s2); //false
	ctx.close();
    }
profile
안녕하세요!

0개의 댓글