스프링 개념 정리



DI


종류
  1. 생성자를 이용한 의존 객체 주입 (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>
     (...)
    
  2. 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방식을 사용하는 규칙
      1. java파일의 메소드 명에서 set을 떼고 앞글자는 소문자로 만들어서 bean의 프로퍼티인 name속성으로 지정해 주어야 한다.
      2. 파라미터로 들어오는 값은 value 속성에서 지정해 주어야 한다.
  3. 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키워드를 쓸 수 있었지만, Listlist라는 태그 안에 value속성을 넣어 주어야 한다.
  4. 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 방식은 keyvalue값을 가지고 있어야 하기 때문에 <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 어노테이션을 붙여주면 됨. }
스프링 컨테이너 생성
  • 스프링에서의 사용 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"));

스프링 파일 만드는 순서

  1. DTO 생성
  2. Service 생성
  3. xml파일로 bean생성 (appContext 파일)
  4. GenericXmlApplicationContext 로 xml 등록

스프링 xml 분리
  1. 분리하지 않은 방식

    GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:appCtx.xml");
    
  2. 카테고리에 따라 분리한 방식

     String[] appCtxs = {"classpath:appCtx1.xml", "classpath:appCtx2.xml", "classpath:appCtx3.xml"};
    
     GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(appCtxs);
    
  • 파일을 하나하나 따로 분리할 경우, 경로를 String 타입의 배열에 저장하여 적용한다.
  • 세개의 방식 중 제일 많이 사용하는 방식
  1. 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 개념

image


의존객체 자동 주입
  • 스프링 설정 파일에서 의존 객체를 주입할 때 <constructor-org> 또는 <property> 태그로 의존 대상 객체를 명시하지 않아도 스프링 컨테이너가 자동으로 필요한 의존 대상 객체를 찾아 주입해 주는 기능이다.
  1. @Autowired

    • 주입하려고 하는 객체의 타입이 일치 하는 객체를 자동으로 주입.

    • 사용법

    1. appContext에서 <bean> 객체 생성만 해주고, <constructor>로 주입을 시켜주지 않는다. 대신 Service의 생성자 위에 @AutoWired 어노테이션을 붙여준다.
    2. 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"
      
    3. <beans> 내부에 <context:annotation-config /> 라는 태그 추가해준다.
  2. @Resource

    • 주입하려고 하는 객체의 이름이 일치 하는 객체를 자동으로 주입.

    • 주의사항 Resource는 생성자에는 쓰지 못하고 프로퍼티 또는 메소드에만 사용할 수 있다.

  • 공통 주의사항 일반 생성자에 @AutoWired를 쓰는것은 상관 없으나, 프로퍼티나 메소드에 쓸 경우에는 파라미터가 없는 Default 생성자가 있어야 작동한다.
    (일단 해당 서비스 객체가 만들어져야 자동으로 주입 시켜줄 수 있기 때문)

의존 객체 선택

  • 자동객체 주입을 사용할 때, 같은 속성으로 여러개의 Bean 객체가 있을때는 Exception이 난다.
    해당 문제를 해결하기 위해 두가지의 방법이 있다.

    1. Qualifier를 사용하는 방식 (추천)
      • appCtxUseAutowired.xml
        ```xml
      </bean> ``` - `WordSearchService.java` ```java @Autowired @Qualifier("usedDao") private WordDao wordDao; ```
    2. 이름만 맞춰주는 방법 (별로 좋은 방식이 아님)
      • appCtxUseAutowired.xml
        ```xml
      - `WordSearchService.java`  
       ```java
       @Autowired
       private WordDao wordDao;
      
  • @Inject

    • @Autowired와 거의 비슷하게 @Inject 어노테이션을 이용해 의존 객체를 자동으로 주입한다.
    • 차이점
      1. @Autowired의 경우 required 속성을 이용해서 의존 대상 객체가 없어도 Exeption을 피할 수 있지만, @Inject의 경우 required 속성을 지원하지 않는다.
      2. @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 객체가 소멸될 때 어떠한 이벤트를 필요로 한다면 사용할 수 있는 기술이 있다.
    (예를 들어 해당 객체가 데이터베이스에 연결할 필요가 있어서 데이터베이스에 인증을 해야하는 경우 혹은 연결을 소멸시켜야 할 경우 등)

    1. 인터페이스를 사용하는 방법
      • 해당 Service에 InitializingBean, DisposableBean 등의 인터페이스를 상속
      • afterPropertiesSet()destroy() 메소드를 오버라이딩하여 사용
    2. 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;
	}
	
}



© 2019. by mintheon

Powered by mintheon