스프링, DI 시 Optional 처리하기

    스프링, DI 시 Optional 처리하기


    스프링에서 @ComponentScan으로 스프링 빈을 자동등록할 때, @Autowired의 에노테이션을 활용해서 스프링 빈의 의존관계가 자동 주입된다. @Autowired는 @Autowired(required = true)로 되어있다. 즉, 의존관계를 주입할 대상이 없으면 오류가 발생하게 된다. 그렇지만 의존관계를 주입할 대상이 없더라도 동작해야 하는 경우(수정자 주입)가 있다. 이 때는 어떻게 동작을 해야할까? 

    이 상황에서 동작가능한 방법은 세 가지가 있다.

    1. @Autowired(required = false) 설정
    2. 매개변수 앞에 @Nullable
    3. 매개변수를 Optional<T> 로 감싸기

    위 방법들에 대해 하나하나 차이점을 아래에서 살펴보려고 한다.

    1. Autowired(required = false) 설정


    @Autowired(required = false)
            public void setNoBean1(Member member){
                System.out.println("Testbean.setNoBean1");
            }

    Autowired(reuqire = false) 어노테이션을 설정하면, 의존관계 주입할 대상이 없으면 이 메서드는 호출이 되지 않는다. 

     

    2. 매개변수 앞에 @Nullable


            @Autowired
            public void setNoBean2(@Nullable Member member){
                System.out.println("Testbean.setNoBean2");
            }

    매개변수 앞에 @Nuallable을 붙이면, 이 메서드는 호출이 된다. 대신에 Null이 들어가게 된다.

     

    3. 매개변수를 Optional<T>로 감싸기


            @Autowired
            public void setNoBean3(Optional<Member> member){
                System.out.println("Testbean.setNoBean3");
            }

    매개변수의 Type을 Optional로 감쌀 경우, 이 메서드는 호출이 된다. 대신에 Optional.empty라는 값이 들어가게 된다. 

     

    실행 결과 확인해보기


    위의 각 경우에 대해서 Static Class를 만들고, Static Class를 AnnotataionConfig에 등록해보면 2,3번 메서드만 호출되는 것을 확인할 수 있다. 

      @Test
        void test1(){
            AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Testbean.class);
    
            String[] beanDefinitionNames = ac.getBeanDefinitionNames();
            for (String beanDefinitionName : beanDefinitionNames) {
                System.out.println("beanDefinitionName = " + beanDefinitionName);
            }
        }
    
    // 빈이 등록되지 않아도 된다는 것을 보여준다.
        static class Testbean{
    
            @Autowired(required = false)
            public void setNoBean1(Member member){
                System.out.println("Testbean.setNoBean1");
            }
    
            @Autowired
            public void setNoBean2(@Nullable Member member){
                System.out.println("Testbean.setNoBean2");
            }
    
    
            @Autowired
            public void setNoBean3(Optional<Member> member){
                System.out.println("Testbean.setNoBean3");
            }
    
        }

    위의 실행 결과를 보면 Bean2,3 메서드만 호출된 것을 알 수 있다. 그리고 등록된 빈들을 한번 조회해보면 Testbean.class만 등록된 것을 알 수 있다. 이는 Member가 스프링의 빈이 아니라는 것을 보여준다. 

    댓글

    Designed by JB FACTORY