-
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()에서 사용됨)
- 빈의 클래스
- 빈 오브젝트를 어떤 클래스를 이용해서 만들지 정의
- 빈의 의존 오브젝트
- 생성자나 수정자 메소드를 통해 의존 오브잭트를 주입
- 의존 오브젝트는 하나 이상일 수 있음
- 빈의 이름
- DI 정보가 담긴 XML 파일은
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
- 주입해줄 오브젝트의 빈 이름
- name
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 보다는 스키마를 사용하는 것이 바람직 하다
반응형'Java & Spring > 토비의 스프링 3.1' 카테고리의 다른 글
2장) 2.3 개발자를 위한 테스팅 프레임워크 JUnit (0) 2021.06.01 2장) 2.1 USERDAOTEST 다시보기 ~ 2.2 USERDAOTEST 개선 (0) 2021.05.27 1장) 1.6 싱글톤 레지스트리와 오브젝트 스코프 ~ 1.7 의존관계 주입(IoC) (2) 2021.05.21 1장) 1.3 DAO의 확장 ~ 1.5 스프링의 IoC (1) 2021.05.17 1장 오브젝트와 의존관계 (1.1 초난감 DAO ~ 1.2 DAO의 분리) (1) 2021.05.13