본문 바로가기
Spring

Java config를 이용하여 스프링 컨테이너(ApplicationContext) 설정하기

by seeker00 2021. 7. 10.

Java config를 이용한 설정

어노테이션

  • jdk 5부터 지원되었다.

@Configuration

  • 스프링 설정 클래스를 선언하는 어노테이션
  • AnnotationConfigContext 객체는 자바 config 클래스를 읽어들여서 IoC와 DI를 적용하게 된다

@Bean

  • bean 클래스를 정의하는 어노테이션
  • 설정 파일 내 메서드 형태로 작성한다.
  • 메서드의 이름은 xml 파일에서 Bean을 등록할 때, id와 같은 역할을 한다.
  • AnnotationConfigContext는 해당 어노테이션이 붙은 메소드들을 자동으로 실행하며, 리턴값인 객체들을 싱글톤 패턴(default)으로 관리한다
  • 컨테이너의 getBean() 메소드로 빈 객체를 불러올 때, 파라미터로 메소드 명 혹은 클래스를 전달한다.
Car car = (Car)ac.getBean("car");
Car car = (Car)ac.getBean(Car.class);
  • 주로, 외부 라이브러리의 클래스들을 등록할 때 이용한다. (외부 라이브러리 내부 클래스에는 어노테이션을 등록하기 어려우므로)
    • @Controller, @Service, @Repository, @Component 어노테이션이 붙어 있는 객체들은 ComponentScan을 이용해서 읽어들여 메모리에 올리고 DI를 주입하도록 하고, 이러한 어노테이션이 붙어 있지 않은 객체는 @Bean어노테이션을 이용하여 직접 생성해주는 방식으로 클래스들을 관리한다.

@ComponentScan

  • 개발자가 @bean 어노테이션으로 config 파일에서 일일이 명시하지 않아도, 지정한 패키지 내에서 @Controller, @Service, @Repository, @Component 어노테이션이 붙은 클래스를 찾아 컨테이너에 등록한다.
  • 참고) https://galid1.tistory.com/510

@Component

  • 컴포넌트 스캔의 대상이 되는 어노테이션 중 하나로써 주로 유틸, 기타 지원 클래스에 붙이는 어노테이션
    • 객체명을 따로 지정하지 않으면 대상 클래스명을 전체 소문자로 변환해 이용한다.

@Autowired

  • 해당 필드에 주입이 되는 외부 객체의 bean(클래스)를 컨테이너에 찾아 주입하는 어노테이션
    • @Autowired 어노테이션을 이용하게 되면, setter 메소드가 생략 가능하다.

Java Config를 이용해 설정하기

  • @Bean 활용
// ApplicationConfig.java
package kr.or.connect.diexam01;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//어노테이션을 이용해 Config 파일임을 선언
@Configuration
public class ApplicationConfig {

    // ApplicationContext는 1. 파라미터를 갖지 않는 bean 생성 메서드를 우선 시행하고,
    // 2. 생성된 객체와 같은 타입 객체를 파라미터로 받는 bean을 생성한다. (외부 객체 주입, DI 시행)
    // 이를 객체 클래스 내에 @Autowired 어노테이션으로 지정해 간략히 지시할 수 있다.
    @Bean // 빈 등록 - 메서드처럼 작성한다
    public Car car(Engine e) {
        Car c = new Car();
        c.setEngine(e); 
        return c;
    }
    @Bean
    public Engine engine() {
        return new Engine();
    }
}

// ApplicationContextExam03.java
package kr.or.connect.diexam01;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class ApplicationContextExam03 {

    public static void main(String[] args) {
        // 설정이 담긴 클래스(Java Config) 매개변수로 전달
        // 스프링 컨테이너가 생성되고, 빈들 또한 모두 생성
        ApplicationContext ac = new AnnotationConfigApplicationContext(ApplicationConfig.class);

        Car car = (Car)ac.getBean("car");
        // Car car = (Car)ac.getBean(Car.class);
        car.run();
    }
}
  • @ComponentScan 활용
// ApplicationConfig2.java
package kr.or.connect.diexam01;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("kr.or.connect.diexam01") // 패키지를 지정
public class ApplicationConfig2 {
}

// ApplicationContextExam04.java
package kr.or.connect.diexam01;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class ApplicationContextExam04 {

    public static void main(String[] args) {
        // 설정이 담긴 클래스를 매개변수로 전달
        // 스프링 컨테이너가 생성되고, 빈들 또한 모두 생성
        ApplicationContext ac = new AnnotationConfigApplicationContext(ApplicationConfig2.class);

        Car car = (Car)ac.getBean(Car.class);
        car.run();
    }
}

// Car.java
package kr.or.connect.diexam01;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Car {
    @Autowired // 외부 객체 주입을 지시한다
    private Engine v8;

    public Car() {
        System.out.println("Car 생성자");
    }
    // @Autowired 어노테이션으로 대체
    //public void setEngine(Engine e) {
    //    this.v8 = e;
    //}
    public void run() {
        System.out.println("엔진을 이용하여 달립니다.");
        v8.exec();
    }
}

// Engine.java
package kr.or.connect.diexam01;
import org.springframework.stereotype.Component;

@Component
public class Engine {
    public Engine() {
        System.out.println("Engine 생성자");
    }
    public void exec() {
        System.out.println("엔진이 동작합니다.");
    }
}



출처) 부스트코스 풀스택 강의 https://www.boostcourse.org/web316/lecture/20658?isDesc=false