[DI] xml 방식 / Componenet - Scan 방식
[ xml 방식 ]
- Spring-Bean configuratioin.xml
1. Bean 등록
- 해당 패키지에 Spring Bean Configuration.xml 생성 ( new - other )
<bean id="객체이름" class="패키지.클래스">
<property name="변수명" value="값" />
<property name="변수명" ref="객체" />
</bean>
<bean id="dto1" class="member.MemberDTO" >
<property name="id" value="spring"/>
<property name="pw" value="1111"/>
<property name="name" value="backcoder"/>
</bean>
==
MemberDTO dto1 = new MemberDTO( );
dto1.setId = "spring";
dto1.setPw = 1111;
dto1.setName = "backcoder";
- <bean id class ></bean> : 기본생성자 필요
- <property > : setter 필요
- < constructor-args >set 할 개수에 맞춘 생성자 필요
( new 로 객체 생성할때와 마찬가지 규칙 )
2. Bean 가져다 쓰기
ApplicationContext fac = new ClassPathXmlApplicationContext( "패키지 / 파일명.xml" );
: xml 파일 가져와.
Member m1 = (Member) fac.getBean( "빈객체 id" )
: 거기있는 bean 쓸거야 ( 형변환 필요 )
[ DI 종류 ]
(1) 기본생성자
<bean id=" " class=" " > </bean>
(2) Setter Injection
: poperty 를 setter 메소드로 받기 => 해당 클래스 setter 필요
< bean id=" " class=" " >
< property name=" " value/ref =" " />
</bean>
(3) Constructor Injection
: constructor-args 를 생성자로 받기 => 맞춤형 생성자 필요
< bean id=" " class=" " >
< constructor-arg name=" " value/ref =" " />
</bean>
[ scope : singletone ]
<bean id="dto1" class="member.MemberDTO" scope="singleton"> </bean>
: Bean Conatainer 에서 가져다 쓰는 객체는 기본적으로 Singletone 스코프를 가진다. ( default )
singletone => 유일한 객체.
MemberDTO dto1 = (MemberDTO)fac.getBean("dto1");
MemberDTO dto4 = (MemberDTO)fac.getBean("dto1");
=> dto4 에서 다시 bean 가져다 만들려 해도 무시함
처음 만든 dto1 객체로만 공유
- dto1 객체 == dto4 객체
- 주소값 까지 같음 완벽한 같은 객체.
=> 싱글톤 : 처음만든 객체 dto1을 유일한 객체로 공유하여 사용한다.
[ scope = "prototype" ]
=> 객체 생성하면 매번 새롭게 객체 생성
즉, 위의경우 dto4 와 dto1 는 다른 객체
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
[ Componenet - Scan 방식 ]
: Spring-Bean Configuration.xml 파일에 가서 <bean ~ > 으로 등록하는게 아니라
해당 클래스에서 @어노테이션을 붙임으로서, 바로 Bean Container 에 집어넣는 편한 방식.
( Spring-Bean Configuration.xml 혹은 servlet-conext.xml 에 <component-scan 태그 필요 > )
<context:component-scan base-package="com.gourpid.api이름"/>
1. Bean 등록
<bean id="dto1" class="member.MemberDTO" > </bean>
==
@Component ( "dto1" )
public class MemberDTO { ~ }
- @어노테이션 으로 Bean 등록하는건 기본생성자 객체만 가능
=> 객체에 property 넣은 상태로 bean 등록하려면 xml bean 태그 / configuration 클래스 사용
2. Bean 가져다 쓰기
: @Autowired
클래스 객체이름;
ApplicationContext fac = new ClassPathXmlApplicationContext( "패키지 / 파일명.xml" );
MemberDTO dto1 = (MemberDTO) fac.getBean( "dto" )
==
@Component
public class MemberDAO {
@Autowired
MemberDTO dto1; }
=> Bean Container 에 등록된 "해당객체" 를
자동으로 가져와서 객체 생성 해준다.
-----------------------------------------------------
( Bean Container 에 등록된 dto1 객체 )
@Component("dto1")
public class MemberDTO { ~ }
-----------------------------------------------------
[ Bean id ]
@Component ( " Bean id " )
- 안줘도 된다.
=> 자동으으로 클래스 이름 첫글자 소문자로 가져와서
그걸 Bean id 로 사용
@Component
public class MemberDTO { ~ }
=> Bean 등록될 때, 객체 이름은 memberDTO 으로 등록된다. (자동)
즉, 이렇게 등록된 Bean 을 다른 곳에서 가져다 쓴다면
@Component
public class MemberDAO{
@AutoWired
MemberDTO memberDTO;
}
이렇게 가져다 쓰면 된다.
[ @Qualifier( " " ) ]
- 하나의 클래스에 대해 Bean 에 여러개의 객체가 생성되어 있다면,
MemberDTO 클래스를
즉, xml 에서 <bean id ="dto1" class="Mem.MemberDTO >
<bean id ="dto2" class="Mem.MemberDTO > ~.... < /bean >
객체 id 두 개
@Component
public class MemberDTO{ ~ }
어노테이션으로 생성된 id 한개 추가
이런 식으로 여러개의 Bean id 가 존재한다면
@AutoWired
MemberDTO dto999;
이렇게 Bean을 가져올 경우, 어떤 객체를 의미하는지 알 수 없다.
( 저 dto999 는 가져오면서 새로 준 이름일 뿐이다. )
=> @Qualifier ( " Bean id " ) 사용할 Bean id 를 명시적으로 알려준다.
@Qualifier( " dto2 " )
@AutoWired
MemberDTO dto999;
: Bean Container 에 dto2 라는 Bean id 로 등록된 객체를 가져와서 AutoWired 하겠다.
[ @Component 종류 ]
: 비지니스 계층에 따라서 구분 해서 붙여주자.
( 역할은 똑같음. 구분하기 위한 닉네임 )
@Component
- 기본
- 애매한 역할 ( DTO등 )
@Service
- 서비스 계층
@Repository
- DAO 계층
[ xml VS @Component ]
- Component -scan 방식은 편하다.
- Component 로 Bean 등록하는건 기본생성자 객체만 가능하다.
=> 객체에 property 넣은 상태로 bean 등록하려면 xml bean 태그 / configuration 클래스 사용
- xml 방식은 객체나 dependency 관계를 한 파일에 몰아두고 볼 수 있다는 장점.
( Component 방식은 클래스들을 돌아다니며 찾긴 해야 한다. )
=> 둘다 적절히 사용할 줄 알아야 겠다.