본문 바로가기
Spring

[Spring] Annotation, Bean, Stereotype, Configuration, Autowired

by Real Iron 2019. 2. 14.

1. Annotation

그냥 찾아보면 주석이라 나오지만 기능이 있으므로 우리가 코드 설명을 위해 붙여놓는 주석과는 차이가 있다.

JDK5부터 나왔으며 메타데이터(실제데이터가 아닌 데이터를 위한 데이터)라고도 불린다. 컴파일 또는 런타임에 해석이 된다.

설정값들을 명시한다는 점에서 xml과 비슷하지만 xml은 외부에 존재하고, 필요한 경우 이미 빌드한 결과에 재 컴파일할 필요없이 xml에서 설정만 수정하여 변경사항을 적용할 수 있다. 그렇지만 프로그램 작성을 위해 매번 많은 설정파일을 작성해야한다.

Annotation은 선언위에 존재해서 어떤 내용인지 쉽게 판단할 수 있으며 작성할 코드의 양도 적은 편인다. 그렇지만 xml도 위에서 말한 장점이 있으므로 annotation을 사용한다고 해서 xml을 아예 사용 안하는 것은 아니다.


2. Bean으로 만드는 annotation

어떤 클래스를 bean으로 만들기 위해선 @Bean을 사용하거나 @Component를 사용하면 된다. 그렇지만 Bean과 Component는 차이가 있다.

사용하는 관점에서 차이점은 아래와 같다.

    • @Component는 클래스 상단에 적으며 그 default로 클래스 이름이 bean의 이름이 된다. 또한 spring에서 자동으로 찾고 관리해주는 bean이다.

    • @Bean은 @Configuration으로 선언된 클래스 내에 있는 메소드를 정의할 때 사용한다. 이 메소드가 반환하는 객체가 bean이 되며 default로 메소드 이름이 bean의 이름이 된다.

예를 들어 아래와 같이 사용한다.

1
2
3
4
5
@Component
public class TestBean
{
    ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class TestBean
{
    ...
}
 
@Configuration
public class TestConfig
{
    @Bean
    public TestBean testBean()
    {
        return new TestBean();
    }
}

Component와 Bean 둘 다 목적이 불분명한 객체를 bean으로 만들 때 사용한다.


3. Stereotype

원래 bean을 정의하기 위해선 xml에 명시적으로 정의하는 것이 기본이었다. 하지만 Spring 2.0버전 이후로 classpath scanning을 하면서 Spring framework가 자동으로 관리할 bean을 정의할 수 있는 annotation이 생겼다. 이것이 stereotype이다.

Spring 2.0에서 @Repository annotation이 stereotype으로 처음 소개되었다. 그리고 Spring 2.5에 @Component, @Service, @Controller 등의 더 많은 stereotype annotation이 생겼다. 

@Component는 위에서 말했듯이 목적이 불분명한 클래스를 bean으로 만들 때 사용하고 나머지 @Repository, @Controller, @Service 모두 @Component를 좀 더 구체적으로 만든 것이다. (각각 persistence(DAO), presentation, service layer에서 사용된다.)


4. @Configuration & @Bean

Spring 3.0 때 나타난 annotation이다. @Configuration으로 정의된 클래스는 @Bean으로 정의된 메소드들을 포함하며, 이 메소드는 Spring IoC Container에 의해 관리되는 오브젝트들의 instantiation, configuration, intialization 로직등을 담당한다.

아래와 같이 어떤 클래스를 Spring IoC Container에 의해 사용되는 클래스로 정의할 수 있다.

1
2
3
4
5
@Configuration
public class TestConfig
{
    ...
}

@Configuration으로 정의된 클래스 또한 @Component의 확장형(meta-annotated)이다. 그래서 @Autowired로도 찾을 수 있다.


@Bean은 메소드 레벨 annotation이며 몇가지 속성과 같이 쓸 수 있다.(init-method, destroy-method, autowiring, name 등) Configuration 클래스 안에서 정의된 메소드에 @Bean을 붙여 사용할 수 있다. 이렇게 정의된 메소드는 BeanFactory 내에서 쓰일 수 있다는데, BeanFactory는 아직 생소한 개념라 공부를 해야한다. 위에서 설명한대로 default로 메소드 이름이 bean 이름이 된다.


@Bean에 여러가지 설정(lifecycle에 따라 메소드 호출, scope설정, bean name 설정 등)을 할 수 있는데 참조에 있는 Bean에 관련된 링크를 통해 한 번씩 읽어보면 좋다. (단지 영어다..)


5. Autowired

@Autowired annotation은 bean을 자동으로 삽입해주며 생성자, 필드, 메소드에 적용이 가능하다.

예를 들어 아래 코드처럼 메소드를 @Autowired와 같이 선언하면 매개변수에 bean이 자동으로 삽입된다.

1
2
3
4
5
6
7
8
public class AutowiredTest
{
    @Autowired
    public void autowiredTestMethod(TestBean testBean)
    {
        ...
    }
}

매개변수 명이 bean이름(@Bean annotation이 쓰인 메소드 이름)과 같은 것을 알 수 있다. 이렇게 bean이름과 의존성 주입(DI)을 하려는 객체 이름이 같으면 단순히 @Autowired annotation만 사용하면 된다.


하지만 bean이름과 객체 이름이 다를 경우 @Qualifier annotation을 써야한다. @Autowired 다음에 @Qualifier annotation을 사용하면 어떤 bean을 주입할 지 명시할 수 있다. 아래 코드와 같이 사용할 수 있다.

1
2
3
4
5
6
7
8
9
public class AutowiredTest
{
    @Autowired
    @Qualifier("testBean")
    public void autowiredTestMethod(TestBean abc)
    {
        ...
    }
}

만약 bean으로 선언할 때 bean 이름을 바꾸고 싶다면 @Bean annotation에서 name과 autowire property를 변경해서 @Autowired annotation과 바뀐 이름으로 연동되게 할 수 있다. 아래 코드와 같이 사용할 수 있다.

1
2
3
4
5
6
7
8
9
@Configuration
public class TestConfig
{
    @Bean(name="anotherNameBean", autowire=Autowire.BY_NAME)
    public TestBean testBean()
    {
        return new TestBean();
    }
}

이러면 testBean이라는 이름의 bean이 anotherNameBean이라는 이름이 되고 @Qualifier("anotherNameBean")으로 bean을 찾으면 된다.


* 참고

Annotation 관련

http://hiddenviewer.tistory.com/88


@Component와 @Bean 차이

https://stackoverflow.com/questions/10604298/spring-component-versus-bean

http://therealdanvega.com/blog/2017/05/17/spring-component-vs-bean


Stereotype

https://stackoverflow.com/questions/42334096/spring-repository-annotation-for-dao/42370493


@Bean 관련

https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s12.html


@Autowired, @Qualifier 관련

http://jinhokwon.tistory.com/29

https://code.i-harness.com/ko/q/1283ece