1. Bean 설정 방법
방법 | 설명 |
XML 기반 설정 방식 | XML 파일을 사용하는 방법 <bean> 요소의 class 속성에 FQCN(Fully-Qualified Class Name)을 기술하면 빈이 정의됨 <bean id="" class="">으로 bean 생성 <constructor-arg> 또는 <property> 요소를 사용해 의존성주입(DI) |
Annotation 기반 설정 방식 | @Component 계열 Annotation이 명시된 클래스를 탐색(Component Scan)해서 IoC Container에 Bean을 자동으로 등록하는 방법 |
Java 기반 설정 방식 | @Configuration을 Java Class에 명시하여 설정하고 @Bean을 사용해 bean을 정의하는 방법 |
(XML + Annotation 방식 또는 Java class + Annotation 방식 의 조합으로 주로 설정한다)
1-1 Java 기반 Bean 설정 방법
- Java 기반 설정 방식에서는 자바코드로 Bean을 설정 - 이때 사용되는 Java class 를 Java Configuration이라고 함
@Configuration // (1)
public class SpringConfig {
@Bean // (2)
public MemberService memberService(){
return new MemberServiceImpl(); // (3)
}
//<Bean id=memberService>으로 빈이 등록이 되었다
//이렇게 Bean을 config.class에 등록을 해주고
//해당 빈의 클래스에 가서 @Component("bean 이름") 을 해주면 bean이 연결이 된다
}
// 클래스 명 위에 @Component를 붙여준다
// @Componenet("bean 이름") 과 같이 빈 이름(id)를 지정할 수 있다
// 이는 xml 방식의 <Bean id="bean 이름" class="파일위치">와 동일한 표현이다
@Component("memberService")
public class MemberServiceImpl implements MemberService{
}
AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext(SpringConfig.class);
MemberService memberService = context.getBean(MemeberService.class);
① 클래스에 @Configuration 을 붙여 설정 클래스를 선언
- @Configuration 은 1개 이상 Bean을 등록하고 있음을 명시하는 어노테이션
② 메서드에 @Bean 을 붙여 빈을 정의
- 메서드명이 Bean의 이름이 되고 그 Bean의 인스턴스가 반환값이 됨
- 개발자가 직접 제어가 불가능한 외부 라이브러리 또는 설정을 위한 클래스를 Bean으로 등록할 때
@Bean 어노테이션을 활용한다
③ 다른 컴포넌트를 참조해야 할 떄는 해당 컴포넌트의 메서드를 호출
- 메서드에 매개변수를 추가하는 방법으로 다른 컴포넌트의 의존성을 주입 할 수 있음
(인수로 전달될 인스턴스에 대한 Bean은 별도로 정의 되어 있어야 한다)
- DI가 프로그램적인 방법으로 처리됨
@Bean 어노테이션의 경우 주로 아래와 같은 상황에서 주로 사용
1. 개발자가 직접 제어가 불가능한 라이브러리를 사용할 때
2. 초기에 설정을 하기 위해 활용할 때
@Configuration 없이 @Bean 만 사용해도 스프링 빈으로 등록이 된다
대신 메서드 호출을 통해 객체를 생성할 때 싱글톤을 보장하지 못한다
그렇기 때문에 Spring 설정 정보를 위해서는 반드시 @Configuration 을 사용해주어야 한다
빈의 설정을 담당하는 @Configuration 어노테이션도 내부적으로 @Component를 가지고 있어
@Configuration 이 붙은 클래스도 Spring 의 빈으로 등록이 된다
1-2 XML 기반 Bean 설정 방법
- XML 기반 설정 방식은 XML 파일을 이용해 Bean을 설정
1-2-1 생성자(constructor) 기반 의존성 주입 방식
<beans>
<bean id="boardDAO" class="org.waterpunch.model.BoardDAOImpl"></bean>
<bean id="boardService" class="org.waterpunch.model.BoardServiceImpl">
<constructor-arg ref="boardDAO"/>
</bean>
<beans>
public class BoardServiceImpl implements BoardService {
private BoardDAO boardDAO;
public BoardServiceImpl(BoardDAO boardDAO) {
this.boardDAO=boardDAO;
}
}
1-2-2 설정자(setter) 기반 의존성 주입 방식
<beans>
<bean id="boardDAO" class="org.waterpunch.model.BoardDAOImpl"></bean>
<bean id="boardService" class="org.waterpunch.model.BoardServiceImpl">
<property name="boardDAO" ref="boardDAO"/>
</bean>
</beans>
public class BoardServiceImpl implements BoardService {
private BoardDAO boardDAO;
@Override
public void setBoardDAO(BoardDAO boardDAO) {
this.boardDAO=boardDAO;
}
}
(생성자 기반 의존성 주입방식은 xml에서 constructor-arg 이용)
(setter 기반 의존성 주입방식은 xml에서 property 이용)
1-3 Annotation기반 Bean 설정 방법
- Annotation 기반의 설정 방식에서는 IoC 컨테이너에 관리할 Bean을 Bean 설정 파일에 정의하는 대신 Bean을 정의하는 Annotation을 Bean의 클래스에 부여하는 방식을 사용
- 컴포넌트 스캔(Component Scan) : Annotation이 붙은 클래스를 탐색해서 IoC 컨테이너에 자동으로 등록함
(밑에 추가 내용 있음)
- 오토와이어링(Auto Wiring) : 명시적으로 Bean을 정의하지 않고도 Annotation이 붙어 있으면
IoC 컨테이너가 자동으로 Bean을 주입하는 방식
//config.xml
//org.waterpunch 에 있는 component를 스캔한다
<context:component-scan base-package="org.waterpunch"/>
package org.waterpunch.model;
@Service
public class BankServiceImpl implements BankService {
@Autowired
private BankDAO BankDAO;
}
2. 컴포넌트 스캔 (Component Scan)
- 지정한 특정 패키지 하위의 클래스를 탐핵한 후 IoC 컨테이너에 객체 생성 후 등록함
방식 | 예시 |
XML 방식 | <context:componenet-scan base-package="com.example.demo"/> |
Annotation 방식 | @ComponentScan(basePackages="com.example.demo") |
2-1 컴포넌트 스캔 대상 주요 Annotation
Annotation | 설명 |
@Controller | MVC의 Controller 역할을 하는 클래스에 명시하는 Annotation |
@Service | 비즈니스 로직을 처리하는 클래스에 명시하는 Annotation 트랜잭션 처리는 @Service 명시 클래스에서 하도록 한다 |
@Repository | 영속적 데이터 처리를 위한 클래스에 명시하는 Annotation |
@Component | 모든 컴포넌트에 대한 제네릭 스테레오 타입 위 세가지 경우에 해당하지 안흔 기타 지원 클래스에 사용 |
2-2 DI 관련 주요 Annotation
Annotation | 설명 |
@Autowired | 의존 대상 객체를 타입으로 검색해 주입 만약 동일한 타입의 객체가 여러개일 경우 NoUniqueBeanException 발생 추가적으로 @Qualifier("bean name")이 필요 |
@Resource | @Resource : 의존 대상 객체를 타입으로 검색해 주입 @Resource(name="bean name") : 의존 대상 객체를 이름으로 검색해 주입 |
@Autowired를 해주었는데 만약 동일한 타입을 가진 bean 객체가 두 개 있다면?
- 스프링이 어떤 빈을 주입해야 할지 알 수 없어서 스프링 컨테이너를 초기화하는 과정에서 Exception을 발생
>> 주입은 하나를 해야하는데 실제로는 두 개 이상의 빈이 존재해 주입할 때 사용할 객체를 선택할 수 없음
>> 단, @Autowired가 적용된 필드나 설정 메서드의 property 이름과 같은 이름을 가진 빈 객체가 존재할 경우
이름이 같은 빈 객체를 주입받는다
이것을 해결하기 위해 @Qualifier 어노테이션을 사용
@Qualifier 어노테이션
- 사용할 의존 객체를 선택할 수 있도록 해준다
1. 설정에서 bean의 한정자 값을 설정한다
2. @Autowired 어노테이션이 적용된 주입 대상에 @Qualifier 어노테이션을 설정한다
(이 때 @Qulifier 의 값으로 앞어 설정한 한정자를 사용한다
'Java > Spring' 카테고리의 다른 글
[Spring] 스프링 AOP Pointcut 표현식 (0) | 2021.08.18 |
---|---|
[Spring/MyBatis] MyBatis? (0) | 2021.05.28 |
[Spring] 스프링 AOP(관점지향 프로그래밍, Aspect-Oriented-Programming) (1) | 2021.05.24 |
[Spring] Maven? (0) | 2021.05.23 |
[Spring] IoC (제어 역전, Inversion Of Control) / DI (의존성 주입, Dependency Injection) (0) | 2021.05.20 |
댓글