[Spring] Component Annotation으로 Bean 자동 등록하기
Spring에서 Bean을 등록하기 위해서는 Bean 설정 xml파일이라면 <bean> 태그로, Java 파일을 이용한 등록이라면 @Configuration과 @Bean Annotation을 이용하여 Bean을 등록하였다.
하지만 @Component라는 Annotation을 이용하면 xml파일이나 Java파일에 Bean을 등록하는 것이 아닌 해당 Bean클래스에서 바로 자동으로 등록이 가능하게 만들 수 있다.
@Component Anntation을 이용하기 위해서는 우선 Bean 설정 xml파일이나 Java파일에 @Component 애노테이션을 탐색할 수 있게 만드는 설정을 해주어야 한다.
@Component를 상속하는 여러 가지 Anntation이 있다.
@Controller, @Service, @Repository 등이 있으며 자세한 내용은 Spring 공식 문서에서 확인할 수 있다.
Spring Framework Reference Documentation
Authors Rod Johnson , Juergen Hoeller , Keith Donald , Colin Sampaleanu , Rob Harrop , Thomas Risberg , Alef Arendsen , Darren Davison , Dmitriy Kopylenko , Mark Pollack , Thierry Templier , Erwin Vervaet , Portia Tung , Ben Hale , Adrian Colyer , John Lew
docs.spring.io
(1) xml 파일에서 설정
xml 파일에 설정하기 위해서는 <context> 태그를 사용해야 한다. <context> 태그를 사용하기 위한 네임스페이스를 먼저 작성해준다.
xmlns:context="http://www.springframework.org/schema/context"
<!-- xsi:schemaLocation 부분에 추가 -->
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
위의 정보를 xml 파일에 추가해주어야 한다.
그 후 @Component Anntation을 탐색하기 위한 설정을 해준다.
<context:component-scan base-package="Bean 클래스의 패키지명" />
xml에 설정을 할 때는 <context::component-scan> 태그를 이용한다.
<context::component-scan>의 base-package 속성은 탐색할 패키지를 작성하면 되는데 여기서 작성할 패키지는 Bean 클래스가 있는 패키지의 이름이다.
만약 여러 패키지를 탐색하려면 <context::component-scan> 태그를 여러 번 작성하면 된다.
여기까지 했다면 xml에서의 설정을 끝이다.
(2) Java 파일에서 설정
Java 파일을 Bean 설정 파일로 쓰는 경우 아래와 같이 설정한다.
// Bean 설정 파일 Anntation
@Configuration
// @Component 설정 Annotation
@ComponentScan(basePackages="Bean 클래스의 패키지 이름")
public class BeanConfigClass {
}
자바 설정 파일에서는 @ComponentScan Annotation을 이용하며 소괄호 안에 basePackages에 Bean클래스의 패키지 명을 작성한다.
만약 여러 패키지를 작성하고자 한다면 아래와 같이 작성한다.
@ComponentScan(basePackages={"패키지명1", "패키지명2", "패키지명3"})
여러 패키지를 작성할 때는 중괄호 안에 쉼표로 구분하여 작성한다.
위의 설정을 해주었다면 Java파일에서 할 설정은 끝이다.
(3) @Component Anntation등록
위에서 설명한 설정을 했다면 이제 Bean 클래스에서 @Component를 등록하여 자동으로 Bean으로 등록하도록 만든다.
// Bean 클래스
@Component
public class TestBean {
}
@Component의 등록은 굉장히 간단하게 클래스 이름 윗부분에 등록만 해주면 된다.
만약 @Component를 등록해준 Bean클래스의 패키지가 Bean 설정 파일에서 탐색하도록 설정을 해두었다면 @Component를 붙여주는 것만으로도 Bean으로 등록이 된다.
@Component에 ( ) 소괄호를 붙여 안에 " " 큰따옴표로 Bean의 이름을 지정해줄 수 있다.
위 코드의 상태는 아래 코드들과 일치한다.
// 자바 파일에서 Bean 등록
@Bean
public TestBean1 java1() {
return new TestBean1();
}
<!-- xml 파일에서 Bean 등록 -->
<bean class="패키지 포함 클래스 이름" />
여기서 주의할 점은 @Component로 Bean을 등록한 Bean은 타입을 통한 Bean 등록이기 때문에 같은 클래스 타입의 Bean 다른 이름(id)으로 등록하기 위해서는 자바 설정 파일이나 xml을 이용하여 bean을 등록해주어야 한다.
위의 @Component Annotation을 이용하여 등록한 Bean의 객체 주소를 가져오는 코드를 살펴보자면 아래와 같다.
public class Main {
public static void main(String[] args) {
// xml 파일에 설정한 경우
ClassPathXmlApplicationContext ctx1 = new ClassPathXmlApplicationContext("xml 파일의 이름");
TestBean bean1 = ctx1.getBean(TestBean.class);
System.out.println("bean1 : " + bean1);
ctx1.close();
// 자바 파일에 설정한 경우
AnnotationConfigApplicationContext ctx2 = new AnnotationConfigApplicationContext(자바 빈 설정 파일 이름.class);
TestBean bean2 = ctx2.getBean(TestBean.class);
System.out.println("bean2 : " + bean2);
ctx2.close();
}
}
(4) @Component 자동 주입
@Component 자동 주입은 기존의 자동 주입과 전혀 다르지 않다.
- @Autowired
- @Qualifier
- 생성자인 경우 타입이 같은 Bean을 찾아 자동 주입
- JSR-250 라이브러리를 이용하는 경우 @Resource 사용 가능
위와 같이 기존에 사용하던 자동 주입과 전혀 다르지 않다.
Bean 클래스 하나를 예를 들자면 아래와 같다.
@Component
public class TestBean1 {
@Autowired
private DataBean1 data1;
@Autowired
@Qualifier("obj2")
private DataBean2 data2;
@Resource(name="obj3")
private DataBean3 data3;
@Resource(name="obj4")
private DataBean3 data4;
@Resource(name="obj5")
private DataBean3 data5;
public DataBean1 getData1() {
return data1;
}
public DataBean2 getData2() {
return data2;
}
public DataBean3 getData3() {
return data3;
}
public DataBean3 getData4() {
return data4;
}
public DataBean3 getData5() {
return data5;
}
}
@Autowired와 @Qualifier, @Resource 등을 이용하여 자동 주입을 하는 예제이다.
만약 생성자를 통한 자동주입을 하려면 아래와 같다.
@Component
public class TestBean2 {
private int data1;
private String data2;
private DataBean4 data3;
private DataBean5 data4;
public TestBean2(@Value("100")int data1, @Value("문자열")String data2, DataBean4 data3, DataBean5 data4) {
this.data1 = data1;
this.data2 = data2;
this.data3 = data3;
this.data4 = data4;
}
public int getData1() {
return data1;
}
public void setData1(int data1) {
this.data1 = data1;
}
public String getData2() {
return data2;
}
public void setData2(String data2) {
this.data2 = data2;
}
public DataBean4 getData3() {
return data3;
}
public void setData3(DataBean4 data3) {
this.data3 = data3;
}
public DataBean5 getData4() {
return data4;
}
public void setData4(DataBean5 data4) {
this.data4 = data4;
}
}
기본 타입 혹은 String형은 생성자의 매개변수에서 @Value를 이용하여 값을 주입할 수 있다.
본 포스팅은 필자가 공부한 내용을 정리한 것으로 오류가 존재할 수 있습니다.
참고 : 인프런 - 스프링 프레임워크 개발자를 위한 실습을 통한 입문 과정