@Bean vs @Component

최진규·2023년 6월 8일
0

Bean

spring bean을 선언하는 여러가지 방법이 있다.
spring bean이란 spring ioc container에 의해 관리되는 특수한 인스턴스를 의미하는데,
보통은 singleton이다.
다른 scope들도 존재한다.

그런데 생각해보니 @Bean@Component 둘다 빈을 등록하는 어노테이션인데,
@Component위주로 사용하고 있었다.

@Bean을 사용하는 경우는 직접 Configuration을 통해서 bean을 등록하는 경우이다.

그래서 둘의 차이점에 대해서 정리해본다.

둘은 사용하는 용도가 다르다.

@Bean

@Bean은 개발자가 제어할 수 없는 객체를 spring bean으로 만들때 사용한다.
예를 들어서 외부 라이브러리가 있다.

또 메소드에 어노테이션을 달아서 반환되는 객체가 빈이된다.

일단은 간단하게 이런 configuration이 있다고 하자.

@Configuration  
public class ApplicationConfig {  
  
  @Bean  
  public ArrayList<String> arrayList() {  
    return new ArrayList<String>();  
  }  
}

예를 들어서 이런 경우에는 개발자가 제어하기 어려운 ArrayList 를 bean으로 만드는 경우이다.
별도로 해당 라이브러리의 객체를 반환하는 메소드를 선언하고 위에 @Bean을 붙여준다.

이름을 지정하고 싶으면 다음과 같이 하자.

@Configuration  
public class ApplicationConfig {  
  
  @Bean  
  public ArrayList<String> arrayList() {  
    return new ArrayList<String>();  
  }

  @Bean(name = "arrayListBean")  
  public ArrayList<String> arrayListBean() {  
    return new ArrayList<String>();  
  }
}

의존성 주입은 다음과 같이 한다.

@Configuration  
public class ApplicationConfig {  
  
  @Bean  
  public ArrayList<String> arrayList() {  
    System.out.println("set bean of arrayList with custom name");  
    return new ArrayList<String>();  
  }  
  @Bean(name = "arrayListBean")  
  public ArrayList<String> arrayListBean() {  
    System.out.println("set bean of arrayList");  
    return new ArrayList<String>();  
  }  
  @Bean  
  public Student student() {  
    System.out.println("set student bean");  
    return new Student(arrayListBean());  
  }  
  @RequiredArgsConstructor  
  public class Student {  
    private final ArrayList<String> arrayList;  
  }  
}

그리고 실제로 개발자가 제어하지 않는 라이브러리의 인스턴스를 Bean으로 만들었는데,
실제로 Singleton bean으로 잘 선언됬는지 체크해보자.

이런 테스트 코드를 작성해보자.

@SpringBootTest  
@RunWith(SpringRunner.class)  
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)  
public class ApplicationConfigTest {  
  
  @Autowired  
  ArrayList<String> arrayList;  
  
  @Autowired  
  ApplicationContext applicationContext;  
  
  @Test  
  @Order(1)  
  public void setArrayList() {  
    arrayList.add("asdf");  
    System.out.println("added");  
  }  
  @Test  
  @Order(0)  
  public void checkApplicationContext() {  
    ArrayList arrayList = applicationContext.getBean("arrayList", ArrayList.class);  
    Assert.assertNotNull(arrayList);  
  }  
  @Test  
  @Order(2)  
  public void printArrayList() {  
    System.out.println("arrayList = " + arrayList);  
  }}

대충 실행시켜보면 로그 잘 찍힌다.

@Component

그럼 @Component는 언제 사용하는 걸까 ?
이건 너무 당연하겠지만 개발자가 직접 작성한 클래스를 Spring Bean으로 만들기 위해 사용한다.

샘플로 코드를 작성해보자.

@Configuration  
public class ApplicationConfig {  

  @Component  
  public class Apple {    
    private Color color;  
    @Autowired  
    public Apple(Color color) {  
      this.color = color;  
      System.out.println("Apple bean creation completed");  
    }  
  }  
  
  @Component  
  public class Color {  
    private ColorVar colorVar;  
  
    public Color() {  
      this.colorVar = ColorVar.RED;  
      System.out.println("Color Bean Creation Completed");  
    } 
  }  
  
  public enum ColorVar {  
    RED, GREEN  
  }  
}

이렇게 @Component를 달면 끝 !

profile
개발하는 개복치

0개의 댓글