ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 1장) 1.8 XML을 이용한 설정 ~ 1.9 정리
    Java & Spring/토비의 스프링 3.1 2021. 5. 27. 13:50
    반응형

    1장 오브젝트와 의존관계

    1.8 XML을 이용한 설정

    • 장점

      • 별도의 빌드 작업이 필요 없다
      • 환경이 달라져서 오브젝트의 관계가 바뀌는 경우, 빠르게 변경사항 반영 가능
    • XML 설정

      • DI 정보가 담긴 XML 파일은 <beans>를 루트 엘리먼트로 사용
      • @Configuration과 @Bean이 붙은 자바 클래스로 만든 설정과 내용이 동일
      • @Bean의 DI 정보 3가지
        • 빈의 이름
          • @Bean 메소드 이름 (getBean()에서 사용됨)
        • 빈의 클래스
          • 빈 오브젝트를 어떤 클래스를 이용해서 만들지 정의
        • 빈의 의존 오브젝트
          • 생성자나 수정자 메소드를 통해 의존 오브잭트를 주입
          • 의존 오브젝트는 하나 이상일 수 있음
    • connecitonMaker() 전환

      • 자바 코드 설정 정보 XML 설정 정보
        빈 설정 파일 @Configuration <beans>
        빈 이름 @Bean methodName() <bean id ="methodName"
        빈 클래스 return new BeanClass(); class="a.b.c... BeanClass">
      • class 애트리뷰트 설정 -> 오브젝트를 만들 때 사용하는 클래스 이름(return 타입 지정 X

      • @Bean                                    // <bean
        public ConnectionMaker 
        connectionMaker() {                        // id="connectionMaker"
            return new DConnectionMaker();        // class="springbook...DConnectionMaker />"
        }
    • userDao() 전환

      • 스프링 개발자가 수정자 메소드를 사용해 의존관계를 주입하는 것을 선호하는 이유는 XML로 의존관계 정보를 만들 때 편리하기 때문

      • 자바빈의 관례에 따라 수정자 메소드는 프로퍼티가 되고, 프로퍼티 이름은 메소드 이름에서 set을 제외한 나머지 부분을 사용

      • <property> 에는 name과 ref 두 개의 애트리뷰트가 있다

        • name
          • 프로퍼티의 이름
        • ref
          • 주입해줄 오브젝트의 빈 이름
      • userDao.setConnectionMaker(connectionMaker());
        
        <bean id="userDao" class="springbook.dao.UserDao">
            <property name="connectionMaker" ref="connectionMaker" />
        </bean>
        • 의존 관계 정보를 주입하는 코드 레벨을 xml로 변환하면 위와 같이 변경된다.
    • XML의 의존관계 주입 정보

      • <bean>으로 등록한 태그들을 <beans> 태그로 감싸주면 XML로의 전환 작업이 끝난다.

      • 보통 프로퍼티 이름과 DI 되는 빈의 이름이 같은 경우가 많음

      • 바뀔 수 있는 클래스 이름보다는 대표적인 인터페이스 이름을 따르는 것이 자연스럽지만, 의미를 좀 더 잘 드러낼 수 있거나 같은 이름이 중복된다면 다르게 정해도 상관 없다.

      • <beans>
            <bean id="localDBConnectionMaker" class="...LocalDBConnectionMaker" />
            <bean id="localDBConnectionMaker" class="...LocalDBConnectionMaker" />
            <bean id="localDBConnectionMaker" class="...LocalDBConnectionMaker" />
        
            <bean id="userDao" class="springbook.dao.UserDao">
                <property name="connectionMaker" ref="localDBConnectionMaker" />
            </bean>
        </beans>
        • 이름이 중복되는 경우 & DI하는게 여러 개인 경우 위와 같이 설정해두고, running 환경에 따라 바꿔서 사용하는 경우가 더러 있음
    • XML을 이용하는 Application Context

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

        • 생성자 파라미터로 XML 파일의 클래스패스를 지정해주면 됨
        • 클래스패스는 루트부터 시작하므로 /를 생략해도 됨
      • ClassPathXmlApplicationContext

        • 클래스패스가 루트부터 시작하기 때문에, 경로가 길어지는 경우 실수할 확률도 있고 귀찮다..

        • 같은 위치에 있는 클래스 파일을 인자로 넘기면, 알아서 class path를 찾아준다.

        • new GenericXmlApplicationContext("springbook/user/dao/daoContext.xml");
          new ClassPathXmlApplicationContext("daoContext.xml", UserDao.class);
        • 위의 방법으로 클래스를 지정할 경우가 아니라면 GenericXmlApplicationContext를 사용하는 것이 좋다

    • DataSource 인터페이스로 변환

      • 앞서 구현한 ConntionMaker처럼 일반적으로 DataSource를 구현해서 DB 커넥션을 제공하는 클래스를 만들 일은 거의 없다.

        • 이미 좋은 인터페이스 & 클래스가 제공되기 때문
      • DataSource 인터페이스에서 실제 관심을 가질 것은 getConntion() 메소드 하나 뿐

      • UserDao를 DataSource를 이용하도록 수정해보자

      • import javax.sql.DataSource;
        
        public class UserDao {
            private DataSource dataSource;
        
            public void setDataSource(DataSource dataSource) {
                this.dataSource = dataSource;
            }
        
            public void add(User user) throws SQLException {
                Connection connection = dataSource.getConnection();
                // logic..
            }
        }
      • DataSrouce는 인터페이스기 때문에 구현 클래스가 필요한데, 테스트환경에서 간단히 사용할 수 있는 SimpleDriverDataSource를 사용하자

        • @Bean
          public DataSource dataSource() {
              SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
          
              datasource.setDriverClass(com.mysql.jdbc.Driver.class);
              dataSource.setUrl("jdbc:mysql://localhost/springbook");
              dataSource.setUserName("spring");
              dataSource.setPassword("book");
          
              return dataSource;
          }
      • 위와 같이 제공되고 있는 인터페이스와 클래스를 이용해서 더욱 쉽고 빠르게 connection을 리턴을 빠르게 개발할 수 있다.

    • 프로퍼티 값의 주입

      • 위의 코드를 XML로 변환할 때, 빈 등록을 해주면서 어떻게 오브젝트 레퍼런스가 아닌 단순 값을 주입할 수 있을까?

        • value 애트리뷰트를 사용하면 쉽게 값이 주입된다.

        • <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
              <property name="dirverClass" value="com.mysql.jdbc.Driver" />
              <property name="url" value="jdbc:mysql://localhost/springbook" />
              <property name="username" value="spring" />
              <property name="password" value="book" />
          </bean>
        • 여기서 driverClass 값을 주입하는데, 스트링 타입으로 설정해서 어떻게 주입되는지 궁금할 수 있다.

        • 스프링이 프로퍼티의 값을 수정자 메소드의 파라미터 타입을 참고해서 적절한 형태로 변환해주기 때문에 가능하다.

        • Class driverClass = Class.forName("com.mysql.jdbc.Driver");
          dataSource.setDriverClass(driverClass);
          • 내부적으로 위와 같이 변환 작업이 일어난다고 생각하면 된다.

    1.9 정리

    • 스프링이란 어떻게 오브젝트가 설계뙤고, 만들어지고, 관계를 맺고 사용되는지에 관심을 같는 프레임워크 라는 사실이 가장 중요
      • 어떻게 설계하고 분리하고, 개선하고, 의존관계를 가질지는 개발자의 몫이고, 스프링은 도구일 뿐
    • 1장에서 진행한 내용 간략한 정리
      • 책임이 다른 코드 분리
      • 전략패턴
        • 바뀔 수 있는 쪽의 클래스를 인터페이스로 구현하고, 다른 클래스에서 인터페이스를 통해서만 접근하도록 설정 ~> 구현 클래스에 변경이 일어나도 인터페이스 및 다른 구현 클래스의 변경X
      • 개방 폐쇄 원칙
        • 자신의 책임 자체가 변경되는 경우 외에는 불필요한 변화가 발생하지 않게 하고, 자유롭게 확장 및 변경할 수 있도록 설정
      • 낮은 결합도 & 높은 응집도
      • 제어의 역전(IoC)
        • IoC컨테이너로 넘겨서 오브젝트가 자신이 사용할 대상의 생성이나 선택에 관한 책임으로부터 자유롭게 설정
      • 싱글톤 레지스트리
        • 전통 싱글톤 패턴의 단점을 극복하며 장점을 살리도록 설계된 컨테이너를 활용
      • 의존관계 주입(DI)
        • 설계 시점과 코드에는 느슨한 의존관계 설정, 런타임시에 제3자인 DI 컨테이너를 통해 주입받아 의존관계를 설정
      • 생성자 주입과 수정자 주입
      • XML 설정
        • DI 설정정보와 의존 오브젝트가 아닌 일반 값을 외부에서 설정해서 런타인시에 주입하는 XML 설정 방법을 학습

    용어 정리

    • DTD와 스키마

      • XML 문서는 미리 정해진 구조를 따라 작성됐는지 검사할 수 있음

        • 구조를 정의하는 방법에는 DTD와 스키마(schema)가 있음
      • 스프링은 기본 태그인 <beans>, <bean> 외에도 특별 목적의 태그를 사용하는 방법을 제공

        • 이 태그들은 스키마(schema)에 정의되어 있기 때문에, 이런 기능을 사용하기 위해서는 DTD가 아닌 네임스페이스가 지원되는 스키마를 사용해야함
      • <!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/XMLScheam-instance"
               xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
      • 특별한 이유가 없다면 길더라도 DTD 보다는 스키마를 사용하는 것이 바람직 하다

    반응형

    댓글

Designed by Tistory.