일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- DI
- 객체
- 스프링
- pom.xml
- Spring legacy Project
- 어노테이션
- 이클립스
- mysql
- 인터페이스
- Spring 개발환경 설정
- 의존성주입
- JVM
- spring
- 리액트
- 상속
- merge
- 영속성 컨텍스트
- github
- 깃허브
- 자동주입
- list
- @transactional
- java
- springboot
- 스프링 컨테이너
- @Bean
- 자바
- 빈
- react
- 트랜잭션
- Today
- Total
DEVLOG
스프링 설정 파일 분리 본문
applicationContext.xml에서 빈을 생성하다보면 한 파일에 많은 코드가 집약되어 가독성이 떨어질 수 있다. 이를 방지하기 위해 기능별로 스프링 설정 파일을 분리하고, 스프링 컨테이너 생성을 위해 배열원소로 받는다.
기존 applicationContext.xml 파일을 기능별로 나눠 세 개의 파일(appCtx1.xml / appCtx2.xml / appCtx3.xml)로 분리했다고 가정한다.
이 세 개의 파일을 배열원소로 받아 MainClassUseXMLs.java에서 스프링 컨테이너를 생성해보자.
appCtx1.xml
Dao 객체 생성하고, 이 객체를 매개변수로 받는 Service 객체의 생성자 및 객체 생성
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="studentDao" class="ems.member.dao.StudentDao" ></bean>
<bean id="registerService" class="ems.member.service.StudentRegisterService">
<constructor-arg ref="studentDao" ></constructor-arg>
</bean>
<bean id="modifyService" class="ems.member.service.StudentModifyService">
<constructor-arg ref="studentDao" ></constructor-arg>
</bean>
<bean id="deleteService" class="ems.member.service.StudentDeleteService">
<constructor-arg ref="studentDao" ></constructor-arg>
</bean>
<bean id="selectService" class="ems.member.service.StudentSelectService">
<constructor-arg ref="studentDao" ></constructor-arg>
</bean>
<bean id="allSelectService" class="ems.member.service.StudentAllSelectService">
<constructor-arg ref="studentDao" ></constructor-arg>
</bean>
</beans>
appCtx2.xml
사용자 정보
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataBaseConnectionInfoDev" class="ems.member.DataBaseConnectionInfo">
<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:xe" />
<property name="userId" value="scott" />
<property name="userPw" value="tiger" />
</bean>
<bean id="dataBaseConnectionInfoReal" class="ems.member.DataBaseConnectionInfo">
<property name="jdbcUrl" value="jdbc:oracle:thin:@192.168.0.1:1521:xe" />
<property name="userId" value="masterid" />
<property name="userPw" value="masterpw" />
</bean>
</beans>
appCtx3.xml
infomation
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="informationService" class="ems.member.service.EMSInformationService">
<property name="info">
<value>Education Management System program was developed in 2015.</value>
</property>
<property name="copyRight">
<value>COPYRIGHT(C) 2015 EMS CO., LTD. ALL RIGHT RESERVED. CONTACT MASTER FOR MORE INFORMATION.</value>
</property>
<property name="ver">
<value>The version is 1.0</value>
</property>
<property name="sYear">
<value>2015</value>
</property>
<property name="sMonth">
<value>1</value>
</property>
<property name="sDay">
<value>1</value>
</property>
<property name="eYear" value="2015" />
<property name="eMonth" value="2" />
<property name="eDay" value="28" />
<property name="developers">
<list>
<value>Cheney.</value>
<value>Eloy.</value>
<value>Jasper.</value>
<value>Dillon.</value>
<value>Kian.</value>
</list>
</property>
<property name="administrators">
<map>
<entry>
<key>
<value>Cheney</value>
</key>
<value>cheney@springPjt.org</value>
</entry>
<entry>
<key>
<value>Jasper</value>
</key>
<value>jasper@springPjt.org</value>
</entry>
</map>
</property>
<property name="dbInfos">
<map>
<entry>
<key>
<value>dev</value>
</key>
<ref bean="dataBaseConnectionInfoDev"/>
</entry>
<entry>
<key>
<value>real</value>
</key>
<ref bean="dataBaseConnectionInfoReal"/>
</entry>
</map>
</property>
</bean>
</beans>
MainClassUseXMLs.java
기능별로 분리된 위 appCtx.xml 파일들을 배열로 받아 컨테이너 생성
// 배열로 받기
String[] appCtxs = {"classpath:appCtx1.xml", "classpath:appCtx2.xml", "classpath:appCtx3.xml"};
GenericXmlApplicationContext ctx =
new GenericXmlApplicationContext(appCtxs);
빈(Bean)의 범위
싱글톤(Singleton)
스프링 컨테이너에서 생성된 빈 객체의 경우 동일한 타입에 대해서는 기본적으로 한 개만 생성이 되며, getBean() 메소드로 호출될 때 동일한 객체가 반환된다.
자바 객체 생성시(new ClassName()) 새로운 객체가 계속 생성되어 메모리 낭비가 심하다. 그러나 스프링은 컨테이너 생성시 객체를 호출해서(getBean) 사용하므로 메모리 효율성이 높다.
프로토타입(Prototype)
싱글톤 범위와 반대의 개념으로, getBean() 메소드로 객체를 참조할 때 새로운 객체를 계속 생성하며, 이를 프로토타입 범위라고 한다.
프로토타입의 경우 개발자는 별도로 설정을 해줘야 하는데, 스프링 설정 파일에서 빈(Bean) 객체를 정의할 때 scope 속성을 명시해주면 된다.
InjectionBean.java
package scope.ex;
public class InjectionBean {
}
DependencyBean.java
생성자와 setter메소드를 활용한 의존성 주입
package scope.ex;
public class DependencyBean {
private InjectionBean injectionBean;
public DependencyBean(InjectionBean injectionBean) { // 생성자
System.out.println("DependencyBean : constructor");
this.injectionBean = injectionBean;
}
public void setInjectionBean(InjectionBean injectionBean) { // 메소드
System.out.println("DependencyBean : setter");
this.injectionBean = injectionBean;
}
}
applicationContext.xml
scope 속성 없이 dependecyBean 객체 생성했으므로, MainClass.java에서 레퍼런스가 다른 두 개의 dependecyBean 객체 호출 시 동일한 메모리 주소의 객체를 가리키므로 한 번만 호출됨
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="injectionBean" class="scope.ex.InjectionBean" />
<bean id="dependencyBean" class="scope.ex.DependencyBean">
<constructor-arg ref="injectionBean" /> <!-- 생성자 생성시 참조객체 -->
<property name="injectionBean" ref="injectionBean" /> <!-- setter() 메소드 -->
</bean>
</beans>
MainClass.java
package scope.ex;
import org.springframework.context.support.GenericXmlApplicationContext;
public class MainClass {
public static void main(String[] args) {
GenericXmlApplicationContext ctx =
new GenericXmlApplicationContext("classpath:applicationContext.xml");
InjectionBean injectionBean =
ctx.getBean("injectionBean", InjectionBean.class);
DependencyBean dependencyBean01 =
ctx.getBean("dependencyBean", DependencyBean.class);
DependencyBean dependencyBean02 =
ctx.getBean("dependencyBean", DependencyBean.class);
if(dependencyBean01.equals(dependencyBean02)) {
System.out.println("dependencyBean01 == dependencyBean02"); // 하나의 객체만 생성되어 한 번만 호출됨
} else {
System.out.println("dependencyBean01 != dependencyBean02");
}
ctx.close();
}
}
아래 실행결과를 보면 동일한 객체를 가리키므로 한 번만 호출되었음을 알 수 있다.
그러나 아래 코드처럼 applicationContext.xml 파일에서 빈 객체에 scope="prototype" 속성을 준다면
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="injectionBean" class="scope.ex.InjectionBean" />
<!-- scope="prototype" 속성을 주면 객체 두 개 생성되고, MainClass에서는 두 번 호출됨 -->
<bean id="dependencyBean" class="scope.ex.DependencyBean" scope="prototype">
<constructor-arg ref="injectionBean" /> <!-- 생성자 생성시 참조객체 -->
<property name="injectionBean" ref="injectionBean" />
</bean>
</beans>
아래 실행결과처럼 프로토타입에 의해 getBean() 메소드로 호출할 때마다 새로운 객체가 생성되어 두 번 호출되고, 이 두 객체는 가리키는 주소값이 서로 다름을 알 수 있다.
출처
자바 스프링 프레임워크(renew ver.) - 신입 프로그래머를 위한 강좌 - 인프런 | 강의
스프링 프레임워크 기본부터 실전 사용법까지! 충실하고 폭넓은 설명과 예제를 통해 현장에 바로 투입되어 활약하는 개발자로 거듭나세요., - 강의 소개 | 인프런...
www.inflearn.com
'Spring' 카테고리의 다른 글
의존객체 선택 (0) | 2022.06.07 |
---|---|
의존객체 자동 주입 (0) | 2022.06.07 |
다양한 의존 객체 주입 방법 (0) | 2022.06.06 |
DI(Dependency Injection) : 의존성 주입 (0) | 2022.06.04 |
스프링 프로젝트 생성(2) - 작업 폴더를 생성하여 프로젝트 import하기 (0) | 2022.06.04 |