본문 바로가기

Spring/토비의 스프링 3.1

1.8 XML을 이용한 설정


1.8.1 XML 설정

DI정보가 담긴 XML : <beans>를 루트 엘리먼트로 사용

  • 여러 개의 <bean>을 정의할 수 있음
  • @Configuration과 @Bean이 붙은 자바 클래스와 설정이 동일
  • @Congiguration - <beans> // @Bean - <bean> 에 대응
  • 하나의 @Bean 메소드에서 얻을 수 있는 빈의 DI 정보
    1. 빈의 이름 : @Bean 메소드 이름, getBean()에서 사용
    2. 빈의 클래스 : 빈 오브젝트를 어떤 클래스를 이용해서 만들지를 정의
    3. 빈의 의존 오브젝트 : 빈의 생성자나 수정자 메소드를 통해 의존 오브젝트를 주입

connectionMaker() 전환

클래스 설정과 XML 설정의 대응항목

자바 코드 설정정보 XML 설정정보
빈 설정파일 @Configuration <beans>
빈의 이름 @Bean methodName() <bean id="methodName"
빈의 클래스 return new BeanClass(); class="a.b.c...BeanClass">
빈의 의존 오브젝트 없음 없음

class 프로퍼티에는 리턴타입이 아닌 메소드에서 오브젝트를 만들 때 사용하는 클래스 이름!

<!-- connectionMaker() { return new DConnectionMaker(); } -->
<bean id="connectionMaker" class="com.david.tobysspring.user.dao.DConnectionMaker" />

userDao() 전환

수정자 메소드 : 프로퍼티가 됨

  • name : 프로퍼티의 이름(수정자 메소드)
  • ref : 주입해 줄 오브젝트의 빈 이름(xml bean의 id)
<!-- 
    userDao() { 
        UserDao userDao = new UserDao();
        userDao.setConnectionMaker(connectionMaker());
        return userDao; 
    } 
-->
<bean id="userDao" class="com.david.tobysspring.user.dao.UserDao">
    <property name="connectionMaker" ref="connectionMaker" />
</bean>

XML의 의존관계 주입 정보

완성된 XML

<beans>
    <bean id="connectionMaker" class="com.david.tobysspring.user.dao.DConnectionMaker" />

    <bean id="userDao" class="com.david.tobysspring.user.dao.UserDao">
        <property name="connectionMaker" ref="connectionMaker" />
    </bean>
</beans>

XML DTD와 스키마

DTD 선언 (<beans> 엘리먼트 앞)

<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN 2.0//EN"  
    "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

스키마

<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">

1.8.2 XML을 이용하는 애플리케이션 컨텍스트

GenericXmlApplicationContext : XML에서 빈의 의존관계 정보를 이용하는 IoC/DI 작업

  • 생성자 파라미터로 XML 파일의 클래스패스를 지정해주면 된다.
  • XML 설정파일은 클래스패스 최상단에 위치하면 편리하다.
  • 기본적으로 스프링의 클래스패스는 src/main/resources이다.

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 
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="connectionMaker" class="com.david.tobysspring.user.dao.DConnectionMaker" />

    <bean id="userDao" class="com.david.tobysspring.user.dao.UserDao">
        <property name="connectionMaker" ref="connectionMaker" />
    </bean>
</beans>

UserDaoTest의 ApplicationContext 부분 수정

public class UserDaoTest {
    public static void main(String[] args) throws ClassNotFoundException, SQLException{
        ApplicationContext context = new GenericXmlApplicationContext("/applicationContext.xml");
    }
}

cf) ClassPathXmlApplicationContext
패키지명이 너무 길어서 귀찮을 경우, XML 파일과 같은 클래스패스에 있는 클래스 오브젝트를 넘겨서 클래스패스에 대한 힌트제공이 가능하다.
new ClassPathXmlApplicationContext("daoContent.xml", UserDao.class);
그러나, xml은 보통 resources 밑에 관리하므로 별로 쓸 일은 없을 듯 하다.

1.8.3 DataSource 인터페이스로 변환

DataSource 인터페이스 적용

ConnectionMaker : DB 커넥션을 생성해주는 하나의 기능만 가진 단순한 인터페이스
DataSource : Java에서 DB 커넥션을 가져오는 오브젝트의 기능을 추상화해서 만든 인터페이스

DataSource를 사용한 UserDao.class

public class UserDao {
    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void add(User user) throws ClassNotFoundException, SQLException {
        Connection c = dataSource.getConnection();
        //...
    }

    public User get(String id) throws ClassNotFoundException, SQLException {
        Connection c = dataSource.getConnection();
        //...
    }
}

SimpleDriverDataSource : 테스트 환경에서 간단히 사용할 수 있는 DataSource 구현 클래스

자바 코드 설정 방식

DaoFactory 설정 방식을 이용

  • 기존의 connectionMaker() 메소드를 dataSource()로 변경하고 SimpleDriverDataSource 오브젝트를 리턴
  • DaoFactory 지웠는데.....? 일단... 코드만 써보자... 어차피 XML로 바꿀꺼니까..

Daofactory.class

@Bean
public DataSource dataSource() {
    SimpleDriverDataSource dataSource = new SimpleDriverDataSource();

    dataSource.setDriverClass(oracle.jdbc.driver.OracleDriver);
    dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
    dataSource.setUsername("spring");
    dataSource.setPassword("book");

    return dataSource;
}

@Bean
public UserDao userDao() {
    UserDao dao = new UserDao();
    userDao.setDataSource(dataSource());
    return userDao;
}

테스트는 일단 패스...

XML 설정 방식

connectionMaker 빈 삭제 후 dataSource 빈을 등록

applicationContext.xml

<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource" />

DB 접속정보가 나타나 있지 않음

1.8.4 프로퍼티 값의 주입

값 주입

setDriverClass()

  • Class 오브젝트이긴 하지만 다른 빈 오브젝트를 DI 방식으로 가져와서 넣는 것은 아니다.
  • 단순 정보도 수정자 메소드에 넣을 수 있다.
  • 그러나 오브젝트 구현 클래스를 다이내믹하게 바꿀 수 있게 해 주는 것이 목적은 아니다.
  • 다만, 클래스 외부에서 변경 가능한 정보를 설정해줄수 있도록 만들기 위함
  • 이를 값을 주입한다고 말한다.
  • 수정자 메소드가 정의되어 있다면 <property>를 사용해 정보를 설정할 수 있다.
  • 단, 값을 주입하는 것이므로 value 애트리뷰트를 사용한다.
  • 방법은 동일하지만 수정자 메소드로 전달되는 것은 스트링 그 자체이다.

수정된 applicationContext.xml

<!-- 
    dataSource.setDriverClass(oracle.jdbc.driver.OracleDriver);
    dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
    dataSource.setUsername("spring");
    dataSource.setPassword("book");
-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
    <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>
    <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"></property>
    <property name="username" value="spring"></property>
    <property name="password" value="book"></property>
</bean>

value 값의 자동 변환

driverClass는 스트링 타입이 아니라 java.lang.Class 타입인데 텍스트 형태로 value에 들어가있다.

  • 스프링이 프로퍼티의 값을, 수정자 메소드의 파라미터 타입을 참고해서 적절한 형태로 변환시켜줌
  • oracle.jdbc.driver.OracleDriver -> oracle.jdbc.driver.OracleDriver.class
  • Integer, Double, String, Boolean, URL, File 등 다양한 타입으로 변경해 줌

문제점

JDBC가 정상 작동하지 않는다.
ojdbc6.jar를 properties에 추가하면 돌아가는데 maven으로 돌리면 오류 발생 ㅠ


' Spring > 토비의 스프링 3.1' 카테고리의 다른 글

1장. 오브젝트와 의존관계  (0) 2019.01.11
1.9 정리  (0) 2019.01.11
1.7 의존관계 주입(DI)  (0) 2019.01.10
1.6 싱글톤 레지스트리와 오브젝트 스코프  (0) 2019.01.09
1.5 스프링의 IoC  (0) 2019.01.07