본문 바로가기

Spring/Spring 공부

2. IOC 코드 실습

예전 했던 코드로 IOC 코드 실습을 진행했다.

@Component: class에 붙이면 Spring bean 취급을 한다.

 

@Component
import org.springframework.stereotype.Component;

import java.util.Base64;
@Component
public class Base64Encoder implements IEncoder{
    public String encode(String message){
        return Base64.getEncoder().encodeToString(message.getBytes());
    }
}
@Component
public class UrlEncoder implements  IEncoder {

    public String encode(String message){
        try {
            return URLEncoder.encode(message, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }
}

 

 

Bean으로 등록되는 것을 볼 수 있다.

이렇게 되면 스프링이 실행이 될 때 어노테이션이 붙은 클래스를 찾아서 직접 객체를 싱글톤 형태로 만들어서 스프링 컨테이너에서 관리를 한다.

 

이걸 쓰는 법.

 

 

스프링컨테이너에 접근해서 꺼내오면 된다.

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class ApplicationContextProvider implements ApplicationContextAware {

    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }
    public static ApplicationContext getContext(){
        return context;
    }
}

 

스프링 어플리케이션이 실행이 될 때 Provider를 만들 때 set메서드에 어플리케이션컨텍스트를 주입시키고 그걸 받아서 static 변수에 할당을 하고 그것을 받아서 쓴다.

 

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

import java.util.Base64;

@SpringBootApplication
public class SpringIocApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringIocApplication.class, args);

        ApplicationContext context = ApplicationContextProvider.getContext();

        Base64Encoder base64Encoder = context.getBean(Base64Encoder.class);
        Encoder encoder = new Encoder(base64Encoder);
        String url =  "www.naver.com/books/it?page=10&size=20&naver=spring-boot";

        String result = encoder.encode(url);
        System.out.println(result);
    }

}

 

Bean을 찾는 방법은 몇 가지 있는데 클래스 타입을 가지고 찾았다.

 

Bean을 주입 받을 수 있는 장소는 변수, 생성자, Set메서드가 있다.

 

정리

@Coponent를 붙이면 Spring이 관리를 시작한다 => 제어의 역전, IOC

 

그런데 컴포넌트가 여러 개이면 스프링에서 어떤 것을 매칭할 지 결정을 못한다.

그럴 때에는 @Qulifier 라는 어노테이션을 사용하여 무엇을 사용할 지 정해주면 된다.

package com.example.springioc;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class Encoder {

    private IEncoder iEncoder;

    public Encoder(@Qualifier("base64Encoder") IEncoder iEncoder){
        this.iEncoder = iEncoder;
    }

    public void setIEncoder(IEncoder iEncoder){
        this.iEncoder = iEncoder;
    }

    public String encode(String message){
        return iEncoder.encode(message);
    }
}

 

base64Encoder를 매칭 시켰다.

그럼 실행 코드는

@SpringBootApplication
public class SpringIocApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringIocApplication.class, args);

        ApplicationContext context = ApplicationContextProvider.getContext();

        //Base64Encoder base64Encoder = context.getBean(Base64Encoder.class);
        //UrlEncoder urlEncoder = context.getBean(UrlEncoder.class);

        Encoder encoder = context.getBean(Encoder.class);
        String url =  "www.naver.com/books/it?page=10&size=20&naver=spring-boot";
        String result = encoder.encode(url);
        System.out.println(result);
    }

}

 

이렇게 간결하게 된다.

객체가 전부 Spring Container에 관리되고 있다.

스프링컨테이너에 관리되는 객체를 bean이라고 부른다.

특정 클래스에서 new로 생성되는 개체를 bean이라 생각하면 된다.

 

정리: Component 어노테이션을 붙여서 스프링에 주입 받아서 사용한다.

 

2개의 인코더를 사용하고 싶을 때 사용하는 방법.

 

직접 Bean으로 등록.

@Configuration

한 개 클래스에서 여러개의 Bean을 등록 한다는 것.

@Configuration
class AppConfig{

    @Bean("base64Encode")
    public Encoder encoder(Base64Encoder base64Encoder){
        return new Encoder(base64Encoder);
    }

    @Bean("urlEncode")
    public Encoder encoder(UrlEncoder urlEncoder){
        return new Encoder(urlEncoder);
    }

}

이런 식으로 작성할 수 있다.

Encoder 라는 bean이 중복되었는데 Bean에 이름을 붙이면 해결 된다.

 

서비스 로직에서는 new를 사용하지 않고 Spring Context에 저장하여 불러오고 생성자나 set 메서드 변수에 어노테이션을 통해 직접 객체를 받아오는 방식으로 진행된다.

 

정리: 스프링에서 객체를 직접 관리하고 그 객체를  Bean이라 불리고 그 Bean은 스프링 컨테이너고 스프링이 권한을 다 가져갔기 때문에 제어의 역전이 일어났고 그것이 IOC라고 한다.

 

쉽게 이야기 하면

스프링 컨테이너를 관리하는 것 = IOC

그리고 그것을 통해 주입을 받는다 = DI

라고 생각하면 편할 것 같다.

'Spring > Spring 공부' 카테고리의 다른 글

6. Spring Boot Annotations  (0) 2022.07.03
5. ObjectMapper  (0) 2022.07.02
4. AOP 코딩 실습-2  (0) 2022.07.02
3. AOP 코드 실습  (0) 2022.07.01
1. IoC, DI/ DI 관련 코드 실습  (0) 2022.06.30