article thumbnail image
Published 2022. 6. 1. 17:59

1. @Component

  • @Component 어노테이션을 이용하면 Bean Configuration 파일에 Bean을 따로 등록하지 않아도사용할 수 있다.
  • 빈 등록 자체를 빈 클래스 자체에다가 할 수 있다는 의미이다.
  • @Component 어노테이션은 기본적으로 타입 기반의 자동 주입 어노테이션이다.
  • @Autowired, @Resource와 비슷한 기능을 수행한다고 할 수 있다.

2. Java configuration 파일에서 @Component 설정하기

  • @Configuration 어노테이션 아래에 @ComponentScan(basePackages="패키지 경로")이라는 어노테이션을 써줌으로서 해당 패키지 안에 있는 bean 클래스의 어노테이션을 분석할 수 있도록 설정해줄 수 있다.

javacb1이라는 빈을 만들어서 패키지안에 등록되어 있는 bean클래스(comBean 클래스) 를 return하는 빈을 등록해준다.

이 빈을 메인에 출력해보면, 

다음과 같이 그냥 comBean1.class를 가져오는것 만으로도 빈을 가져올 수 있다.

@Component 어노테이션은 타입기반으로 빈을 등록해주는 놈이라서 이름을 써주지 않고 클래스만 넣어주면 된다.

 

3. @Component

위에서 설명했던것 처럼 @Component는 타입을 통해 등록된 Bean객체를 가져올 수 있다.

또한 IoC컨테이너 객체를 생성할 때 자동으로 객체가 생성되며, Singleton이다.

기본생성자를 만들고 실행해서 생성자가 언제 호출되는지를 확인해보았다.

getBean하여 객체를 가져오기 전에 comBean1클래스의 기본생성자가 호출된 모습을 볼 수 었다.

또한, 빈 객체의 범위는 싱글톤이기 때문에 객체를 두번 호출하면 같은 객체가 출력되는것을 확인하였다. 

 

4. @Component("빈 이름")

@Component 어노테이션도 빈을 설정하는 어노테이션이기 때문에 빈의 이름을 따로 정해줄수도 있다. 괄호열고 빈이름을 적어주면 된다. 그런데 @Component는 특징이 있다.

 

한개의 패키지 내에서 여러개의 이름으로 빈을 등록하는 것이 불가능하다는 것이다.

 

@Component는 이름을 셋팅할 때 쓴다기보다는 이름이 없이 딱 타입을 통해서 가지고 오는 빈들... 즉, 전체 프로그램에서 특정 클래스타입의 빈을 딱 한번 등록해서 사용할 경우에 사용된다.

 

같은 클래스 타입으로 여러개의 이름으로 빈을 등록하려면 xml파일을 이용하거나 java configuration 파일을 이용해서 빈을 여러개 정의해주면 되겠다.

 

 

 

이로 인해서 @Bean 과 @Component 를 사용해야 할 경우를 다음과 같이 비교해볼 수 있다.

 

- @Bean :             개발자가 Class코드를 수정할 수 없을 때

                           같은 클래스 타임의 Bean을 여러개 등록할 때

 

- @Component    개발자가 Class코드를 수정할 수 있을 때

다음과 같이 이름을 "test"라고 지정하고 @Component를 사용하였다. 

이렇게하면, test라는 이름으로 빈을 가져오는것이 가능하다.

위에서 말했듯이 @Component를 사용하면 빈의 이름을 같은 패키지 안에서 여러개 지정할 수 없다..

@Component("test1", "test2")와 같은 형태는 존재하지 않는다는 것이다.

 

따라서, 같은 타입의 빈 클래스를 여러개이름을 부여하여 사용하기 위해서는 java configuration 파일을 사용한다. 

 

5. @Component의 여러 가지 설정

@Component

@Lazy

-> getBean을 할 때 객체를 생성하는 Lazy속성이다. 

 

 

@Component

@Scope("prototype")

-> Default가 싱글톤으로 설정된 객체 생성에 범위를 prototype으로 바꾸어준다. 이렇게 하면 객체가 생성될때마다 새로운 객체가 생성된다.

 

 

 

@PostConstruct, @PreDestroy

-> @Component로 설정된 bean클래스에 @PostConstruct, @PreDestroy 어노테이션이 설정되어 있는 메소드는 각각 객체가 생성되기 전에 호출되는 메소드, 객체가 소멸된 후에 호출되는 메소드로 지정된다.

@Bean을 사용할때는 initMethod="initmethod" 와 같이 빈을 만들때마다 생성을 해주어야 했지만 @Component에@PostConstructor, @PreDestroy을 설정하면 객체가 생성되기 전 후로 메소드를 계속 호출 가능하다.

 

6. @Component의 자동주입

@Component어노테이션을 사용하여 자동주입하는것은 @Bean 어노테이션을 이용하는 것과 동일하다..

예제를 보며 한개한개 살펴보자.

 

 

@Autowired

-> 타입을 통한 자동주입이다. 변수에 설정해주면 자동으로 타입에 맞는 빈을 찾아서 setter를 통한 주입을 해준다.

 

 

@Qualifier("빈 이름")

-> 이름을 통한 자동주입이다. @Autowired 와 함께 써준다. 

@Component("obj1") 어노테이션을 이용하여 obj1이라는 이름의 빈을 생성하였다고 한다면, @Qualifier("obj1") 을 사용해서 이름을 통한 자동주입을 해준다.

 

 

@Resource(name="빈 이름")

-> JSR-250 에서 제공하는 어노테이션으로 @Autowired @Qualifier("빈 이름") 과 같은 역할을 한다. 동작은 위와 동일하게 하겠다.

 

 

생성자를 통한 주입

-> @Component 어노테이션을 사용하여 빈을 등록한 comBean1과 comBean2가 있다고 하자.

TestBean1이라는 클래스의 생성자에서 저 두 타입의 빈을 주입한다고 하면, 

이런식으로 해주면 되겠다. 별다른 설정없이 타입을 기반으로 빈을 찾아서 생성자를 통해 주입을 해준다.

예전에 @Required라는 어노테이션을 설명한적이 있다. 이는 반드시 값을 주입해야하는 프로퍼티를 설정하는 어노테이션으로써, @Required를 setter에 붙이면 반드시 setter를 통해 값을 주입해야하는 역할을 하는 어노테이션이었다.

 

그런데 spring5.1 부터는 @Required를 사용하지 않는다. 

반드시 주입해야할 프로퍼티가 있다면 위의 예제와 같이 @Component로 빈을 등록하고(사실 @Autowired를 사용해도 상관은 없다.) 생성자를 통해서 값을 주입하는것을 더 권장한다.

int, String과 같은 기본형은 자동주입을 해줄수 없으므로 @Value 어노테이션을 이용하여 값을 지정할 수 있다.

'Spring > Annotation' 카테고리의 다른 글

@Transactional  (0) 2022.06.24
@EqualsAndHashCode  (0) 2022.06.03
@Configuration  (0) 2022.06.01
@RequestParam  (0) 2022.05.30
@Controller, @RestController 비교  (0) 2022.05.30
복사했습니다!