스프링 개념 정리
DI
종류
생성자를 이용한 의존 객체 주입 (
new
로 생성하지 않고 객체 주입함)- 자바 파일
public StudentRegisterService(StudentDao studentDao) { this.studentDao = studentDao; } public StudenModifyService(StudentDao studentDao) { this.studentDao = studentDao; } (...)
- xml 파일
<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> (...)
Setter를 이용한 의존 객체 주입
- 자바 파일
public void setJdbcUrl(String jdbcUrl) { this.jdbcUrl = jdbcUrl; } public void setUserId(String userId) { this.userId = userId; } public void setUserPw(Sring userPw) { this.userPw = userPw; }
- xml 파일
<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>
setter
방식을 사용하는 규칙- java파일의 메소드 명에서
set
을 떼고 앞글자는 소문자로 만들어서bean
의 프로퍼티인name
속성으로 지정해 주어야 한다. - 파라미터로 들어오는 값은
value
속성에서 지정해 주어야 한다.
- java파일의 메소드 명에서
List타입 의존 객체 주입
- 자바 파일
public void setDevelopers(List<String> developers) { this.developers = developers; }
- xml 파일
<property name="developers"> <list> <value>A</value> <value>B</value> <value>C</value> <value>D</value> </list> </property>
- setter 방식은 파라미터가 단일이기 때문에
value
키워드를 쓸 수 있었지만,List
는list
라는 태그 안에value
속성을 넣어 주어야 한다.
Map타입 의존 객체 주입
- 자바 파일
public void setAdministrators(Map<String> administrators) { this.administrators = administrators; }
- xml 파일
<property name="administrators"> <map> <entry> <key> <value>Cheney</value> </key> <value> <value>cheney@springPjt.org</value> </value> </entry> <entry> <key> <value>Jasper</value> </key> <value> <value>jasper@springPjt.org</value> </value> </entry> </map> </property>
- Map 방식은
key
와value
값을 가지고 있어야 하기 때문에<entry>
라는 태그 안에<key>
,<value>
쌍을 이루게 주입시킨다.
객체 & Service 등록
스프링에서의 사용
applicationContext.xml
파일<bean id="studentDao" class="ems.member.dao.StudentDao"></bean> <bean id="modifyService" class="ems.member.service.StudentModifyService"> <constructor-arg ref="studentDao"></constructor-arg> </bean>
스프링 부트에서의 사용
- 스프링 부트의 경우에는 class와 id로 서비스를 직접 등록할 필요가 없음. 서비스 클래스 위에
@Service
어노테이션을 붙여주면 됨. }
- 스프링 부트의 경우에는 class와 id로 서비스를 직접 등록할 필요가 없음. 서비스 클래스 위에
스프링 컨테이너 생성
- 스프링에서의 사용
MainClassUseXML.java
파일GenericXmlApplicationcontext ctx = new GenericXmlApplicationContext("classpath:applicationContext.xml");
DI가 끝난 객체들을 갖다 쓰는 법
MainClassUseXML.java
파일
StudentRegisterService modifyService = ctx.getBean("modifyService", StudentModifyService.class);
modifyService.modify(new Student("12345", "deer", "00000", "melissa", 26, "W", "Vocal Music"));
스프링 파일 만드는 순서
DTO
생성Service
생성xml
파일로bean
생성 (appContext 파일)GenericXmlApplicationContext
로 xml 등록
스프링 xml 분리
분리하지 않은 방식
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:appCtx.xml");
카테고리에 따라 분리한 방식
String[] appCtxs = {"classpath:appCtx1.xml", "classpath:appCtx2.xml", "classpath:appCtx3.xml"}; GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(appCtxs);
- 파일을 하나하나 따로 분리할 경우, 경로를 String 타입의 배열에 저장하여 적용한다.
- 세개의 방식 중 제일 많이 사용하는 방식
xml import 방식
appCtx.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"> <import resource="classpath:appCtx1.xml"/> </beans>
MainClassUseXMLs
파일GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:appCtx.xml");
최상단의 xml에 다른 xml들을 import 시킨 후에 최상단의 xml만 메인문에서 적용한다.
Bean
개념
의존객체 자동 주입
- 스프링 설정 파일에서 의존 객체를 주입할 때
<constructor-org>
또는<property>
태그로 의존 대상 객체를 명시하지 않아도 스프링 컨테이너가 자동으로 필요한 의존 대상 객체를 찾아 주입해 주는 기능이다.
@Autowired
주입하려고 하는 객체의 타입이 일치 하는 객체를 자동으로 주입.
사용법
appContext
에서<bean>
객체 생성만 해주고,<constructor>
로 주입을 시켜주지 않는다. 대신Service
의 생성자 위에@AutoWired
어노테이션을 붙여준다.appContext
에서<beans>
에 스키마를 추가해준다.xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
<beans>
내부에<context:annotation-config />
라는 태그 추가해준다.
@Resource
주입하려고 하는 객체의 이름이 일치 하는 객체를 자동으로 주입.
주의사항
Resource
는 생성자에는 쓰지 못하고 프로퍼티 또는 메소드에만 사용할 수 있다.
- 공통 주의사항 일반 생성자에
@AutoWired
를 쓰는것은 상관 없으나, 프로퍼티나 메소드에 쓸 경우에는파라미터가 없는 Default 생성자
가 있어야 작동한다.
(일단 해당 서비스 객체가 만들어져야 자동으로 주입 시켜줄 수 있기 때문)
의존 객체 선택
자동객체 주입을 사용할 때, 같은 속성으로 여러개의 Bean 객체가 있을때는 Exception이 난다.
해당 문제를 해결하기 위해 두가지의 방법이 있다.Qualifier
를 사용하는 방식 (추천)appCtxUseAutowired.xml
```xml
</bean> ``` - `WordSearchService.java` ```java @Autowired @Qualifier("usedDao") private WordDao wordDao; ``` - 이름만 맞춰주는 방법 (별로 좋은 방식이 아님)
appCtxUseAutowired.xml
```xml
- `WordSearchService.java` ```java @Autowired private WordDao wordDao;
@Inject
@Autowired
와 거의 비슷하게@Inject
어노테이션을 이용해 의존 객체를 자동으로 주입한다.- 차이점
@Autowired
의 경우required
속성을 이용해서 의존 대상 객체가 없어도 Exeption을 피할 수 있지만,@Inject
의 경우 required 속성을 지원하지 않는다.@Named
라는 어노테이션을 추가하여 중복되는 속성의 객체들이 있을 경우, 이름으로 객체를 찾을 수 있다.
(@Autowired
의 경우 bean 객체 안에qualifier
를 사용해 주어야 해서 번거로웠다.)
[예]
appCtxUseAutowired.xml
<bean id="wordDao1" class="com.word.dao.Word.Dao" /> <bean id="wordDao2" class="com.word.dao.Word.Dao" /> <bean id="wordDao3" class="com.word.dao.Word.Dao" />
WordSearchService.java
java @Inject @Named(value="wordDao1") private WordDao wordDao;
스프링의 생명주기
Bean 객체가 생성될 때, Bean 객체가 소멸될 때 어떠한 이벤트를 필요로 한다면 사용할 수 있는 기술이 있다.
(예를 들어 해당 객체가 데이터베이스에 연결할 필요가 있어서 데이터베이스에 인증을 해야하는 경우 혹은 연결을 소멸시켜야 할 경우 등)- 인터페이스를 사용하는 방법
- 해당 Service에
InitializingBean
,DisposableBean
등의 인터페이스를 상속 afterPropertiesSet()
과destroy()
메소드를 오버라이딩하여 사용
- 해당 Service에
- Bean에 직접 등록해주는 방법
해당
bean
객체에init-method
,destroy-method
속성 추가appCtx.xml
```xml
- `BookRegisterService.java`
public void initMethod() { System.out.println(“–initMethod()–”); }
public void destroyMethod() { System.out.println(“–destroyMethod()–”); } ```
- 인터페이스를 사용하는 방법
스프링 xml파일을 java 파일로 변환
- ctx 설정하는 객체도 달라졌다.
AnnotationConfigApplicationContext
를 사용한다.AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MemberConfig.class);
applicationConfig.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="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>
<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>
<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>
Memberconfig.java
파일 ```java package ems.member.configration;
import java.util.ArrayList; import java.util.HashMap; import java.util.Map;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
import ems.member.DataBaseConnectionInfo; import ems.member.dao.StudentDao; import ems.member.service.EMSInformationService; import ems.member.service.StudentAllSelectService; import ems.member.service.StudentDeleteService; import ems.member.service.StudentModifyService; import ems.member.service.StudentRegisterService; import ems.member.service.StudentSelectService;
@Configuration public class MemberConfig {
/* <bean id="studentDao" class="ems.member.dao.StudentDao" ></bean> */
@Bean
public StudentDao studentDao() {
return new StudentDao();
}
@Bean
public StudentRegisterService registerService() {
return new StudentRegisterService(studentDao());
}
@Bean
public StudentModifyService modifyService() {
return new StudentModifyService(studentDao());
}
@Bean
public StudentSelectService selectService() {
return new StudentSelectService(studentDao());
}
@Bean
public StudentDeleteService deleteService() {
return new StudentDeleteService(studentDao());
}
@Bean
public StudentAllSelectService allSelectService() {
return new StudentAllSelectService(studentDao());
}
@Bean
public DataBaseConnectionInfo dataBaseConnectionInfoDev() {
DataBaseConnectionInfo infoDev = new DataBaseConnectionInfo();
infoDev.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:xe");
infoDev.setUserId("scott");
infoDev.setUserPw("tiger");
return infoDev;
}
@Bean
public DataBaseConnectionInfo dataBaseConnectionInfoReal() {
DataBaseConnectionInfo infoReal = new DataBaseConnectionInfo();
infoReal.setJdbcUrl("jdbc:oracle:thin:@192.168.0.1:1521:xe");
infoReal.setUserId("masterid");
infoReal.setUserPw("masterpw");
return infoReal;
}
@Bean
public EMSInformationService informationService() {
EMSInformationService info = new EMSInformationService();
info.setInfo("Education Management System program was developed in 2015.");
info.setCopyRight("COPYRIGHT(C) 2015 EMS CO., LTD. ALL RIGHT RESERVED. CONTACT MASTER FOR MORE INFORMATION.");
info.setVer("The version is 1.0");
info.setsYear(2015);
info.setsMonth(1);
info.setsDay(1);
info.seteYear(2015);
info.seteMonth(2);
info.seteDay(28);
ArrayList<String> developers = new ArrayList<String>();
developers.add("Cheney.");
developers.add("Eloy.");
developers.add("Jasper.");
developers.add("Dillon.");
developers.add("Kian.");
info.setDevelopers(developers);
Map<String, String> administrators = new HashMap<String, String>();
administrators.put("Cheney", "cheney@springPjt.org");
administrators.put("Jasper", "jasper@springPjt.org");
info.setAdministrators(administrators);
Map<String, DataBaseConnectionInfo> dbInfos = new HashMap<String, DataBaseConnectionInfo>();
dbInfos.put("dev", dataBaseConnectionInfoDev());
dbInfos.put("real", dataBaseConnectionInfoReal());
info.setDbInfos(dbInfos);
return info;
}
}
---
##### 스프링 config.java 파일을 분리
- Standard한 방법은 기능별로 구별하는 것이다.
- ctx 선언 방법이 여러가지가 있다. 본인은 첫번째 방법이 눈에 보기 좋아 선호한다.
1. 모든 Config를 배열 형태로 표시
```java
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(MemberConfig1.class, MemberConfig2.class, MemberConfig3.class);
```
2. 한 config에 `@Import` 사용
```java
@Configuration
@Import({MemberConfig2.class, MemberConfig3.class})
public class MemberConfig1 {
(...)
```
- `MemberConfig1.java` 파일
```java
package ems.member.configration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ems.member.dao.StudentDao;
import ems.member.service.StudentAllSelectService;
import ems.member.service.StudentDeleteService;
import ems.member.service.StudentModifyService;
import ems.member.service.StudentRegisterService;
import ems.member.service.StudentSelectService;
@Configuration
public class MemberConfig1 {
/* <bean id="studentDao" class="ems.member.dao.StudentDao" ></bean> */
@Bean
public StudentDao studentDao() {
return new StudentDao();
}
@Bean
public StudentRegisterService registerService() {
return new StudentRegisterService(studentDao());
}
@Bean
public StudentModifyService modifyService() {
return new StudentModifyService(studentDao());
}
@Bean
public StudentSelectService selectService() {
return new StudentSelectService(studentDao());
}
@Bean
public StudentDeleteService deleteService() {
return new StudentDeleteService(studentDao());
}
@Bean
public StudentAllSelectService allSelectService() {
return new StudentAllSelectService(studentDao());
}
}
MemberConfig2.java
파일
```java package ems.member.configration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
import ems.member.DataBaseConnectionInfo;
@Configuration public class MemberConfig2 {
@Bean
public DataBaseConnectionInfo dataBaseConnectionInfoDev() {
DataBaseConnectionInfo infoDev = new DataBaseConnectionInfo();
infoDev.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:xe");
infoDev.setUserId("scott");
infoDev.setUserPw("tiger");
return infoDev;
}
@Bean
public DataBaseConnectionInfo dataBaseConnectionInfoReal() {
DataBaseConnectionInfo infoReal = new DataBaseConnectionInfo();
infoReal.setJdbcUrl("jdbc:oracle:thin:@192.168.0.1:1521:xe");
infoReal.setUserId("masterid");
infoReal.setUserPw("masterpw");
return infoReal;
}
}
- `MemberConfig3.java` 파일
```java
package ems.member.configration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ems.member.DataBaseConnectionInfo;
import ems.member.service.EMSInformationService;
@Configuration
public class MemberConfig3 {
// @Bean
// public DataBaseConnectionInfo dataBaseConnectionInfoDev() {
// DataBaseConnectionInfo infoDev = new DataBaseConnectionInfo();
// infoDev.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:xe");
// infoDev.setUserId("scott");
// infoDev.setUserPw("tiger");
//
// return infoDev;
// }
//
// @Bean
// public DataBaseConnectionInfo dataBaseConnectionInfoReal() {
// DataBaseConnectionInfo infoReal = new DataBaseConnectionInfo();
// infoReal.setJdbcUrl("jdbc:oracle:thin:@192.168.0.1:1521:xe");
// infoReal.setUserId("masterid");
// infoReal.setUserPw("masterpw");
//
// return infoReal;
// }
@Autowired
DataBaseConnectionInfo dataBaseConnectionInfoDev;
@Autowired
DataBaseConnectionInfo dataBaseConnectionInfoReal;
@Bean
public EMSInformationService informationService() {
EMSInformationService info = new EMSInformationService();
info.setInfo("Education Management System program was developed in 2015.");
info.setCopyRight("COPYRIGHT(C) 2015 EMS CO., LTD. ALL RIGHT RESERVED. CONTACT MASTER FOR MORE INFORMATION.");
info.setVer("The version is 1.0");
info.setsYear(2015);
info.setsMonth(1);
info.setsDay(1);
info.seteYear(2015);
info.seteMonth(2);
info.seteDay(28);
ArrayList<String> developers = new ArrayList<String>();
developers.add("Cheney.");
developers.add("Eloy.");
developers.add("Jasper.");
developers.add("Dillon.");
developers.add("Kian.");
info.setDevelopers(developers);
Map<String, String> administrators = new HashMap<String, String>();
administrators.put("Cheney", "cheney@springPjt.org");
administrators.put("Jasper", "jasper@springPjt.org");
info.setAdministrators(administrators);
Map<String, DataBaseConnectionInfo> dbInfos = new HashMap<String, DataBaseConnectionInfo>();
// dbInfos.put("dev", dataBaseConnectionInfoDev());
// dbInfos.put("real", dataBaseConnectionInfoReal());
// 위쪽 주석의 내용으로 받아내야 하나, 기능별로 config 파일을 분리했으므로 `@AutoWired`를 사용하여 Bean 객체를 받아온다.
dbInfos.put("dev", dataBaseConnectionInfoDev);
dbInfos.put("real", dataBaseConnectionInfoReal);
info.setDbInfos(dbInfos);
return info;
}
}