본문 바로가기
dev/Spring

[Spring] Di 따라하기 4

by dev_Step 2022. 6. 22.

 

지금 까지 객체를 생성하여 Map에 넣는 작업을 여러 가지 방법으로 진행했었는데

1. Properties File를 통해서 

2. @Component 어노테이션을 통해서

 

추가적으로 xml 파일을 통해서 도 객체를 생성할수 있다. 이제부터 이렇게 생성하는 객체를 Bean이라고 칭하도록 하겠다.

 

>>config.xml 에

<bean > </bean> 을 통해서 객체를 생성할 수 있다.

이때 id는      Map의 key 값에 해당되고

       class는  Map의 Value값에 해당이 된다.

추가적으로 <property> 라는 태그는  해당 Bean이 가지는 속성으로 매개변수라고 생각하면된다. 

    해당 Bean이 속성을 갖는데 이 속성이 일반 변수면 value값을

                                                                  참조 변수면 ref 를 써준다. 

또한 추가 적으로 Scope는 객체의 범위를 말하는 것으로 Singleton 으로 지정하면 Servlet 처럼 1개의 객체를 생성한 후 

이 후에 해당 객체를 호출하는 식으로 1개를 계속 쓰는 형식이고, Prototype 의 경우는 새로운 객체를 계속 생성하는 방식이다.

 

>> 추가 적으로 Property 태그는 해당 Car 클래스에 해당하는 속성들 color, oil, engine, doors 의 setter 가 있어야 사용이 가능 하다.

 


config.xml File
Bean을 초기화
<bean id="car" class="com.fastcampus.ch3.Car">
        <property name="color" value="red" />
        <property name="oil" value="100" />
        <property name="engine" ref="engine" /> &lt;!&ndash;참조변수라서 ref&ndash;&gt;
        <property name="doors"> &lt;!&ndash; 배열 타입일경우 &ndash;&gt;
            <array value-type="com.fastcampus.ch3.Door">
                <ref bean="door"/>
                <ref bean="door"/>
            </array>
        </property>
</bean>

생성자로 초기화
>> 생성자로 초기화 하려면 해당 생성자가 존재해야함
>> public Car(String color, int oil, Engine engine, Door[] doors){this.color = color; this.oil=oil; this.engine=engine; this.doors=doors;}
<bean id="car" class="com.fastcampus.ch3.Car">
      <constructor-arg name="color" value="red" />
      <constructor-arg name="oil" value="100" />
      <constructor-argname="engine" ref="engine" /> &lt;!&ndash;참조변수라서 ref&ndash;&gt;
      <constructor-argname="doors"> &lt;!&ndash; 배열 타입일경우 &ndash;&gt;
            <array value-type="com.fastcampus.ch3.Door">
                <ref bean="door"/>
                <ref bean="door"/>
            </array>
       </constructor-arg>
</bean>
<bean id="door" class="com.fastcampus.ch3.Door" scope="prototype" />
<bean id="engine" class="com.fastcampus.ch3.Engine" />-->



기본형=value일때 참조형일때=ref

<List>-기본형
<property name="colors">
	<list>
    	<value>red</value>
        <value>yellow</value>
        <value>blue</value>
    </list>
</properties>


<List>-참조형
<property name="engines">
	<list>
    	<ref bean="superEngine"/>
        <ref bean="turboEngine"/> 
    </list>
</properties>

<Set>
<property name="engines">
	<set>
    	<ref bean="superEngine"/>
        <ref bean="turboEngine"/> 
    </set>
</properties>



<Map> - 기본형
<property name="doors">
	<map>
    	<entry key="left" value-ref="door">
        <entry key="right" value-ref="door">
    </set>
</properties>



<Map> - 참조형
<property name="doorsColor">
	<map>
    	<entry key="left" value="red">
        <entry key="right" value="blue">
    </set>
</properties>

>> 아래와 같다.

 

또 다른 방식으로는 Component-Scan을 활용하는 방법이다.

>>> base-package에 해당 @Component어노테이션이 있는 클래스를 탐지할 범위를 지정해주고 

해당 범위에 @Component 어노테이션이 붙어있는 클래스를 Bean으로 등록해준다. 

1,2 모두 동일한 id로 Bean으로 등록이 되며
("") 은생략이 가능 하며  생략됬을 경우 클래스의 첫글짜를 소문자로
superEngine 지정하여 저장한다. == ("superEngine")

<bean id="superEngine" class="~~~"> == 동일 
1.
@Component
class SuperEngine extends Engine{]

2.
@Component("superEngine")
class SuperEngine extends Engine{]

>> 추가 적으로 @Controller , @Service, @Repository @ControllerAdvice의 메타에너테이션도 Component-Scan에
의하여 Bean으로 등록이 되어진다

.

 

>> 이때 만약 Bean등록이 중복되는경우 <context:exclude-filter type="" expression=""> 을통해서 특정한 범위를

Bean으로 등록하는 것을 제외 시킬수 있다.

 

이 Component-Scan의 경우는 

<context:annotation-config/> 어노테이션이 있어야 사용할 수 있다.

<context:component-scan base-package="com.fastcampus.ch3">
    <!-- 빈생성을 제외한다.-->
    <context:exclude-filter type="regex" expression="com.fastcampus.ch3.diCopy*.*"/>
</context:component-scan>

<!-- Autowired 사용하려면 아래의 태그가 있어야함-->
<context:annotation-config/>

 

 

=========================================================================================

>> 여태까지 실습했던 DiTest는 ApplicationContext의 기능을 만들어 본것이 였고,

실제로는 ApplicationContext를 통해서 Bean 객체에 접근 및 사용할 수 있다.

>> getBean을 통해서 By name Or By Type 으로 Bean 객체를 생성하는 것을 볼수 있다. 

 

>> 또한 Car Class를 보면 

@Value 와 @Autowire @Resource @Qualifier 를 확인할 수 있는데.

>> @Value의 경우는 해당 객체에 일반 변수에 값을 주입할때 사용하는 것이다.

(참조변수의 경우 Autowired, Resouce등을 사용하지만 일반변수는 사용하지 못하므로 @Value를 통해서 값주입)

@Value 애너테이션 같은경우는
systemProperties, systemEnviroment를 사용할 수 있다.

systemProperties의 경우는
Properties prop = System.getProperties();
System.out.println("System.getProperties() = " + prop )

systemEnviroment는 // 환경변수들이 map에 저장된다.
Map<String, String> env = System.getenv();
System.out.println("System.getenv() = " + env);

@Value("#{systemProperties['user.timezone']}")
@Value("#{systemEnviroment['pwd']}")


@PropertySource("~~~.properties")의경우는
파일로부터 값들을 가지고 올수 있다.

@Value("${autosaveDir}")  ==>  autosave
@Value("${autosave}")     ==>  true 
@Value("${autosaveInterval}") ==> 30


src/main/resource/setting.properties
autosaveDir=autosave
autosave=true
autosaveInterval=30

 

@Autowire의 경우는 By type으로 객체를 주입해준다. 만약에 같은 Type의 객체가 여러개 있을경우 차선책으로

동일한 By Name 값으로 매칭시켜준다. ( By type -> 중복된게 있다면 -> By name (일치하는것))  만약에 이름도 일치 하지 않을경우 에러 발생한다.

>> 단 @Autowired  Engine[] engine  DI하는 변수가 배열일 경우에는 type이 n개 여도 상관이 없지만 

           @Autowired Engine engine    DI하는 변수가 그냥 단순 참조변수일경우 n개 이면 안된다 1개이여야 한다.

    하지만 옵션으로 @Autowired(required=false) 일경우 DI 되어질 Bean을 찾지 못해도 에러가 발생하지 않는다.

 

 

@Qualifier("name") 의 경우 Autowired에서 이름이 일치하는게 없을경우@Qualifier의 ("name") 으로 지정되있는 이름의 Bean을 주입해준다.

 

주로 

>> 아래와 같은 형식으로 사용한다.

@Autowired

@Qualifier("name") 

Engine engine

 

 

@Resource의 경우는 By name 으로 Bean의 name을 가지고 주입해준다 

 

 

 

 

======================================================================================

 

스프링 애너테이션(Spring) // 표준 애너테이션(JAVA)

스프링 애너테이션 표준 애너테이션 비교
@Autowired @Inject @Inject에는 required 속성이 없다
@Qualifier @Qualifier, @Named 스프링의 @Qualifier는 @Named와 유사
- @Resource 스프링에는 이름 검색이 없음
@Scope("singleton") @Singleton 표준에서는 prototype이 Default
@Component @Named(""), @ManagedBean("") 표준에서는 반드시 이름이 있어야함

 

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

[Spring] AOP-2  (0) 2022.07.12
[Spring] Transaction, Commit, Rollback  (0) 2022.07.06
[Spring] Di 따라하기 3  (0) 2022.06.22
[Spring] Di 따라하기 2  (0) 2022.06.22
[Spring] Di 따라하기 1  (0) 2022.06.22