Contents
실습 5. 컴포넌트 스캔(Component Scan)실습 5. 컴포넌트 스캔(Component Scan)
[참고] 컴포넌트 스캔이란?
- 패키지를 분석하는 기술
- 패키지 경로를 기준으로
.class파일을 찾고 리플렉션으로 클래스 메타데이터 분석
→ 어노테이션(깃발) 달린 클래스 찾음
→ 객체를 생성하여 Spring 컨테이너가 관리하도록 등록
- 목표 : RestController(어노테이션) 붙어 있는 클래스를 new 하는 것!
※ 스캔 기준 :
@Component 계열 전체 ⭕@RestController : @RestController =@Controller +@ResponseBody@Controller : @Controller ⊂ @Component1) RestController
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 {
}2) RequestMapping
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) // 동작 시점(컴파일 source? 실행시점 runtime?)
@Target(ElementType.METHOD) // 위치 : 메서드 위
public @interface RequestMapping {
String value(); // 어노테이션의 속성값(value라는 이름 사용 시에만 생략 가능)
}3) BoardController
package ex04;
import ex04.anno.RequestMapping;
import ex04.anno.RestController;
@RestController
public class BoardController {
@RequestMapping("/insert")
public void insert(){
System.out.println("insert 호출됨");
}
@RequestMapping("/delete")
public void delete(){
System.out.println("delete 호출됨");
}
@RequestMapping("/update")
public void update(){
System.out.println("update 호출됨");
}
@RequestMapping("/select")
public String select1(){
System.out.println("select 호출됨");
return "apple";
}
}4) UserController
user 정보를 관리하는 메서드가 있을 경우 해당 컨트롤러에서 메서드 관리
package ex04;
public class UserController {
}
5) App (main) (기초)
package ex04;
import ex04.anno.RequestMapping;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Scanner;
public class App {
static void findUri(String uri) {
// 3. 동적 클래스 분석
Method[] methods = BoardController.class.getDeclaredMethods();
for (Method m : methods) {
RequestMapping rm = m.getDeclaredAnnotation(RequestMapping.class);
if (rm.value().equals(uri)) {
try {
Object res = m.invoke(null);
System.out.println("응답 버퍼 : " + res);
} catch (Exception e) {
e.printStackTrace(); // 피범벅
}
}
}
}
public static void main(String[] args) throws URISyntaxException {
// 1. 키보드 입력 자리
String uri = "/insert";
// 2. 패키지 스캔
ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // java 폴더 찾는 함수(문법) ref > out > production > classes 폴더
URL packageUrl = classLoader.getResource("ex04"); // java 폴더에 있는 'ex04' 찾는 것 (문법)
File ex04Folder = new File(packageUrl.toURI()); // 폴더를 파일 객체로 받은 이유는 윈도우는 모든 것을 파일로 구분함 (문법)
File[] files = ex04Folder.listFiles(); // 해당 폴더의 파일을 리스트에 담음(문법) anno, App, BoardController, UserController
// 3. 찾은 것 검증
for (File f : files) {
System.out.println(f.getName());
}
}
}5-1) 결과

2) 찾은 것들 중 class 찾기
package ex04;
import ex04.anno.RequestMapping;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Scanner;
public class App {
static void findUri(String uri) {
// 3. 동적 클래스 분석
Method[] methods = BoardController.class.getDeclaredMethods();
for (Method m : methods) {
RequestMapping rm = m.getDeclaredAnnotation(RequestMapping.class);
if (rm.value().equals(uri)) {
try {
Object res = m.invoke(null);
System.out.println("응답 버퍼 : " + res);
} catch (Exception e) {
e.printStackTrace(); // 피범벅
}
}
}
}
public static void main(String[] args) throws URISyntaxException, ClassNotFoundException {
// 1. 키보드 입력 자리
String uri = "/insert";
// 2. 패키지 스캔
ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // java 폴더 찾는 함수(문법) ref > out > production > classes 폴더
URL packageUrl = classLoader.getResource("ex04"); // java 폴더에 있는 'ex04' 찾는 것 (문법)
File ex04Folder = new File(packageUrl.toURI()); // 폴더를 파일 객체로 받은 이유는 윈도우는 모든 것을 파일로 구분함 (문법)
File[] files = ex04Folder.listFiles(); // 해당 폴더의 파일을 리스트에 담음(문법) anno, App, BoardController, UserController
// 3. 찾은 것 검증
for (File f : files) {
// System.out.println(f.getName());
if(f.getName().endsWith(".class")) {
String className = "ex04."+f.getName().replace(".class", ""); // ex04.BoardController, ex04.UserController
Class cls = Class.forName(className); // JVM이 문자열로 클래스 로딩하는 것
System.out.println(cls);
}
}
}
}
3) 어노테이션 달린 클래스 찾기
package ex04;
import ex04.anno.RequestMapping;
import ex04.anno.RestController;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Scanner;
public class App {
static void findUri(String uri) {
// 3. 동적 클래스 분석
Method[] methods = BoardController.class.getDeclaredMethods();
for (Method m : methods) {
RequestMapping rm = m.getDeclaredAnnotation(RequestMapping.class);
if (rm.value().equals(uri)) {
try {
Object res = m.invoke(null);
System.out.println("응답 버퍼 : " + res);
} catch (Exception e) {
e.printStackTrace(); // 피범벅
}
}
}
}
public static void main(String[] args) throws URISyntaxException, ClassNotFoundException {
// 1. 키보드 입력 자리
String uri = "/insert";
// 2. 패키지 스캔
ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // java 폴더 찾는 함수(문법) ref > out > production > classes 폴더
URL packageUrl = classLoader.getResource("ex04"); // java 폴더에 있는 'ex04' 찾는 것 (문법)
File ex04Folder = new File(packageUrl.toURI()); // 폴더를 파일 객체로 받은 이유는 윈도우는 모든 것을 파일로 구분함 (문법)
File[] files = ex04Folder.listFiles(); // 해당 폴더의 파일을 리스트에 담음(문법) anno, App, BoardController, UserController
// 3. 찾은 것 검증
for (File f : files) {
// System.out.println(f.getName());
if(f.getName().endsWith(".class")) {
String className = "ex04."+f.getName().replace(".class", ""); // ex04.BoardController, ex04.UserController
Class cls = Class.forName(className); // JVM이 문자열로 클래스 로딩하는 것
// System.out.println(cls);
// 어노테이션 분석해서 담기
if (cls.isAnnotationPresent(RestController.class)) {
System.out.println(cls);
}
}
}
}
}
4) 찾은 것들을 new해서 컬렉션에 담기
package ex04;
import ex04.anno.RestController;
@RestController
public class UserController {
}
package ex04;
import ex04.anno.RequestMapping;
import ex04.anno.RestController;
@RestController
public class BoardController {
@RequestMapping("/insert")
public void insert(){
System.out.println("insert 호출됨");
}
@RequestMapping("/delete")
public void delete(){
System.out.println("delete 호출됨");
}
@RequestMapping("/update")
public void update(){
System.out.println("update 호출됨");
}
@RequestMapping("/select")
public String select1(){
System.out.println("select 호출됨");
return "apple";
}
}
package ex04;
import ex04.anno.RequestMapping;
import ex04.anno.RestController;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class App {
static void findUri(String uri) {
// 3. 동적 클래스 분석
Method[] methods = BoardController.class.getDeclaredMethods();
for (Method m : methods) {
RequestMapping rm = m.getDeclaredAnnotation(RequestMapping.class);
if (rm.value().equals(uri)) {
try {
Object res = m.invoke(null);
System.out.println("응답 버퍼 : " + res);
} catch (Exception e) {
e.printStackTrace(); // 피범벅
}
}
}
}
public static void main(String[] args) throws URISyntaxException, ClassNotFoundException, InstantiationException, IllegalAccessException {
// 1. 키보드 입력 자리
String uri = "/insert";
// 2. 패키지 스캔
ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // java 폴더 찾는 함수(문법) ref > out > production > classes 폴더
URL packageUrl = classLoader.getResource("ex04"); // java 폴더에 있는 'ex04' 찾는 것 (문법)
File ex04Folder = new File(packageUrl.toURI()); // 폴더를 파일 객체로 받은 이유는 윈도우는 모든 것을 파일로 구분함 (문법)
File[] files = ex04Folder.listFiles(); // 해당 폴더의 파일을 리스트에 담음(문법) anno, App, BoardController, UserController
// 3. 찾은 것들을 new 해서 컬렉션에 담아두기
List<Object> iocContainer = new ArrayList<>(); // Inversion Of Controller (제어의 역전)
for (File f : files) {
// System.out.println(f.getName());
if(f.getName().endsWith(".class")) {
String className = "ex04."+f.getName().replace(".class", ""); // ex04.BoardController, ex04.UserController
Class cls = Class.forName(className); // JVM이 문자열로 클래스 로딩하는 것
// System.out.println(cls);
// 어노테이션 분석해서 담기
if (cls.isAnnotationPresent(RestController.class)) {
// System.out.println(cls);
Object instance = cls.newInstance(); // 어떤 타입으로 new될 지 모르기 때문에 Object 타입
iocContainer.add(instance);
}
}
}
}
}
5) 메서드 호출
package ex04;
import ex04.anno.RequestMapping;
import ex04.anno.RestController;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class App {
static void findUri(String uri, Object obj) {
// 3. 동적 클래스 분석
Method[] methods = obj.getClass().getDeclaredMethods();
for (Method m : methods) {
RequestMapping rm = m.getDeclaredAnnotation(RequestMapping.class);
if (rm.value().equals(uri)) {
try {
Object res = m.invoke(obj);
System.out.println("응답 버퍼 : " + res);
} catch (Exception e) {
e.printStackTrace(); // 피범벅
}
}
}
}
public static void main(String[] args) throws URISyntaxException, ClassNotFoundException, InstantiationException, IllegalAccessException {
// 1. 키보드 입력 자리
String uri = "/select";
// 2. 패키지 스캔
ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // java 폴더 찾는 함수(문법) ref > out > production > classes 폴더
URL packageUrl = classLoader.getResource("ex04"); // java 폴더에 있는 'ex04' 찾는 것 (문법)
File ex04Folder = new File(packageUrl.toURI()); // 폴더를 파일 객체로 받은 이유는 윈도우는 모든 것을 파일로 구분함 (문법)
File[] files = ex04Folder.listFiles(); // 해당 폴더의 파일을 리스트에 담음(문법) anno, App, BoardController, UserController
// 3. 찾은 것들을 new 해서 컬렉션에 담아두기
List<Object> iocContainer = new ArrayList<>(); // Inversion Of Controller (제어의 역전)
for (File f : files) {
// System.out.println(f.getName());
if(f.getName().endsWith(".class")) {
String className = "ex04."+f.getName().replace(".class", ""); // ex04.BoardController, ex04.UserController
Class cls = Class.forName(className); // JVM이 문자열로 클래스 로딩하는 것
// System.out.println(cls);
// 어노테이션 분석해서 담기
if (cls.isAnnotationPresent(RestController.class)) {
// System.out.println(cls);
Object instance = cls.newInstance(); // 어떤 타입으로 new될 지 모르기 때문에 Object 타입
iocContainer.add(instance);
}
}
}
// 4. 메서드 호출
for (Object obj : iocContainer) {
findUri(uri, obj);
}
}
}
Share article