진짜 개발자
본문 바로가기

FrameWork/Spring

Spring - @Bean 어노테이션과 @Component 어노테이션(DI) - 2

728x90
@Component, @Bean

프로그램이 거대해 짐에 따라 XML을 이용하여 IOC Container를 설정하는 것이 점점 어려워졌고 때문에 Annotation(@)이란 것이 등장했다(이하 어노테이션). 어노테이션은 코드에 메타데이터를 작성하여 직관적인 코딩이 가능하게 만들어주며 이에 따라 생산성이 증대되는 장점을 가지고 있다.



1. @Configuration

@Configuration Configuration 어노테이션은 스프링 IOC Container에게 해당 클래스를 Bean 구성 Class임을 알려주는 것이다.

 


 

2. @Bean vs @Component

@Bean어노테이션과 @Component어노테이션 둘다 Spring(IOC) Container에 Bean을 등록하도록 하는 메타데이터를 기입하는 어노테이션이다. 그렇다면 왜 두개나 만들어 놓았을까? 정답은 둘의 용도가 다르기 때문이다.

2.1. @Bean

@Bean어노테이션의 경우 개발자가 직접 제어가 불가능한 외부 라이브러리등을 Bean으로 만들려할 때 사용된다.

 

위는 @Bean 어노테이션을 이용하여 Bean을 생성한 예제이다. 위와 같이 ArrayList같은 라이브러리등을 Bean으로 등록하기 위해서는 별도로 해당 라이브러리 객체를 반환하는 Method를 만들고 @Bean어노테이션을 붙혀주면 된다. 위의 경우 Bean어노테이션에 아무런 값을 지정하지 않았으므로 Method 이름을 CamelCase로 변경한 것이 Bean id로 등록된다. (ex. 메소드 이름이 arrayList()인 경우 arrayList가 Bean id)

 

위와 같이 @Bean어노테이션에 name이라는 값을 이용하면 자신이 원하는 id로 Bean을 등록할 수 있다. 어노테이션 안에 값을 입력하지 않을 경우 메소드의 이름을 CamelCase로 변경한것이 Bean의 id가 된다.

 

의존관계가 필요할 때에는 어떻게 해결할 수 있을까? Student객체의 경우 생성자에서 ArrayList를 주입 받도록 코드를 짜놓았다 이럴때에는 Bean으로 선언된 array()메소드를 호출함으로써 의존성을 주입할 수 있다.

 

 

2.2. @Component

@Component 어노테이션의 경우 개발자가 직접 작성한 Class를 Bean으로 등록하기 위한 어노테이션이다. 아래의 예제를 보자

 

Student Class는 개발자가 사용하기 위해서 직접 작성한 Class이다 이러한 클래스를 Bean으로 등록하기 위해 상단에 @Component어노테이션을 사용한것을 볼 수 있다.

 

@Component역시 아무런 추가 정보가 없다면 Class의 이름을 Camelcase로 변경한 것이 Bean id로 사용된다. 하지만 @Bean과 다르게 @Component는 name이 아닌 value를 이용해 Bean의 이름을 지정한다.

 

 @Autowired


 @Component를 사용한 Bean의 의존성 주입은 @AutoWired 어노테이션을 이용하여 할 수 있다. 위와 같이 Student가 Pencil에 대한 의존성을 가지고 있는 경우 @AutoWired 어노테이션을 이용하여 의존성을 자동으로 주입할 수 있다. 이때 당연히 Pencil도 @Component 어노테이션을 가지고 있어야 한다. 그래야만 IOC Container에 Bean으로 등록이되기 때문이다.


@Autowired 어노테이션의 경우 형(타입)을 통해 해당 자리에 들어올 객체를 판별하여 주입해준다. 따라서 해당 자리에 들어올 수 있는 객체가 여러개인 경우, 즉 다형성을 띄고있는 객체타입에 @Autowired를 사용한 경우에는 @Qualifier("Bean이름") 을 이용하여 해당 자리에 주입될 Bean을 명시해주어야 한다. 


위의 그림에서는 Goods라는 인터페이스를 Computer 와 Book이 구현하고 있으므로 Person클래스의 goods 참조변수에 위치할 수 있는 Bean이 Book,Computer 두가지 이다 때문에 @Qualifier("Bean이름")을 통해 해당 자리에 위치할 빈을 명시했다



3. 사용방법

3.1 @Bean

 

우선 의존성 주입 대상 Class를 생성한다. 생성자가 호출될 때 콘솔창에 "hi"를 출력하도록 했다.

 

Student를 Bean으로 등록하기 위해 Config Class를 임의로 만들고 @Configuration어노테이션을 부여했다. 그 후 Student 객체를 반환하는 Method를 작성하고 @Bean어노테이션을 부여한다.

 

Annotation을 기반으로 Bean을 등록했으므로 AnnotationConfigApplicationContext객체를 생성하고 매개변수로 @Configuration어노테이션을 부여한 ApplicationConfig 클래스를 넘겨준다. 그 후 getBean을 이용하여 사용하면 된다.

 

 

3.2 @Component

@Component어노테이션이 부여된 Class들은 자동으로 IOC Container에 Bean으로 등록이 되는데 IOC Container 에게 이러한 어노테이션이 부여된 Class를 자동으로 Bean으로 등록하라고 하기 위해서 XML파일에 따로 설정이 필요하다.

 

우선 xml파일을 연뒤 하단에 Namespaces 탭을 클릭한뒤 context를 체크한 다음 저장을 한다.

 

다시 Source 탭으로 돌아와 <context:component-scan base-package="com.java.ex"></context:component-scan> 코드를 추가해주면 준비는 완료된다.

 

@Component 어노테이션을 부여한 Student 클래스이다.

 

Main 클래스에서는 기존 XML을 이용하여 의존성을 주입하듯 객체를 생성하면 된다.

 

 


4. 요약

@Component는 개발자가 직접 작성한 ClassBean으로 만드는 것이고. @Bean은 개발자가 작성한 Method 를 통해 반환되는 객체를 Bean으로 만드는것 이다. 또한 각자의 용도가 정해져있으므로 정해진 곳에서만 사용가능하며 다른곳에서 사용하려한다면 Compile 에러를 내뱉는다.