✅ 스프링 IoC 컨테이너가 관리할 Bean 설정
지금까지 DaoFactory
를 통해서 의존관게를 설정할 수 있었습니다. 자바 클래스로써 @Configuration 어노테이션을 사용해서 스프링 IoC 컨테이너가 해당 설정 정보를 참고하여 Bean 객체를 생성하고, 컴파일 시에 의존관계를 설정할 수 있습니다. 스프링에서는 자바 클래스 외에도 XML 방식을 통해서 의존관계를 설정할 수도 있습니다.
—@Configuration 어노테이션을 통해서 설정한 @Bean 메소드를 통해 얻는 정보는 아래와 같다.
- 빈의 이름 : @Bean 메소드의 이름, 곧 빈의 이름이 된다. getBean() 메소드를 통해 반환받을 객체를 찾을 때 key로 사용된다.
- 빈의 클래스 : 빈 객체를 어떤 클래스로 이용하여 만들지를 정의한다.
- 빈의 의존 오브젝트 주입 : 빈의 생성자나 수정자 메소드를 통해서 서로 의존 관계에 있는 객체를 주입한다.
✅ ApplicationContext.xml
xml 파일을 사용해서 ApplicationContext에 빈을 등록하고 사용하려면 어떻게 해야할까요? ApplicationContext
컨테이너가 사용하는 설정 정보를 등록하는 applicactionContext.xml을 생성합니다. 관례에 따라 위와 같은 이름으로 작명되고 클래스패스 최상단에 위하도록 합니다. src 폴더에 해당 xml 파일을 생성하였습니다.
- DaoFactory의 connectionMaker() XML 등록
자바 클래스에서 작성한 메소드의 이름이 XML 설정에서는 <bean id= “”>에 해당하는 부분에 들어가게 된다. 메소드에서 반환받은 객체가 XML 설정에서는 빈의 클래스, 즉 어떤 클래스를 사용하여 객체를 생성할 것인지 결정하는 부분인 <class= “”> 부분이 된다. 주의해야 할 것은 클래스의 패키지 이름까지 모두 정확하게 적어야 한다는 점이다.
- DaoFactory
@Bean //==> <bean public ConnectionMaker connectionMaker() { //==> id="connectionMaker" ConnectionMaker connectionMaker = new DConnectionMaker(); //==> com.jhcode.spring.ch1.dao.DConnectionMaker return connectionMaker; }
@Configuration 어노테이션을 사용해서 클래스로 등록했던 정보들이 주석과 같이 바뀌게 됩니다. 각각 메소드의 이름은 id로, 생성되는 객체는 패키지명까지 정확하게 적은 클래스로 입력됩니다. 아래에서 어떻게 설정되는지 확인해보겠습니다.
- applicationContext.xml
<bean id="connectionMaker" class="com.jhcode.spring.ch1.dao.DConnectionMaker"></bean>
.xml을 통해 connectionMaker을 id로 가지는
DConnectionMaker
클래스를 빈으로 등록시켰습니다. id는 애플리케이션 컨텍스트를 호출하여 빈 객체를 찾을 때 사용됩니다.
- DaoFactory
- DaoFactory의 userDao() XML 등록
UserDao
는 수정자(Setter)을 사용해서 의존 관계를 주입 받고 있습니다. 이를 XML에서는 어떻게 설정하는지 알아보겠습니다- DaoFactory
@Bean public UserDao userDao() { ConnectionMaker connectionMaker = new DConnectionMaker(); UserDao userDao = new UserDao(); userDao.setConnectionMaker(connectionMaker); //.xml==> <property name="connectionMaker" ref="connectionMaker"/> return userDao; }
- applicationContext.xml
<bean id="userDao" class="com.jhcode.spring.ch1.dao.UserDao"> <property name="connectionMaker" ref="connectionMaker" /> </bean>
property 설정을 추가함으로써 setter을 통해 의존 관계를 주입 받는 것을 표현할 수 있습니다. <bean>의 id에 해당하는 메소드를 통해 반환 될 객체가 필요한 의존 관계를, applicationContext에 등록되어 있는 <bean>의 id를 ref으로 찾아 해당 id를 통해 반환 되는 객체를 참조하여 의존 관계를 설정해주는 속성입니다.
name 어트리뷰트는 DI에서 사용할 수정자 메소드의 이름입니다. 자바 코드 설정에서는
setConnectionMaker
에 해당합니다.프로퍼티의 이름이나 빈의 이름을 인터페이스의 이름과 다르게 설정하기도 합니다. 같은 이름이 중복되거나, 의미를 조금 더 잘 들어내는 이름으로 변경하기도 하는데, 이름을 변경하면 참조하는 빈의 이름도 바꿔주어야 하기 때문에 설계 단계에서 명명 규칙을 잘 정해주는 것이 매우 중요합니다.
- myConnectionMaker
<bean id="myConnectionMaker" class="com.jhcode.spring.ch1.dao.DConnectionMaker"></bean> <bean id="userDao" class="com.jhcode.spring.ch1.dao.UserDao"> <property name="connectionMaker" ref="myConnectionMaker" /> </bean>
UserDao
빈은, <property> 속성을 통해 myConnectionMaker의 이름으로 xml에 id로 등록되어있는 빈을 주입받아 의존관계를 설정하게 됩니다.
- 같은 인터페이스 타입을 여러 개 정의한 경우, 예시
<beans> <bean id="localDBConnectionMaker" class="..localDBConnectionMaker" /> <bean id="testDBConnectionMaker" class="..testDBConnectionMaker" /> <bean id="productionDBConnectionMaker" class="..productionDBConnectionMaker" /> <bean id="userDao" class="springbook.user.dao.UserDao"> <property name="connetionMaker" ref="localDBConnectionMaker" /> </bean> </beans>
#해당 메소드는 존재하지 않는다. 예시를 위해 작성되었다.
userDao는 Setter을 사용해서
ConnectionMaker
을 주입받고 있습니다. 여러 개의ConnectionMaker
구현 클래스를 Bean으로 등록해두고 각각의 용도에 따라 ref를 변경하여 선택하여 사용할 수 있습니다.
- myConnectionMaker
- DaoFactory
- GenericXmlApplicationContext Test
지금까지 만든 ApplicationContext.xml이 제대로 동작하는지 테스트 해보겠습니다.
- 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-3.0.xsd"> <bean id="myConnectionMaker" class="com.jhcode.spring.ch1.dao.DConnectionMaker"> <property name="driverClass" value="org.mariadb.jdbc.Driver" /> <property name="url" value="jdbc:mariadb://localhost:3306/toby_study?characterEncoding=UTF-8" /> <property name="username" value="root" /> <property name="password" value="1234" /> </bean> <bean id="userDao" class="com.jhcode.spring.ch1.dao.UserDao"> <property name="connectionMaker" ref="myConnectionMaker" /> </bean> </beans>
- UserDaoTest
public class UserDaoTest { public static void main(String[] args) throws ClassNotFoundException, SQLException { ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml"); UserDao dao = context.getBean("userDao", UserDao.class);
GenericXmlApplicationContext는 ApplicationContext의 구현체로 Xml 설정 정보를 읽어올 때 사용하는 객체입니다.
- applicationContext.xml 전체코드
✅ DataSource 인터페이스
DB 커넥션을 생성하기 위해서 DaoFactory를 만들고, IoC/DI 를 적용 시키면서 학습하였습니다. 그러나 DB 커넥션을 가져오는 많은 인터페이스와 구현체가 DB연결과 풀링 기능 등을 갖추어 이미 준비되어있기 때문에 사실 그것들을 잘 사용하기만 하면 됩니다.
- DataSource 인터페이스
import java.sql.Connection; import java.sql.SQLException; import java.sql.Wrapper; import javax.sql.CommonDataSource; public interface DataSource extends CommonDataSource, Wrapper { Connection getConnection() throws SQLException; //...생략 }
spring에서 제공하는 DataSource 인터페이스입니다. 여러 기능들이 있고, 이것을 구현한 여러 클래스가 존재하지만 간단하게 SimpleDataSource를 사용해서
UserDao
를 변경해보겠습니다.
- UserDao
public class UserDao { //== DataSource 사용하기 ==// private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public void add(User user) throws ClassNotFoundException, SQLException{ Connection con = dataSource.getConnection();
DataSource
를 사용하여UserDao
에 적용한 코드입니다다. 기존에ConnectionMaker
를 통하여 DB 커넥션을 직접 생성하고getConnection()
메소드를 통해서 반환 받았던 것을 스프링에서 제공해주는DataSource
객체를 통하여 반환 받을 수 있습니다. 그렇다면 DB 연결 정보는 어떻게 해야 할까요?
- SimpleDataSource
spring에서 제공하는
DataSource
의 구현 클래스인SimpleDataSource
를 사용하기 위해선 의존성을 추가해주어야 합니다.- pom.xml → spring jdbc 의존성 추가
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.24</version> </dependency>
- DaoFactory
package com.jhcode.spring.ch1.dao; import javax.sql.DataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.SimpleDriverDataSource; @Configuration public class DaoFactory { @Bean public UserDao userDao() { UserDao userDao = new UserDao(); userDao.setDataSource(dataSource()); return userDao; } @Bean public DataSource dataSource() { SimpleDriverDataSource dataSource = new SimpleDriverDataSource(); String url = "jdbc:mariadb://localhost:3306/toby_study?characterEncoding=UTF-8"; String username = "root"; String password = "1234"; dataSource.setDriverClass(org.mariadb.jdbc.Driver.class); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } }
Setter을 사용해서 DB 연결 정보를 주입하고,
DataSource
객체를 반환 받아 UserDao가 사용할 수 있게 만들었습니다. 이렇게 해서 DI를 사용할 수 있습니다.
- pom.xml → spring jdbc 의존성 추가
- DataSource를 XML로 변경하기
DataSource를 XML 설정 방식으로 변경하려면 어떻게 해야할까요?
<bean id="dataSource" class="org.springFramework.jdbc.datasource.SimpleDriverDataSource"> <property name="driverClass" value="org.mariadb.jdbc.Driver" /> <property name="url" value="jdbc:mariadb://localhost:3306/toby_study?characterEncoding=UTF-8" /> <property name="username" value="root" /> <property name="password" value="1234" /> </bean>
기존에 Setter을 사용해서 값을 넣었던 것처럼, XML 에서는 value=”” 속성을 이용하여 값을 넣어주면 됩니다. 한가지 특이한 점은 값을 모두 스트링 타입으로 넣어주는데 DiverClass는 사용하고자 하는 클래스의 타입(.class)가 들어가야한다는 점입니다. 이는 스프링에서 수정자 메소드의 파라미터 타입을 참고해서 적절한 형태로 변환해주기 때문에 가능합니다.
프로젝트 환경
- IDE : STS3 - 3.9.18.RELEASE
- SpringFramework : 5.3.20
- Java : 11
- Maven
📖토비 스프링 3.1 -p128~142
Uploaded by N2T