스프링 설정 파일
src/main/resources > applicationContext.xml 파일을 생성한다.
applicationContext.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- InitSampleData 빈 -->
<bean id="initSampleData"
class="ch04_pjt_01.ems.utils.InitSampleData">
<property name="sNums">
<array>
<value>hbs001</value>
<value>hbs002</value>
<value>hbs003</value>
<value>hbs004</value>
<value>hbs005</value>
</array>
</property>
<property name="sIds">
<array>
<value>rabbit</value>
<value>hippo</value>
<value>raccoon</value>
<value>elephant</value>
<value>lion</value>
</array>
</property>
<property name="sPws">
<array>
<value>p0001</value>
<value>p0002</value>
<value>p0003</value>
<value>p0004</value>
<value>p0005</value>
</array>
</property>
<property name="sNames">
<array>
<value>agatha</value>
<value>barbara</value>
<value>chris</value>
<value>doris</value>
<value>elva</value>
</array>
</property>
<property name="sAges">
<array>
<value>19</value>
<value>22</value>
<value>20</value>
<value>27</value>
<value>19</value>
</array>
</property>
<property name="sGenders">
<array>
<value>M</value>
<value>W</value>
<value>W</value>
<value>M</value>
<value>M</value>
</array>
</property>
<property name="sMajors">
<array>
<value>English</value>
<value>Korean</value>
<value>French</value>
<value>Philosophy</value>
<value>History</value>
</array>
</property>
</bean>
<!-- StudentDao 빈 -->
<bean id="studentDao"
class="ch04_pjt_01.ems.member.dao.StudentDao" />
<!-- StudentRegisterService 빈 생성 -->
<bean id="studentRegisterService"
class="ch04_pjt_01.ems.member.service.StudentRegisterService">
<constructor-arg ref="studentDao" />
</bean>
<!-- StudentModifyService 빈 생성 -->
<bean id="studentModifyService"
class="ch04_pjt_01.ems.member.service.StudentModifyService">
<constructor-arg ref="studentDao" />
</bean>
<!-- StudentDeleteService 빈 생성 -->
<bean id="studentDeleteService"
class="ch04_pjt_01.ems.member.service.StudentDeleteService">
<constructor-arg ref="studentDao" />
</bean>
<!-- StudentSelectService 빈 생성 -->
<bean id="studentSelectService"
class="ch04_pjt_01.ems.member.service.StudentSelectService">
<constructor-arg ref="studentDao" />
</bean>
<!-- StudentAllSelectService 빈 생성 -->
<bean id="studentAllSelectService"
class="ch04_pjt_01.ems.member.service.StudentAllSelectService">
<constructor-arg ref="studentDao" />
</bean>
<!-- PrintStudentInformationService 빈 생성 -->
<bean id="printStudentInformationService"
class="ch04_pjt_01.ems.member.service.PrintStudentInformationService">
<constructor-arg ref="studentAllSelectService" />
</bean>
<!-- DBConnectionInfo 빈 -->
<!-- 개발에 이용하는 데이터베이스 빈 생성 -->
<bean id="dev_DBConnectionInfoDev"
class="ch04_pjt_01.ems.member.DBConnectionInfo">
<property name="url" value="000.000.000.000" />
<property name="userId" value="admin" />
<property name="userPw" value="0000" />
</bean>
<!-- 실제 서비스에 이용하는 데이터베이스 빈 생성 -->
<bean id="real_DBConnectionInfo"
class="ch04_pjt_01.ems.member.DBConnectionInfo">
<property name="url" value="111.111.111.111" />
<property name="userId" value="master" />
<property name="userPw" value="1111" />
</bean>
<!-- EMSInformationService 빈 -->
<bean id="eMSInformationService"
class="ch04_pjt_01.ems.member.service.EMSInformationService">
<property name="info"
value="Education Management System program was developed in 2022." />
<property name="copyRight"
value="COPYRIGHT(C) 2022 EMS CO., LTD. ALL RIGHT RESERVED. CONTACT MASTER FOR MORE INFORMATION." />
<property name="ver" value="The version is 1.0" />
<property name="sYear" value="2022" />
<property name="sMonth" value="3" />
<property name="sDay" value="1" />
<property name="eYear" value="2022" />
<property name="eMonth" value="4" />
<property name="eDay" value="30" />
<property name="developers">
<list>
<value>Cheney.</value>
<value>Eloy.</value>
<value>Jasper.</value>
<value>Dillon.</value>
<value>Kian.</value>
</list>
</property>
<!-- administrators 필드 초기화 -->
<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>
<!-- dbInfos 필드 초기화 -->
<property name="dbInfos">
<map>
<entry>
<key>
<value>dev</value>
</key>
<ref bean="dev_DBConnectionInfoDev" /> // 개발용 데이터베이스 지정
</entry>
<entry>
<key>
<value>real</value>
</key>
<ref bean="real_DBConnectionInfo" /> // 실제 서비스 데이터베이스 지정
</entry>
</map>
</property>
</bean>
</beans>
InitSampleData 빈
InitSampleData는 학생 5명의 샘플 정보로 <bean>을 이용해서 빈을 생성할 수 있다.
<bean>은 id와 class 속성을 가진다.
- id : 빈을 가리키는 레퍼런스 변수 이름
- class : 클래스 이름
※ class 속성 값에 패키지를 포함한 클래스 이름을 반드시 명시해야한다!!
기존의 객체 생성 방법 | IoC 컨테이너에서 객체 생성 방법 |
InitSampleData initSampleData = new InitSampleData(); | <bean id="initSampleData" class="ch04_pjt_01.ems.utils.InitSampleData" /> |
<bean>에는 클래스의 멤버 필드를 나타내는 하위 태그로 <property>가 있고 이를 이용하여 필드를 초기화할 수 있다.
InitSampleData에 sNums 필드를 <bean>에서 초기화하면 다음과 같다.
기존의 객체 생성 방법 | IoC 컨테이너에서 객체 생성 방법 |
private String[] sNums = {"hbs001", "hbs002", "hbs003", "hbs004", "hbs005" }; | <bean id="initSampleData" class="ch04_pjt_01.ems.utils.InitSampleData"/> <property name="sNums"> <array> <value>hbs001</value> <value>hbs002</value> <value>hbs003</value> <value>hbs004</value> <value>hbs005</value> </array> <property> </bean> |
<property>의 name속성에는 필드 이름(sNums)을 명시하고, 데이터 타입이 배열인 경우 <array>와 <value>를 이용해서 값을 명시한다.
applicationContext.xml에서 sNums를 초기화 했으므로 InitSampleData에서 다시 sNums을 초기화하지 않아도 된다.
[변경 전] private String[] sNums = {"hbs001", "hbs002", "hbs003", "hbs004", "hbs005" };
[변경 후] private String[] sNums;
<bean>
- 빈 생성자를 위해 InitSampleData의 생성자를 이용
<property>
- sNums을 초기화하기 위해 sNums의 setter 메서드를 이용
- <property>의 <array>값은 InitSampleData의 setsNums(String[] sNums) 메서드에 전달된다!!!
<bean id="initSampleData" class="ch04_pjt_01.ems.utils.InitSampleData" /> | public InitSampleData() { } |
<array> <value>hbs001</value> <value>hbs002</value> <value>hbs003</value> <value>hbs004</value> <value>hbs005</value> </array> |
public void setsNums(String[] sNums) { this.sNums = sNums; } |
즉, <bean>태그를 이용해서 빈이 생성되고 필드는 <property>를 이용해서 초기화한다.
이때, <bean>은 생성자를 호출하고 <property>는 setter메서드를 호출한다.
어떠한 생성자도 명시하지 않으면 컴파일러가 컴파일 단계에서 자동으로 디폴트 생성자(default constructor)를 생성한다.
발생될 수 있는 에러 유형
1. InitSampleData에 생성자가 있는 경우 - "BeanInstantiationException : 디폴트 생성자를 찾을 수 없습니다"
InitSampleData에 다음과 같은 생성자가 있다면 컴파일러는 컴파일 단계에서 디폴트 생성자를 만들지 않는다.
<bean>은 디폴트 생성자를 호출할 수 없게 되므로 에러 발생한다.
public InitSampleData(String[] sNums){
this.sNums = sNums;
}
2. 초기화하려는 필드에 setter메서드가 없는 경우 - "NotWritablePropertyException: Bean속성 sNum에 쓸 수 없거나 잘못된 setter 메서드가 있습니다."
IoC 컨테이너는 필드를 초기화할 수 없어 에러가 발생한다.
위와같이 applicationContext.xml에서 필드를 초기화하고 InitSampleData.java를 다음과 같이 수정해준다.
package ch04_pjt_01.ems.utils;
public class InitSampleData {
private String[] sNums;
private String[] sIds;
private String[] sPws;
private String[] sNames;
private int[] sAges;
private char[] sGenders;
private String[] sMajors;
public String[] getsNums() {
return sNums;
}
public void setsNums(String[] sNums) {
this.sNums = sNums;
}
public String[] getsIds() {
return sIds;
}
public void setsIds(String[] sIds) {
this.sIds = sIds;
}
public String[] getsPws() {
return sPws;
}
public void setsPws(String[] sPws) {
this.sPws = sPws;
}
public String[] getsNames() {
return sNames;
}
public void setsNames(String[] sNames) {
this.sNames = sNames;
}
public int[] getsAges() {
return sAges;
}
public void setsAges(int[] sAges) {
this.sAges = sAges;
}
public char[] getsGenders() {
return sGenders;
}
public void setsGenders(char[] sGenders) {
this.sGenders = sGenders;
}
public String[] getsMajors() {
return sMajors;
}
public void setsMajors(String[] sMajors) {
this.sMajors = sMajors;
}
}
StudentDao 빈
StudentDao : <bean>을 이용해서 빈을 생성한다. 이때 id와 class 속성에는 initSampleData 빈을 생성할 때와 마찬가지로 id이름과 패키지를 포함한 클래스 이름을 명시한다.
<bean id="studentDao" class="ch04_pjt_01.ems.member.dao.StudentDao" />
모든 Service가 동일한 구조로 StudentRegisterService을 이해하면 모두 이해할 수 있다.
<bean>을 이용해서 StudentRegisterService 빈을 생성하는 코드는 다음과 같다.
<bean id="studentRegisterService" class="ch04_pjt_01.ems.member.service.StudentRegisterService"/>
StudentRegisterService는 객체가 생성될 때 생성자에서 studentDao 필드를 초기화하고, 이를 위해서 StudentDao를 외부에서 주입받고 있다.
즉 디폴트 생성자가 아닌 StudentDao를 주입받는 생성자를 이용해서 객체가 만들어진다.
public StudentRegisterService(StudentDao studentDao) {
this.studentDao = studentDao;
}
따라서 Ioc 컨테이너에서 StudentRegisterService 빈을 생성할 때도 외부에서 StudentDao 객체를 주입받기 위해 <constructor-arg> 태그를 이용한다.
<constructor-arg> : 생성자 매개변수
- ref 속성 : 외부에서 주입되는 빈의 id값을 명시
<bean id="studentRegisterService" class="ch04_pjt_01.ems.member.service.StudentRegisterService">
<constructor-arg ref="studentDao" />
</bean>
<에러>
StudentRegisterService 빈을 생성할 때 <constructor-arg>가 없는 경우 - No default constructor found;
StudentRegisterService는 유일하게 StudentDao를 매개변수로 받는 생성자만 가지고 있다.
만약, <constructor-arg>가 없다면?
→ 생성자 호출에 문제가 되기 때문에 다음과 같은 에러가 발생한다.
DBConnectionInfo빈
DBConnectionInfo는 InitSampleData와 마찬가지로 데이터베이스 연결에 필요한 url, userId, userPw 필드만 있다.
<property>를 이용한 필드 초기화 코드를 작성한다.
프로젝트를 진행할 때 개발용 데이터베이스와 실제 서비스에 이용하는 데이터베이스를 구분해주어야한다!!
<!-- 개발에 이용하는 데이터베이스 빈 생성 -->
<bean id="dev_DBConnectionInfoDev"
class="ch04_pjt_01.ems.member.DBConnectionInfo">
<property name="url" value="000.000.000.000" />
<property name="userId" value="admin" />
<property name="userPw" value="0000" />
</bean>
<!-- 실제 서비스에 이용하는 데이터베이스 빈 생성 -->
<bean id="real_DBConnectionInfo"
class="ch04_pjt_01.ems.member.DBConnectionInfo">
<property name="url" value="111.111.111.111" />
<property name="userId" value="master" />
<property name="userPw" value="1111" />
</bean>
EMSInformationService 빈
EMSInformationService는 필드가 12개이고 데이터 타입고 String, int, Map, List 등 다양하다.
데이터가 한 개이면 <value> 태그를 사용하지않고 <property> 태그의 value 속성을 이용할 수 있다.
<property name="copyRight"
value="COPYRIGHT(C) 2022 EMS CO., LTD. ALL RIGHT RESERVED. CONTACT MASTER FOR MORE INFORMATION." />
<property name="ver" value="The version is 1.0" />
<property name="sYear" value="2022" />
<property name="sMonth" value="3" />
<property name="sDay" value="1" />
<property name="eYear" value="2022" />
<property name="eMonth" value="4" />
<property name="eDay" value="30" />
데이터 타입이 기초 데이터 타입이 아닌 참조 데이터 타입인 필드를 초기화해본다.
developers는 데이터 타입이 List로, <list> 태그를 이용한다.
<property name="developers">
<list>
<value>Cheney.</value>
<value>Eloy.</value>
<value>Jasper.</value>
<value>Dillon.</value>
<value>Kian.</value>
</list>
</property>
administrators는 데이터 타입이 Map으로, <map>과 <entry> 태그를 사용한다.
그리고<key>와 <value>태그를 이용해서 Map의 key와 value를 입력한다.
<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>
dbInfos는 데이터 타입이 Map으로 key와 value 타입은 String과 DBConnectionInfo이다.
DBConnectionInfo는 내가 만든 타입이므로 <ref>를 이용하여 DBConnectionInfo 빈을 지정할 수 있다.
<property name="dbInfos">
<map>
<entry>
<key>
<value>dev</value>
</key>
<ref bean="dev_DBConnectionInfoDev" /> // 개발용 데이터베이스 지정
</entry>
<entry>
<key>
<value>real</value>
</key>
<ref bean="real_DBConnectionInfo" /> // 실제 서비스 데이터베이스 지정
</entry>
</map>
</property>
메이븐 설정 파일
applicationContext.xml을 이용해서 IoC 컨테이너를 만드는 클래스 GenericXmlApplicationContext는 org.springframework.context.support 패키지에 있는 클래스로 pom.xml에 spring-context 모듈을 이용해서 다운로드하고 사용할 수 있다.
pom.xml 코드는 다음과 같다.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>spring5</groupId>
<artifactId>ch04_pjt_01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- spring-context 모듈 -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
</dependencies>
<!-- 빌드 설정 -->
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>11</source>
<target>11</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
'Spring & Springboot > 올인원 스프링 프레임워크' 카테고리의 다른 글
학사 관리 시스템 -4 (0) | 2023.09.14 |
---|---|
학사 관리 시스템 -3 (0) | 2023.09.14 |
학사 관리 시스템 -1 (0) | 2023.09.13 |
프로젝트 생성 시 나타나는 경고 해결방안 (0) | 2023.09.12 |
스프링을 이용한 계산기 프로그램 (0) | 2023.09.12 |