출처:스프링의 정석 : 남궁성 끝까지간다. 01. 원격프로그램의 실행
1.웹브라우저가 URL로 서버에 프로그램 실행을 요청한다.
2. 서버는 그 요청을 받고 톰캣이 인스턴스메서드를 객체생성시켜주고 실행해준다.
->이때 톰캣은 reflection api를 사용하여 인스턴스 메서드를 실행한다.
->reflection api는 클래스의 접근제어자가 private여도 접근할 수 있게 해줄 수 있고 메서드를 실행시키는 기능도 있다.
밑의 코드는 reflection API를 사용하는 예제이다.
Hello의 메소드가 private이지만
reflection api를 사용한다면 main클래스에서 실행할 수 있다.
package com.fastcampus.ch2v2;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
//1.원결 호출가능한 프로그램으로 등록
@Controller
public class Hello {
//2.url 과 메서드를 연결
//톰캣이 [/hello] url을 받으면 실행시켜준다는 의미이다.
//이때 메서드의 접근제어자와 상관없이 실행시켜준다. 그것을 해주는게 reflection API이다.
@RequestMapping("/hello")
private void main() { //main이 private라 외부에서 실행할 수 없을거라고 생각된다.
//하지만 reflection API를 사용하면 실행시킬수있다.
System.out.println("Hello-private");
}
}
package com.fastcampus.ch2v2;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws Exception {
Class helloClass = Class.forName("com.fastcampus.ch2v2.Hello");//class의 정보를 받아온다.
Hello hello = (Hello)helloClass.newInstance();
//class의 정보가 담긴 helloClass를 이용하여 객체생성을 한후 자료타입Hello인 변수 hello에
//참조시킨다.
Method main = helloClass.getDeclaredMethod("main");
//위의 설명과 같이 helloClass에는 "Hello"의 class 정보가 담겨있다. "Hello"의 메서드중 main을
//정보를 자료타입Method인 변수 main에 저장한다.
main.setAccessible(true);
//private의 main의 접근을 true로 변경한다.
main.invoke(hello);
//여기서 나는 굉장히 혼란스러웠다. 그냥 main.invoke실행하면 되지 왜 파라미터로 hello까지
//넣느지가 너무 이해가 안 갔다.
//하지만 이것은 오해이다.
//왜냐하면 main에는 Hello의 main메소드 정보가 담긴 것이다. 객체생성되어 있는 객체를 의미하는게 아니다.
//따라서 이렇게 생각하면 될것 같다.
//helo로 라는 객체 생성된 객체에
//main이라는 메서드정보와 같은 메서드를 실행해주세요.
}
}
'2022 > spring' 카테고리의 다른 글
[Thymeleaf] Th:field란 (0) | 2022.08.30 |
---|---|
[Thymeleaf] 왜 GetMapping("/board/new")에 빈 form을 보내는가? (0) | 2022.08.30 |