Spring Bean 등록 방법
Spring Bean을 설정하는 방법에는 크게 XML 설정을 통한 방법과 Java 설정을 통한 방법이 있습니다. 그리고 각 설정 방법마다 Bean을 직접 등록하는 방법과 컴포넌트 스캔을 활용하여 등록하는 방법이 있습니다. 각 방법에 따라 다음 정보를 Bean으로 등록하는 예시를 통해 설정 방법을 알아보겠습니다.
MyService 객체가 MyRepository 의존성을 갖고 있다.
다음과 같이 MyService와 MyRepository 클래스를 정의합니다.
public class MyService {
private final MyRepository myRepository;
public MyService(MyRepository myRepository) {
this.myRepository = myRepository;
}
}
public class MyRepository {
}
XML bean 설정을 통한 방법
Spring Bean을 XML 설정을 통해 등록할 때는 <beans> 엘리먼트 아래에 등록을 원하는 Bean 정보를 입력합니다.
<beans> 엘리먼트 아래에 <bean> 엘리먼트 추가를 통해 Bean으로 등록할 수 있습니다.
(component-scan을 사용하지 않으면, 빈으로 설정할 클래스들을 아래와 같이 우리가 직접 xml 파일에 일일이 등록해 주어야 한다. 위와 같이 코드가 매우 길어지고, 일일이 추가하기에 복잡해진다.)
<?xml version="1.0" encoding="UTF-8" ?>
<beans ...>
<bean id="MyService"
class="com.example.my.MyService">
<property name="myRepository"
ref="myRepository"/>
</bean>
<bean id="MyRepository"
class="com.example.my.MyRepository">
</bean>
</beans>
각 엘리먼트에 등록할 수 있는 정보는 다음과 같습니다.
- <bean> 엘리먼트 : 등록할 Bean 정보를 명시합니다.
- <bean>의 id 속성 : Bean의 이름을 대문자로 시작하는 카멜케이스로 명시합니다.
- <bean>의 class 속성 : Bean 등록을 원하는 클래스의 위치를 명시합니다.
- <property> 엘리먼트 : Bean에 의존성 주입에 대한 정보를 명시합니다.
- <property>의 name 속성 : 클래스에 정의한 의존성 주입 받을 변수명을 명시합니다.
- <property>의 ref 속성 : 의존성 주입 받을 Bean의 이름을 소문자로 시작하는 카멜케이스로 명시합니다.
XML에 component-scan 을 통한 빈 등록
이번에는 컴포넌트 스캔을 통한 Bean 정보를 등록하는 방법입니다.
<context:component-scan> 엘리먼트를 등록하여 컴포넌트 스캔을 통한 Bean 등록을 할 것이라고 알려줍니다.
빈으로 등록 될 준비를 마친 클래스들을 스캔하여, 빈으로 등록해주는 것이다.
빈으로 등록 될 준비를 하는 것이 무엇일까?
우리가 @Controller, @Service, @Component, @Repository 어노테이션을 붙인
클래스들이 빈으로 등록 될 준비를 한 것이다.
component-scan은 기본적으로 @Component 어노테이션을
빈 등록 대상으로 포함한다.
그렇다면 @Controller 나 @Service는 어떻게 인식하는 걸까?
그 이유는 @Controller나 @Service가 @Component를 포함하고 있기 때문이다.
<?xml version="1.0" encoding="UTF-8" ?>
<beans ...>
<context:component-scan base-package="com.example.my" />
</beans>
그리고 base-package 속성에 컴포넌트 스캔을 진행할 대상 루트 패키지를 작성합니다. 그러면 해당 패키지를 포함한 모든 하위 패키지의 Bean 설정을 스캔하여 등록하게 됩니다.
아래와 같이 base package에 여러개의 패키지를 쓸 수 있다.
<context:component-scan base-package="com.rcod.lifelog, com.rcod.example"/>
위와 같이 설정하면, base pacakage 하위의 @Controller, @Service
@Repository, @Component 클래스가 모두 빈으로 등록되므로,
특정한 객체만 빈으로 등록하여 사용하고 싶다면 include-filter나 exclude-filter를 통해 설정할 수 있다.
@Controller 를 제외하고 싶다면 위와 같이 exclude-filter를 사용하여
org.springframework.stereotype.Controller를 명시해준다.
<context:component-scan base-package="com.rcod.lifelog">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
use-default="false"는 기본 어노테이션 @Controller, @Component등을
스캔하지 않는다는 것이다.
기본 어노테이션을 스캔하지 않는다고 설정하고, include-filter를 통해서
위와 같이 특정 어노테이션만 스캔할 수 있다.
context:component-scan base-package="com.rcod.lifelog" use-default="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
component-scan 동작 과정
1.ConfigurationClassParser 가 Configuration 클래스를 파싱한다.
@Configuration 어노테이션 클래스를 파싱하는 것이다.
2.ComponentScan 설정을 파싱한다.
base-package 에 설정한 패키지를 기준으로
ComponentScanAnnotationParser가 스캔하기 위한 설정을 파싱한다.
3.base-package 설정을 바탕으로 모든 클래스를 로딩한다.
4.ClassLoader가 로딩한 클래스들을 BeanDefinition으로 정의한다.
생성할 빈의 대한 정의를 하는 것이다.
5.생성할 빈에 대한 정의를 토대로 빈을 생성한다.
Java 설정을 통한 방법
이번에는 Spring Bean을 Java 설정을 통해 등록하는 방법에 대해 알아보겠습니다. Java로 설정하게 되면 여러 어노테이션(Annotation)이 사용되게 됩니다. Java 설정을 통해 Bean을 직접 등록하는 방법과 컴포넌트 스캔을 통한 등록 방법에 대해 알아보며, 사용되는 어노테이션에 대해 설명하겠습니다.
@Configuration
@Configuration 은 이 클래스가 xml을 대체하는 설정 파일임을 알려준다.
스프링이 뜰 때에 스프링은 자동으로 @Configuration이 붙은 클래스를 찾아서 구성 정보로 사용한다.
이 클래스에서 Bean을 등록하고 의존관계주입을 처리할 수 있다.
빈을 스프링 컨테이너에 등록하는 방법에는 두 가지가 있다.
@Bean을 통해 직접 등록하는 방법과 @ComponentScan을 이용하여 자동으로 빈 등록하는 방법이 있다.
@Bean을 통한 빈등록
Java에 등록하고 싶은 Bean 정보를 직접 등록하는 방법입니다. Class를 생성한 후 @Configuration 어노테이션을 설정하고 메소드에 @Bean 어노테이션을 달아서 Bean을 등록할 수 있습니다.
@Configuration
public class ApplicationConfig {
@Bean
public MyService myService(MyRepository myRepository) {
return new MyService(myRepository);
}
@Bean
public MyRepository myRepository() {
return new MyRepository
}
}
각 어노테이션의 정보는 다음과 같습니다.
- @Configuration 어노테이션 : 해당 클래스가 Java 설정에 사용되는 클래스라는 것을 의미하며, 클래스명은 자유롭게 지정 가능합니다.
- @Bean 어노테이션 : 해당 메소드가 Bean을 등록하는 메소드라는 것을 의미하며, 메소드명을 바탕으로 Bean의 이름이 지정됩니다. 또한, 메소드의 파라미터는 Bean에 등록된 객체가 있다면 자동으로 전달됩니다.
@ComponentScan을 통한 빈 등록
이번에는 컴포넌트 스캔을 통한 Bean 정보를 등록하는 방법입니다. 이전과 같이 @Configuration 어노테이션을 설정하고 @ComponentScan 어노테이션을 추가하면 됩니다.
@Configuration
@ComponentScan(basePackages = "com.example.my")
public class ApplicationConfig {
}
@ComponentScan의 속성으로 basePackages와 basePackageClasses가 있습니다.
- basePackages는 XML 설정에서 base-package와 동일하게 컴포넌트 스캔을 진행할 대상 루트 패키지를 설정하면 됩니다.
- basePackageClasses는 basePackage의 타입 세이프(Type Safe) 하지 않은 점을 개선한 것으로, 설정된 클래스의 패키지부터 모든 하위 패키지에 대해 컴포넌트 스캔을 진행하게 됩니다.그래서 다음과 같이 basePackageClasses 속성으로 타입 세이프 하게 등록할 수 있습니다.
@Configuration
@ComponentScan(basePackageClasses = ApplicationConfig.class)
public class ApplicationConfig {
}
출처 : https://luckydavekim.github.io/development/back-end/spring-framework/create-spring-bean/
'STUDY > SpringLegacy' 카테고리의 다른 글
[Spring] Spring에서 클라이언트로부터 파라미터를 받는 방법과 Content-Type 설정 (0) | 2024.07.30 |
---|---|
[Spring] @Autowired null 문제 해결 (필드 주입 사용 시) (0) | 2024.06.10 |
[Spring] @Resource, @Autowired, @Inject 차이 (0) | 2024.05.21 |
[Spring] [JS] SSE (Server-Sent Events) 사용하기 (0) | 2024.05.21 |
[Spring] Log4j2 설명 (0) | 2024.04.29 |