@Component 어노테이션을 이용하면 Bean Configuration 파일에 Bean을 따로 등록하지 않아도 사용할 수 있다.
빈 등록자체를 빈 클래스 자체에다가 할 수 있다는 의미이다.
@Component 어노테이션은 기본적으로 타입기반의 자동주입 어노테이션이다.
@Autowired, @Resource와 비슷한 기능을 수행한다고 할 수 있겠다.
@Component 어노테이션을 xml 설정파일에서 설정하는 방법이다.
1. Xml 설정파일에서 @Component 어노테이션 설정하기
xml파일에 <context:component-scan base-package="패키지경로" /> 태그를 설정해주면, 지정된 패키지 안에 있는 bean클래스의 어노테이션을 분석할 수 있도록 지정해주는 것이다.
설정한 패키지 경로 안에 bean클래스를 만들고 @Component 어노테이션을 붙여주면 해당 bean클래스는 자동으로 빈이 생성될 수 있게 된다.
아이디를 사용하지 않고 타입으로 빈을 지정해서 찾는거랑 비슷한 느낌이다... 이름이 없기 때문에 타입으로서 빈을 받아낼 수 있다.
이렇게 패키지를 등록해주고 패키지 아래에 comBean1 이라는 클래스를 만들어서 @Component 어노테이션을 붙여주었다.
그 후 실행해보면, 별다른 빈을 등록하지 않아도 comBean1클래스가 빈에 등록되어 있다는것을 확인할 수 있다.
2. java configuration 파일에서 @Component 설정하기
xml에서 설정한 것을 당연히 자바 configuration 파일에서도 할 수 있다.
@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 어노테이션을 이용하여 값을 지정할 수 있다.
'JAVA > Spring' 카테고리의 다른 글
execution 명시자 (0) | 2020.04.17 |
---|---|
AOP (0) | 2020.04.17 |
JSR-250 어노테이션 (0) | 2020.04.11 |
Annotation을 이용한 빈 설정 (0) | 2020.04.11 |
Java를 이용한 Bean 객체 주입 (0) | 2020.04.10 |