BackEnd/패캠

Ioc, DI

제이드Jade 2022. 1. 18. 00:00
@Component  //야야야 이거 스프링 니가 관리해!!!!(스프링이 의존성 주입  
		: 의존의 역치, Inversion of Control : IoC) => 클래스를 bean으로 등록한 것
            //스프링이 실행되면 스프링이 @component가 붙은 클래스를 찾아서 객체를 싱글톤으로 만들어 스프링 컨테이너에서 모든 생명주기를 관리
            //@Component("bean이름")으로 이름도 만들어 줄 수 있음, 지정안하면 클래스이름의 첫글자를 소문자로 바꾼 것이 된다.
public class Base64Encoder implements IEncoder {
    @Override
    public String encode(String message) {
        return Base64.encode(message.getBytes());
    }
}
@Component
public class Encoder {
    private IEncoder iEncoder;

    public Encoder(@Qualifier("base64Encoder") IEncoder iEncoder){  // 의존하고있는게 두개 이상이면 어떤 것을 주입해줘야 하는지 결정을 못함=> Qualifier("bean이름")으로 명시해주면 됨
// 또한, 컴포넌트의 생성자에서 어떤 클래스를 주입 받는다면, 그 클래스 또한 컴포넌트여야 한다.(여기선 IEncoder 를 구현하는 클래스들)
.	…}

(일단 컨텍스트를 생성해봄)


//스프링 컨테이너에서 객체들을 꺼내오기 위한 코드를 작성한다!!
@Component  //bean으로 관리
public class ApplicationContextProvider implements ApplicationContextAware {

    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {    //얘도 스프링이 주입해줌
        this.context=applicationContext;
    }

    public static ApplicationContext getContext(){  //글애서 이것만 호출해도 의존성이 잘 주입된(값이 잘 지정된) context를 리턴해줄거임
        return context;
    }
}

@SpringBootApplication
public class SpringIocApplication {
    //new로 객체를 직접 생성한 부분이 없음~ 모든 권한이 스프링으로 넘어 간 것(IoC) / 왼쪽 맨 위 돋보기를 누르면 스프링 컨테이너에서 관리되는 객체(=bean)의 목록을 알 수 있다.
    public static void main(String[] args) {
        SpringApplication.run(SpringIocApplication.class, args);
        ApplicationContext context=ApplicationContextProvider.getContext(); //컨테이너로부터 객체를 꺼내올 수 있게 해주는 놈, (스포: 나중에 update될 요소)
        //bean을 찾는 방법 => 방법1)이름으로, 방법2)클래스 타입으로

//        Base64Encoder base64Encoder=context.getBean(Base64Encoder.class);   //방법2)로 bean을 찾아옴
//        UrlEncoder urlEncoder=context.getBean(UrlEncoder.class);

        String url="www.naver.com";
//        Encoder encoder=new Encoder(base64Encoder); //내가 의존성 주입
//        Encoder encoder=context.getBean(Encoder.class); //스프링이 의존성 주입
        Encoder encoder=context.getBean("urlEncode",Encoder.class);
        //encode클래스를 @component로 등록하고 -> 위에 url를 컨테이너에서 가져오고 -> encoder를 컨테이너에 가져와서 -> set으로 url을 매개변수로 줬던 것이 한번에 해결
        // (원랜 default로 base64가 주입됐었기 때문에 set으로 했던 것임)

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

//        encoder.setiEncoder(urlEncoder);
//        result=encoder.encode(url);
//        System.out.println(result);
    }

}

@Configuration //한개의 클래스에서 여러개,여러버전의 bean을 등록하고 싶을 때 => 해당 클래스들에 일일이 @Component 안붙여도 됨
class AppConfig{

    @Bean("base74Encode")   //<bean을 생산하는 메소드> encoder를 bean으로 등록
    public Encoder encoder(Base64Encoder base64Encoder){    //bean객체를 주입
        return new Encoder(base64Encoder);                  //context.getBean("base64Encode",Encoder.class);로 가져오면 이게 호출됨
    }

    @Bean("urlEncode")   //같은 bean이름 회피
    public Encoder encoder(UrlEncoder urlEncoder){  //context.getBean("base64Encode",Encoder.class);로 가져오면 이게 호출됨
        return new Encoder(urlEncoder);
    }
}