<aside> 💡
스프링 입장에서는 개발자가 어떤 메서드를 만들지 알 수 없고, 개발자가 메서드를 추가할 때 마다 스프링 코드를 수정해야 합니다. 그래서 동적으로 처리를 위해 리플렉션이 필요한 것입니다.
동적 분석을 할때 가장 쉬운 방법은 깃발(어노테이션)을 사용하는 것
</aside>


package ex04.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequestMapping {
String value(); // 어노테이션의 속성값 (value만 사용시 키값 생략 가능)
}
package ex04.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface RestController {
}
package ex04;
import ex04.anno.RequestMapping;
import ex04.anno.RestController;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class DispatcherServlet {
// IoC 컨테이너 = 제어의 역전
public List<Object> iocContainer = new ArrayList<>();
// 1.컴퍼넌트 스캔해서 ioc 컨테이너에 객체 추가
public void componentScan(String folder) throws Exception {
// 1. 패키지스캔
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL packageUrl = classLoader.getResource(folder);
File ex04Folder = new File(packageUrl.toURI());
File[] files = ex04Folder.listFiles(); // anno, App, BoardController, UserController
// 2. 찾은 것들을 new해서 컬렉션에 담아두기
for (File f : files){
//System.out.println(f.getName());
if(f.getName().endsWith(".class")){
String className = folder+"."+f.getName().replace(".class", ""); // ex04.BoardController, ex04.UserController
// ex04.BoardController, ex04.UserController, ex04.App
Class cls = Class.forName(className); // JVM 문자열로 클래스 로딩
//System.out.println(cls);
if(cls.isAnnotationPresent(RestController.class)){
System.out.println(cls);
Object instance = cls.newInstance();
iocContainer.add(instance);
}
}
}
}
// 2.컴퍼넌트 스캔 대상에서 메서드 찾기
public void findUri(String value){
for(Object instance : iocContainer){
Method[] methods = instance.getClass().getDeclaredMethods();
for (Method method : methods) {
RequestMapping rm = method.getDeclaredAnnotation(RequestMapping.class);
if(rm.value().equals(value)){
try {
method.invoke(instance);
break;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
package ex04;
import ex04.anno.RequestMapping;
import ex04.anno.RestController;
@RestController
public class BoardController {
@RequestMapping("/select")
public String select(){
System.out.println("select 호출됨");
return "apple";
}
@RequestMapping("/insert")
public void insert(){
System.out.println("insert 호출됨");
}
@RequestMapping(value = "/delete")
public void delete(){
System.out.println("delete 호출됨");
}
@RequestMapping(value = "/update")
public void update(){
System.out.println("update 호출됨");
}
}
package ex04;
import ex04.anno.RequestMapping;
import ex04.anno.RestController;
@RestController
public class UserController {
@RequestMapping("/login")
public void login(){
System.out.println("login 호출됨");
}
}
package ex04;
public class App {
public static void main(String[] args) throws Exception {
// 1. 키보드 입력자리
String uri = "/reply/write";
// 2. 컴퍼넌트 스캔
DispatcherServlet ds = new DispatcherServlet();
ds.componentScan("ex04");
// 3. 메서드 호출
ds.findUri(uri);
}
}
<aside> 💡
프레임워크 = 틀+일하다
스프링 = 봄이 왔다!!
신입 좋고, 관리자 좋고!!
</aside>

package com.example.v4;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class BoardController {
@GetMapping("/insert")
public String insert() {
System.out.println("insert 호출됨");
return "apple";
}
@GetMapping("/delete")
public void delete() {
System.out.println("delete 호출됨");
}
@GetMapping("/update")
public void update() {
System.out.println("update 호출됨");
}
}