Spring Boot 3 & Spring Framework 6 - section 3

이정수·2024년 6월 29일

Udemy학습-Spring & React

목록 보기
19/20

Auto-Wiring 기능을 활용해서 Spring Bean 자동생성하기.

  • 기존의 방법은 Spring Bean을 수동으로 생성하는 방법!
import org.springframework.stereotype.Component;
@Component
public class MarioGame implements GamingConsole {
    public void up(){
        System.out.println("jump");
    }
    public void down(){
        System.out.println("go down");
    }
    public void left(){
        System.out.println("go back");
    }
    public void right(){ System.out.println("go forward"); }
}

@Bean Method를 통해 Spring Bean instance 생성 시 필요로하는 GamingConsole interface를 상속한 Class로서 @ComponentScan에 의해 식별되어 Auto-Wiring 되기 위하여 @Component 선언하여 Spring Bean으로 등록.

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
@Component
//@Configuration
@ComponentScan("com.wjdtn747.rest.webservices.practice.Practice3")
public class App03GamingSpringBean {
    @Bean
    public GameRunner game1(GamingConsole gamingSource) {
        return new GameRunner(gamingSource);
    }
    public static void main(String[] args) {
    // Spring Context 생성
        try( var springContext = new AnnotationConfigApplicationContext(App03GamingSpringBean.class)){
            springContext.getBean(GameRunner.class).run();
        }
    }
}

try(실행 할 코드){성공 시 실행할 코드}catch(Exception e){예외발생 시 실행할 코드}

Spring Context class 내 Bean을 삭제한 경우

  • SpringContextClass 에서 선언된 @Bean game1를 삭제
  • GameRunner class 앞에 @Component라고 선언.
  // GameRunner.java
import org.springframework.stereotype.Component;
@Component
public class GameRunner {
    GamingConsole game;
    public GameRunner(GamingConsole game) {
        this.game = game;
    }
    public void run(){
        System.out.printf("running game is : %s",this.game );
        game.up();
        game.down();
    }
}
  // App03GamingSpringBeans.java
@ComponentScan("com.wjdtn747.rest.webservices.practice.Practice3")
public class App03GamingSpringBean {
       public static void main(String[] args) {
        try( var springContext = new AnnotationConfigApplicationContext(App03GamingSpringBean.class)){
            springContext.getBean(GameRunner.class).run();
        }
    }
}

Spring Context를 포함하는 Class는 @Configuration 또는 @Component을 포함하는 Configuration class이어야하나, 이미 @ComponentScan을 통해 자동으로 @Component를 선언한 class를 식별하여 해당 class의 Spring Bean instance이 생성되어 등록하므로 필요없다.

Spring Context Class 에서 선언된 @Bean game1을 삭제 후 GameRunner classMarioGame class 앞에 각각 @Component로 선언

Spring Context Class에서 @ComponentScan을 통해 이들 Spring Bean이 위치한 경로를 설정 후 class들을 Spring Bean으로서 호출 시 @Component로 선언된 각각의 class에서 Spring Bean Instance를 생성하여 Auto-Wiring.
▶ 해당 @Bean 메소드를 통해 GameRunner Spring Bean Instance를 생성하는 방식에서 해당 GameRunner class에 @Component를 선언하여 Spring Bean instance를 생성하여 활용함으로써 Spring Context에 의해 식별되어 종속성이 정의되는 방식으로 설정.

Spring Context가 Spring Bean을 자동으로 생성 후 Auto-Wiring.

특정 Spring Context에서 어떤 Spring Bean이 사용되는지 확인하는 방법

  • Arrays.stream(SpringContext객체.getBeanDefinitionNames()).forEach(System.out::println);
    SpringContext객체.getBeanDefinitionNames())
  // App03GamingSpringBeans.java
@ComponentScan("com.wjdtn747.rest.webservices.practice.Practice3")
public class App03GamingSpringBean {
       public static void main(String[] args) {
        try( var springContext = new AnnotationConfigApplicationContext(App03GamingSpringBean.class)){
            Arrays.stream(springContext.getBeanDefinitionNames()).forEach(System.out::println);
        }
    }
}

AutoWiring을 활용한 Spring Bean instance 생성방법 예시

package com.wjdtn747.springframework.Injection;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
interface DataService{
    int[] retrieveData();
}
@Component
@Primary
class MongoDbDataService implements DataService{
    public int[] retrieveData(){
        return new int[]{11,22,33,44,55};
    }
}
@Component
@Qualifier("sqlQual")
class MySQLDataService implements DataService{
    public int[] retrieveData(){
        return new int[]{1,2,3,4,5};
    }
}
@ComponentScan
// 경로설정 X -> 해당 package 내에서 @Component를 scan.
public class BusinessCalculationService {
    DataService dataService;
    public BusinessCalculationService(@Qualifier("sqlQual") DataService ds){
        this.dataService = ds;
    }
    public int findMax(){
        return Arrays.stream(dataService.retrieveData()).max().orElse(0);
    }
    public static void main(String[] args) {
        try(var ct = new AnnotationConfigApplicationContext(BusinessCalculationService.class)){
            System.out.println(ct.getBean(BusinessCalculationService.class).findMax());
        }
    }
}


@Qualifier로 AutoWire된 Spring Bean(= sqlQual )의 Stream( = Array )의 최댓값을 return.

profile
공부기록 블로그

0개의 댓글