@WebServlet("/")
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private String envFileName = "control.properties";
private Properties env;
public DispatcherServlet() {
super();
}
@Override
public void init() throws ServletException {
super.init();
env = new Properties();
ServletContext sc = this.getServletContext();
// 여기까지 서블릿 context 찾는 객체
String realPath = sc.getRealPath("WEB-INF\\classes\\com\\my\\env\\" + envFileName);
System.out.println("in DispatcherServlet의 init(): realPath=" + realPath);
try {
env.load(new FileInputStream(realPath)); // 의존성 주입
// env.getProperty(key); // cf)key에 해당하는 value 꺼내오는 메소드
} catch (IOException e) {
e.printStackTrace();
}
}
// 기존 Servlet 다 없애고 DispatcherServlet 혼자서 모든 요청을 처리하도록 수정할 것
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 여기에 넣으면 다른 controller에 이거 다 빼줘도 됨. 코드의 중복 막음. 응답형식은 놔둠.
response.setHeader("Access-Control-Allow-Origin", "http://192.168.1.19:5500");
response.setHeader("Access-Control-Allow-Credentials", "true");
System.out.println("request.getServletPath()=" + request.getServletPath());
// URL 매핑에 따라 properties파일로 dispatcherServlet에서 활용할 것
/*
* if(request.getServletPath().equals("/productjson")) { ProductJsonController
* control = new ProductJsonController(); control.execute(request, response); }
* else if(request.getServletPath().equals("/productlistjson")) {
* ProductListJsonController control = new ProductListJsonController();
* control.execute(request, response); }
*/
String className = env.getProperty(request.getServletPath());
System.out.println(className);
try {
Class clazz = Class.forName(className); // 클래스이름에 해당하는 .class파일 찾아서 JVM으로 로드
// clazz.newInstance();//객체생성작업 아래꺼 사용
// Object가 반환인데 controller로 다운캐스팅
Controller controller = (Controller) clazz.getDeclaredConstructor().newInstance();
// 인터페이스를 구현한 실제 생성된 객체 controller의 오버라이딩된 execute 메서드가 호출
controller.execute(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
// controller 조차 싱글톤으로 만드는 메서드
protected void service2(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("request.getServletPath()=" + request.getServletPath());
// /signup --> SignupController클래스 찾기 -> 객체생성 -> 객체의 재정의된 execute() 호출
// /login --> LoginController클래스 찾기 -> 객체생성 -> 객체의 재정의된 execute() 호출
// /a --> Acontroller
// if(request.getServletPath().equals("/signup")) {
// else if 리플랙션 기술이 없으면 a라는 컨트롤러가 추가되면 else if가 하나 더 추가되어야함
// else if 서비스를 새로 배포도 다시 해야함. 배포 하루종일 걸리고 아무도 못씀
// 리플랙션을 쓰면 객체지향의 기능을 담고있는 것부터 만들면 재사용성을 높일 수 있다. 결합도를 떨어뜨릴 수 있다.
// 주입된 클래스를 Reflection 기법으로 찾아 실행
String className = env.getProperty(request.getServletPath());
try {
Class<?> clazz = Class.forName(className);// 클래스이름에 해당하는 .class파일 찾아서 JVM으로 로드
Controller controller;
try {
Method method = clazz.getMethod("getInstance");
controller = (Controller) method.invoke(null);// static인 getInstance()메서드호출. Controller로 다운캐스팅함. 결합도를
// 떨어뜨린다.
// constroller = (SignupController) method.invoke(null); 이렇게 쓰면 login할때는 다른 변수를
// 선언해야해서
// 일반화된 인터페이스로 다운캐스팅. 구체화된 클래스 타입으로는 안한다
// dispatcherServlet에서 사용할 클래스를 자기가 결정하지 않고 외부파일(control.properties)에서 결정해서 주입
// -> 의존성 주입(dependency injection)
} catch (NoSuchMethodException e) {
controller = (Controller) clazz.getDeclaredConstructor().newInstance();
} // getInstance 있으면 호출받고 아니면 객체생성해서 얻어와라
String path = controller.execute(request, response);
if (path != null) { // jsp로 한다하면
RequestDispatcher rd = request.getRequestDispatcher(path);
rd.forward(request, response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
리플랙션 기술을 통해 위에서 아래의 코드블럭 부분으로
/signup --> SignupController클래스 찾기 -> 객체생성 -> 객체의 재정의된 execute() 호출
/login --> LoginController클래스 찾기 -> 객체생성 -> 객체의 재정의된 execute() 호출
위의 주석처리한 과정 처리 가능. 재사용성을 높인 것
String className = env.getProperty(request.getServletPath());
try {
Class<?> clazz = Class.forName(className);
Controller controller;
try {
Method method = clazz.getMethod("getInstance");
controller = (Controller) method.invoke(null);
} catch (NoSuchMethodException e) {
controller = (Controller) clazz.getDeclaredConstructor().newInstance();
}
String path = controller.execute(request, response);
if (path != null) {
RequestDispatcher rd = request.getRequestDispatcher(path);
rd.forward(request, response);
}
} catch (Exception e) {
e.printStackTrace();
}
* 의존성 주입
dispatcherServlet에서 사용할 클래스를 자기가 결정하지 않고 외부파일(control.properties)에서 결정해서 주입
-> 의존성 주입(dependency injection)
@Override
public void init() throws ServletException {
super.init();
env = new Properties();
ServletContext sc = this.getServletContext();
// 여기까지 서블릿 context 찾는 객체
String realPath = sc.getRealPath("WEB-INF\\classes\\com\\my\\env\\" + envFileName);
System.out.println("in DispatcherServlet의 init(): realPath=" + realPath);
try {
env.load(new FileInputStream(realPath)); // 의존성 주입
// env.getProperty(key); // cf)key에 해당하는 value 꺼내오는 메소드
} catch (IOException e) {
e.printStackTrace();
}
}
'프레임워크 > Spring' 카테고리의 다른 글
라이브러리 dependency로 추가하고 setting 하기 (0) | 2023.10.24 |
---|---|
Maven Project 생성 (0) | 2023.10.24 |
web module version (0) | 2023.10.24 |
Filter (0) | 2023.10.24 |
Listener (0) | 2023.10.24 |