note

Spring Di 심화 학습 본문

JSP/Spring

Spring Di 심화 학습

투한 2012. 2. 29. 09:22
원본 주소







==================================이론======================================

스프링 컨테이너


BeanFactory 인터페이스
  FileSystemResource        파일 시스템의 특정 파일로부터 정보를 읽어 온다.
  InputStreamResource       InputStream 으로 부터 정보를 읽어온다.
  ClassPathResource          클래스패스(src) 에있는 자원으로부터 정보를 읽어온다.
  UrlResource                   특정 URL로부터 정보를 읽어온다.
  ServletContextResource    웹 어플리케이션의 루트 디렉터리를 기준으로 지정한 경로에 위치한 자원으로 부터 정보를 읽어온다.


ApplicationContext 인터페이스
WebApplicationContext 인터페이스
  ClassPathXmlApplicationContext    클래스에 위치한 XML 파일로부터 설정 정보를 로딩한다.
  FileSystemXmlApplicationContext   파일 시스템에 위치한 XML 파일로부터 설정 정보를 로딩한다.
  XmlWebApplicationContext            웹 어플리케이션에 위치한 XML 파일로 부터 설정 정보를 로딩한다.

빈(Bean)생성과 의존 관계 설정

의존관계설정

(1)생성자 방식
 



(2)프로퍼티 설정 방식

<!-- 프로퍼티 설정 방식 -->
<bean name="writeArticleService" class="madvirus.spring.chap02.WriteArticleServiceImpl">
     <property name="articleDao">
            <ref bean="mysqlArticleDao"/>            
        </property>
    </bean>
<bean name="mysqlArticleDao" class="madvirus.spring.chap02.MySQLArticleDao"/>


(3)XML 네임스페이스를 이용한 프로퍼티 설정

xmlns:p="http://www.springframework.org/schema/p

<bean id="monitor" class="madvirus.spring.chap02.SystemMonitor" p:periodTime="10" p:sender-ref="smsSender"/>
<bean id="smsSender" class="madvirus.spring.chap02.SmsSender"/>   

주의!!
p:프로퍼티이름 형식을 사용할 경우 이름이 Ref로 끝나는 프로퍼티에 대해서는 설정할 수가 없다. 따라서, 이런 경우에는 <property> 태그를 이용해서 값을 설정해주어야한다.


(4)룩업 메서드 인젝션 방식

룩업 메서드는 다음과 같은 규칙을 따라야 한다.

* 접근 수식어가 public 이나 protected 여야 한다.
리턴 타입이 void가 아니다.
인자를 갖지않는다.
* 추상 메서드여도(abstract) 된다. = 추상메서드 추상클래스여야한다.
*  final이 아니다.



(5)임의 빈 객체 전달

한번밖에 호출못한 ID가없기때문.
별로 좋은방법은 아니다.


콜렉션 타입 프로퍼티 설정

<list> : java.util.List                    : List 타입이나 배열에 값 목록을 전달할 때 사용된다.
<map>: java.util.Map                 : Map 타입에 <키,값> 목록을 전달 할 때 사용된다.
<set>: java.util.Set                     : Set 타입에 값 목록을 전달할 때 사용된다.
<properties>: java.util.Properties : Properties 타입에 <프로퍼티이름, 프로퍼티값> 목록을 전달할 때 사용된다.


(1) List 타입과 배열

<!-- List 타입 프로퍼티 설정 -->
<bean name="performanceMonitor" class="madvirus.spring.chap02.PerformanceMonitor">
   <property name="deviations">
       <list>
            //제네릭표현 Double시
           <value type="java.lang.Double">0.2</value>
           <value type="java.lang.Double">0.3</value>
       </list>
   </property>

(2) Map 타입

Object형이기때문에 제네릭 표현이가능
key - Object
Value - Object

<bean name="handlerFactory" class="madvirus.spring.chap02.ProtocolHandlerFactory">
   <property name="handlers">
      <map>
            <entry>
               <ket><value>soap</value></key>
               <ref bean="soapHandler"/>
            </entry>
            <entry>
                <key><value>rest</value></key>
                <ref bean="restHandler"/>
            </entry>
            <entry>
                <key><키태그>...</키태그></key>             
                <값태그>...</값태그>
            </entry>
      </map>
   </property>
</bean>

<ref> - 다른 스프링 빈 객체를 키로사용
<bean> - 임의 빈 객체를 생성해서 키로 사용
<value> - 래퍼타입이나 String 을 키로 사용
<list>,<map>,<props>,<set> - 콜렉션 객체를 키로 사용
<null> - null값을 키로 사용

//키와 값의 속성을 지정
<map key-type="jana.lang.Integer" value-type="java.lang.Double">


(3) Properties 타입

String으로만 처리하기때문에 제네릭안함
key - String
Value - String

<bean name="client" class="madvirus.spring.chap02.BookClient">
   <property name="config">
      <props>
            <prop key="server">192.168.1.100</prop>
            <prop keyt="connectionTimeout">5000</prop>
      </props>
   </property>
</bean>

(4) Set 타입

중복값을 허용하지 않는 는다.
중복값을 허용하지 않는 경우외에는 보통 리스트 사용을 많이함.

<property name="subset">
    <set value-type="java.lang.Integer">
         <value>10</value>
         <value>20</value>
         <value>30</value>
    </set>
</property>

<ref> - 다른 스프링 빈 객체를 키로사용
<bean> - 임의 빈 객체를 생성해서 키로 사용
<value> - 래퍼타입이나 String 을 키로 사용
<list>,<map>,<props>,<set> - 콜렉션 객체를 키로 사용
<null> - null레퍼런스를 값으로 사용

==================================프로젝트======================================
예제.
madvirus.spring.chap02
     Article (객체형식을 지정할 용도)
     ArticleDao (인터페이스 insert메소드)
     Command (인터페이스 execute메소드)
     CommandFactory (인터페이스 createCommand 메소드)
     CommandFactoryImpl (CommandFactory를 구현 createCommand메소드 구현)
     Main (기본 프로퍼티 설정)
     Main02 (XML네임스페이스를 이용한 프로퍼티 설정)
     Main03 (룩업 메서드 인젝션 방식)
     Main04 (콜렉션 타입 프로퍼티 설정 - List타입과 배열)
     MySQLArticleDao (ArticleDao 를 구현 insert메소드 구현)
     PerformanceMonitor (콜렉션 타입 프로퍼티 설정 - List타입과 배열)
     Processor (getCommandFactory메서드를 통해 CommandFactory를 객체생성 createCommand(commandName) 
                      로 Command객체를 생성 execute메서드실행)
     SmsSender (객체형식을 지정할 용도)
     SomeCommand (Command 를 구현  execute메서드 구현)
     SystemMonitor (XML네임스페이스 출력부분)
     WriteArticleService (인터페이스 write메소드)
     WriteArticleServiceImpl (WriteArticleService를 구현한 write메소드 구현)
applicationContext.xml (DI(Dependency Injection 처리): 객체의 외부에서 두개의 의존성있는 객체의 관계를 형성)

==================================코드======================================
예제.
madvirus.spring.chap02
     Article (객체형식을 지정할 용도)
package madvirus.spring.chap02;

public class Article {
}

     ArticleDao (인터페이스 insert메소드)
package madvirus.spring.chap02;

public interface ArticleDao {
    void insert(Article article);
}

     Command (인터페이스 execute메소드)
package madvirus.spring.chap02;

public interface Command {    
    void execute();
}

     CommandFactory (인터페이스 createCommand 메소드)
package madvirus.spring.chap02;

public interface CommandFactory {

    Command createCommand(String commandName);
}

     CommandFactoryImpl (CommandFactory를 구현 createCommand메소드 구현)
package madvirus.spring.chap02;

public class CommandFactoryImpl implements CommandFactory{

    @Override
    public Command createCommand(String commandName) {
        if(commandName.equals("some")){
            return new SomeCommand();
        }
        return null;
    }
}

     Main (기본 프로퍼티 설정)
package madvirus.spring.chap02;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class Main {
    public static void main(String[] args){
        Resource resource = new ClassPathResource("applicationContext.xml");
        BeanFactory beanFactory = new XmlBeanFactory(resource);
        //WriteArticleService articleService = (WriteArticleService)beanFactory.getBean("writeArticleService");
        
        //제네릭표현
        WriteArticleService articleService = beanFactory.getBean("writeArticleService",WriteArticleService.class);
        
        articleService.write(new Article());
    }
}

     Main02 (XML네임스페이스를 이용한 프로퍼티 설정)
package madvirus.spring.chap02;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main02 {
    public static void main(String[] args){
        String[] configLocations = new String[] {"applicationContext.xml"};
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
        
        //XML 네임 스페이스를 이용한 프로퍼티 설정
        SystemMonitor articleService = (SystemMonitor)context.getBean("monitor");
        System.out.println(articleService);
    }
}

     Main03 (룩업 메서드 인젝션 방식)
package madvirus.spring.chap02;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main03 {
    public static void main (String[] args){
        String[] configLocations = new String[] {"applicationContext.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
        
        //룩업 메서드 인젝션 방식
        Processor processor = context.getBean("processor",Processor.class);
        processor.process("some");
    }
}

     Main04 (콜렉션 타입 프로퍼티 설정 - List타입과 배열)
package madvirus.spring.chap02;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main04 {
    public static void main(String[] args){
        String[] configLocations = new String[]{"applicationContext.xml"};    
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
        
        //List 타입 프로퍼티 설정
        PerformanceMonitor monitor= (PerformanceMonitor)context.getBean("performanceMonitor");
        System.out.println(monitor);
    }
}

     MySQLArticleDao (ArticleDao 를 구현 insert메소드 구현)
package madvirus.spring.chap02;

public class MySQLArticleDao implements ArticleDao{
    
    @Override
    public void insert(Article article){
        System.out.println("MySQLArticleDao.insert()실행");
    }    
}

     PerformanceMonitor (콜렉션 타입 프로퍼티 설정 - List타입과 배열)
package madvirus.spring.chap02;

import java.util.List;

public class PerformanceMonitor {
    
    private List<Double> deviations;
    
    public void setDeviations(List<Double> deviations){
        this.deviations = deviations;
    }

    @Override
    public String toString() {
        return "PerformanceMonitor [deviations=" + deviations + "]";
    }
}

     Processor (getCommandFactory메서드를 통해 CommandFactory를 객체생성 createCommand(commandName) 로 Command객체를 생성 execute메서드실행
package madvirus.spring.chap02;

public class Processor {

    public void process(String commandName){
        CommandFactory factory = getCommandFactory();
        Command command = factory.createCommand(commandName);
        command.execute();
    }
    
    protected CommandFactory getCommandFactory(){
        return null;
    }
}

     SmsSender (객체형식을 지정할 용도)
package madvirus.spring.chap02;

public class SmsSender {
}

     SomeCommand (Command 를 구현  execute메서드 구현)
package madvirus.spring.chap02;

public class SomeCommand implements Command{

    @Override
    public void execute() {
        System.out.println("SomeCommand executed.");
    }    
}

     SystemMonitor (XML네임스페이스 출력부분)
package madvirus.spring.chap02;

public class SystemMonitor {
    
    private long periodTime;
    private SmsSender sender;
    
    
    public void setPeriodTime(long periodTime) {
        this.periodTime = periodTime;
    }
    public void setSender(SmsSender sender) {
        this.sender = sender;
    }
    
    @Override
    public String toString() {
        return "SystemMonitor [periodTime=" + periodTime + ", sender=" + sender
                + "]";
    }
}

     WriteArticleService (인터페이스 write메소드)
package madvirus.spring.chap02;

public interface WriteArticleService {
    void write(Article article);
}

     WriteArticleServiceImpl (WriteArticleService를 구현한 write메소드 구현)
package madvirus.spring.chap02;

public class WriteArticleServiceImpl implements WriteArticleService{

    private ArticleDao articleDao;
    
    //의존 관계 설정 방식: 프로퍼티
    public void setArticleDao(ArticleDao articleDao){
        this.articleDao = articleDao;
    }    
    
    @Override
    public void write(Article article) {        
        System.out.println("WriteArticleServiceImpl.write() 메서드 실행");
        articleDao.insert(article);
    }    
}

applicationContext.xml (DI(Dependency Injection) 처리 : 객체의 외부에서 두개의 의존성있는 객체의 관계를 형성)
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    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-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- 프로퍼티 설정 방식 -->
    <bean name="writeArticleService" class="madvirus.spring.chap02.WriteArticleServiceImpl">
        <property name="articleDao">
            <ref bean="mysqlArticleDao"/>            
        </property>
    </bean>
    <bean name="mysqlArticleDao" class="madvirus.spring.chap02.MySQLArticleDao"/>
    
    <!-- XML 네임스페이스를 이용한 프로퍼티 설정 -->
    <!-- p:periodTime p:sender  프로퍼티명  -->
    <!-- ref="smsSender" 빈객체 전달 -->
    <bean id="monitor" class="madvirus.spring.chap02.SystemMonitor" p:periodTime="10" p:sender-ref="smsSender"/>
    <bean id="smsSender" class="madvirus.spring.chap02.SmsSender"/>    
    
    <!-- 룩업 메서드 인젝션 방식 -->
    <bean id="processor" class="madvirus.spring.chap02.Processor">
        <!-- 메서드인젝션 -->
        <lookup-method name="getCommandFactory" bean="commandFactory"/>        
    </bean>
    <bean id="commandFactory" class="madvirus.spring.chap02.CommandFactoryImpl"/>    
    
    <!-- List 타입 프로퍼티 설정 -->
    <bean name="performanceMonitor" class="madvirus.spring.chap02.PerformanceMonitor">
        <property name="deviations">
            <list>
                <value type="java.lang.Double">0.2</value>
                <value type="java.lang.Double">0.3</value>
            </list>
        </property>
    </bean>
</beans>

==================================결과값===================================== 
1. 프로퍼티 설정 방식



2. XML네임스페이스를 이용한 프로퍼티 설정


3. 룩업 메서드 인젝션 방식 


4. 콜렉션 타입 프로퍼티 설정 - List타입과 배열