이전 절에서는 리플랙션 API를 사용하여 프런트 컨트롤러를 개션하였다. 이제 페이지 컨트롤러를 추가하더라도 프런트 컨트롤러를 손댈 필요가 없어졌다. 하지만 ContextLoaderListener 클래스는 변경해야 한다. ContextLoaderListener 클래스에서 페이지 컨트롤러 객체를 생성하기 때문이다. ContextLoaderListener 클래스에서 페이지 컨트롤러를 생성하는 코드의 일부분이다.
@Override
public void contextInitialized(ServletContextEvent event) {
try {
...
//MemberDao 객체 준비하여 ServletContext에 보관
//MemberDao memberDao = new MemberDao();
MySqlMemberDao memberDao = new MySqlMemberDao();
memberDao.setDataSource(ds); //DAO에 DataSource 객체 주입
//sc.setAttribute("memberDao", memberDao); //memberDao 객체를 별도로 꺼내서 사용할 일 없기 때문에 ServletContext에 저장하지 않는다.
//페이지 컨트롤러 객체를 ServletContext에 저장시, 서블릿 요청 URL을 키값으로 하여 저장
sc.setAttribute("/auth/login.do", new LogInController().setMemberDao(memberDao));
sc.setAttribute("/auth/logout.do", new LogOutController());
sc.setAttribute("/member/list.do", new MemberListController().setMemberDao(memberDao));
sc.setAttribute("/member/add.do", new MemberAddController().setMemberDao(memberDao));
sc.setAttribute("/member/update.do", new MemberUpdateController().setMemberDao(memberDao));
sc.setAttribute("/member/delete.do", new MemberDeleteController().setMemberDao(memberDao));
} catch(Throwable e) {
e.printStackTrace();
}
}
페이지 컨트롤러뿐만 아니라 DAO를 추가하는 경우에도 ContextLoaderListener 클래스에 코드를 추가해야 한다.
이번 절의 목표는 바로 이 부분, 객체를 생성하고 의존 객체를 주입하는 부분을 자동화하는 것이다.
1. 실습 시나리오
웹 애플리케이션을 시작할 때 생성해야 할 객체가 있다면 프로퍼티 파일(application-context.properties)에 기록한다. ContextLoaderListener 클래스는 이 프로퍼티 파일의 정보를 읽고 객체를 생성한다(그림 1).
① 웹 애플리케이션이 시작되면 서블릿 컨테이너는 ContextLoaderListener 클래스의 contextInitialized() 메서드를 호출한다.
② contextInitialized() 메서드에서는 ApplicationContext 객체를 생성한다. 이 때 생성자에 프로퍼티 파일의 경로를 매개변수로 넘겨준다.
③ ApplicationContext 클래스는 프로퍼티 파일의 내용을 읽어들인다.
④ 프로퍼티 파일에 선언된 대로 객체를 생성하여 객체 테이블에 저장한다.
⑤ 객체 테이블에 저장된 각 객체에 대해 의존 객체를 찾아서 할당해준다.
시나리오 대로 실행된다면 페이지 컨트롤러나 DAO를 만들 때마다 더이상 ContextLoaderListener 클래스를 변경할 필요가 없게 된다.
2. 프로퍼티 파일 작성
생성할 객체에 대한 정보를 담고 있는 프로퍼티 파일을 만든다. webapp/WEN-INF 폴더에 application-context.properties 파일을 생성한다.
#1. for ApplicationContext.
jndi.dataSource=java:comp/env/jdbc/studydb
memberDao=spms.dao.MySqlMemberDao
/auth/login.do=spms.controls.LogInController
/auth/logout.do=spms.controls.LogOutController
/member/list.do=spms.controls.MemberListController
/member/add.do=spms.controls.MemberAddController
/member/update.do=spms.controls.MemberUpdateController
/member/delete.do=spms.controls.MemberDeleteController
앞에서 작성한 프로퍼티 파일은 ApplicationContext 클래스에서 객체를 준비할 때 사용한다. 객체의 종류에 따라 준비하는 방법이 다르므로 몇 가지 작성 규칙을 정의하였다. 물론 이 규칙은 현재 만드는 미니 프레임워크에만 해당한다.
- 톰캣 서버에서 제공하는 객체
DataSource 인터페이스처럼 톰캣 서버에서 제공하는 객체는 ApplicationContext 클래스에서 생성할 수 없다. 대신 InitialContext 클래스를 통해 해당 객체를 얻어야 한다. 다음은 이런 종류의 객체를 설정하는 규칙이다.
jndi.{객체이름}={JNDI이름}
프로퍼티의 키(key)는 'jndi.'와 객체 이름을 결합하여 작성한다. 프로퍼티의 값(value)은 톰캣 서버에 등록된 객체의 JNDI 이름이다. 앞의 프로퍼티 파일에서 첫 번째 줄의 내용이 톰캣 서버가 제공하는 DataSource 객체에 대한 것이다.
jndi.dataSource=java:comp/env/jdbc/studydb
이 DataSource 객체는 MemberDao(MySqlMemberDao)에 할당될 것이다.
- 일반 객체
MemberDao와 같은 일반 객체는 다음의 규칙으로 설정한다.
{객체이름}={패키지 이름을 포함한 클래스 이름}
프로퍼티의 키는 객체를 알아보는데 도움이 되는 이름을 사용한다. 단 다른 이름과 중복 되어서는 안 된다. 프로퍼티의 값은 패키지 이름을 포함한 전체 클래스 이름(fully qualified class name)이어야 한다. 앞의 프로퍼티 파일에서 두 번째 줄이 MemberDao를 설정하는 코드이다.
memberDao=spms.dao.MySqlMemberDao
- 페이지 컨트롤러 객체
페이지 컨트롤러는 프런트 컨트롤러에서 찾기 쉽도록 다음의 규칙으로 작성한다.
{서블릿 URL}={패키지 이름을 포함한 클래스 이름}
프로퍼티의 키는 서블릿 URL이다. 프런트 컨트롤러 'DispatcherServlet'은 서블릿 URL을 이용하여 페이지 컨트롤러를 찾는다.
/auth/login.do=spms.controls.LogInController
/auth/logout.do=spms.controls.LogOutController
/member/list.do=spms.controls.MemberListController
/member/add.do=spms.controls.MemberAddController
/member/update.do=spms.controls.MemberUpdateController
/member/delete.do=spms.controls.MemberDeleteController
참고도서 : https://freelec.co.kr/book/1674/
[열혈강의] 자바 웹 개발 워크북
[열혈강의] 자바 웹 개발 워크북
freelec.co.kr
'교재 실습 > 자바 웹 개발 워크북' 카테고리의 다른 글
91. 프로퍼티를 이용한 객체 관리 (3) (1) | 2022.08.11 |
---|---|
90. 프로퍼티를 이용한 객체 관리 (2) (0) | 2022.08.10 |
88. 리플랙션 API를 이용하여 프런트 컨트롤러 개선하기 (4) (0) | 2022.08.06 |
87. 리플랙션 API를 이용하여 프런트 컨트롤러 개선하기 (3) (0) | 2022.08.06 |
86. 리플랙션 API를 이용하여 프런트 컨트롤러 개선하기 (2) (0) | 2022.08.04 |
댓글