[Spring Boot] 2. Reflection_4.Ex04

김미숙's avatar
Mar 20, 2025
[Spring Boot] 2. Reflection_4.Ex04
‼️

1. Component Scan?

  • @Component 계열 어노테이션이 붙은 클래스를 자동으로 감지하고 Spring 컨테이너에 등록하는 기능.
  • @Configuration 클래스에서 @ComponentScan을 사용해 설정할 수 있음.

2. 주요 Annotation

어노테이션
설명
@Component
가장 일반적인 컴포넌트 지정
@Service
서비스 계층(비즈니스 로직) 컴포넌트
@Repository
데이터 액세스 계층 (DAO) 컴포넌트
@Controller
Spring MVC 컨트롤러
@RestController
REST API 컨트롤러
⚡ 모든 어노테이션은 @Component를 기반으로 동작한다. 즉, @Service, @Repository, @Controller@Component의 기능을 포함하고 있다.
 

Annotation / @Component

package ex04; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) // 언제 작동할지 정함 runtime or source(comfile시) @Target(ElementType.TYPE) // 클래스 위! public @interface Component { // 이 깃발이 붙은 클래스만 new해서 전달 }

Annotation / @RequestMapping

package ex04; //A회사 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) // 언제 작동할지 정함 runtime or source(comfile시) @Target(ElementType.METHOD) public @interface RequestMapping { String value(); }

DispatcherServlet

package ex04; import java.io.File; import java.lang.reflect.Method; import java.net.URL; import java.util.HashSet; import java.util.Set; public class DispatcherServlet { public Set<Object> componentScan(String packageName) { // 1. @Component가 붙으면 new해서 컬렉션에 담기 Set<Object> instances = new HashSet(); ClassLoader classLoader = ClassLoader.getSystemClassLoader(); URL packageUrl = classLoader.getResource(packageName); File packageDir = new File(packageUrl.getFile()); for (File file : packageDir.listFiles()) { if (file.getName().endsWith(".class")) { String className = packageName + "." + file.getName().replace(".class", ""); //System.out.println(className); try { Class cls = Class.forName(className); if (cls.isAnnotationPresent(Component.class)) { Object instance = cls.getDeclaredConstructor().newInstance(); instances.add(instance); } } catch (Exception e) { throw new RuntimeException(e); } } } // for 종료 return instances; } public void routing(Set<Object> instances, String path) { for (Object instance : instances) { Method[] methods = instance.getClass().getMethods(); for (Method method : methods) { RequestMapping rm = method.getAnnotation(RequestMapping.class); if (rm == null) continue; // 다음 for문으로 바로 넘어감 if (rm.value().equals(path)) { try { method.invoke(instance); } catch (Exception e) { throw new RuntimeException(e); } } } } } }

UserController

package ex04; @Component public class UserController { @RequestMapping("/login") public void login() { System.out.println("login call"); } @RequestMapping("/join") public void join() { System.out.println("join call"); } @RequestMapping("/logout") public void logout() { System.out.println("logout call"); } @RequestMapping("/userinfo") public void userinfo() { System.out.println("userinfo call"); } }

BoardController

package ex04; @Component public class BoardController { @RequestMapping("/write") public void write() { System.out.println("write call"); } @RequestMapping("/delete") public void delete() { System.out.println("delete call"); } }
 

ex04 Package 안에 있는 Class 확인하기

‼️
실제 ex04 안에 있는 Class가 아닌 comfile된 Class를 찾는다

App

package ex04; import java.io.File; import java.net.URL; public class App { public static void main(String[] args) { // 1. @Component가 붙으면 new해서 컬렉션에 담기 ClassLoader classLoader = ClassLoader.getSystemClassLoader(); URL packageUrl = classLoader.getResource("ex04"); File packageDir = new File(packageUrl.getFile()); for (File file : packageDir.listFiles()) { if (file.getName().endsWith(".class")) { String className = "ex04." + file.getName().replace(".class", ""); System.out.println(className); } } } }
C:\workspace\tools\jdk-21\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2024.3.2.1\lib\idea_rt.jar=54433:C:\Program Files\JetBrains\IntelliJ IDEA 2024.3.2.1\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\workspace\spring_lec\ref\out\production\ref ex04.App ex04.App ex04.BoardController ex04.Component ex04.DispatcherServlet ex04.RequestMapping ex04.UserController Process finished with exit code 0
 

Component Annotation이 있는 Class 확인하기

package ex04; import java.io.File; import java.net.URL; import java.util.HashSet; import java.util.Set; public class App { public static void main(String[] args) { // 1. @Component가 붙으면 new해서 컬렉션에 담기 Set<Object> instances = new HashSet(); ClassLoader classLoader = ClassLoader.getSystemClassLoader(); URL packageUrl = classLoader.getResource("ex04"); File packageDir = new File(packageUrl.getFile()); for (File file : packageDir.listFiles()) { if (file.getName().endsWith(".class")) { String className = "ex04." + file.getName().replace(".class", ""); //System.out.println(className); try { Class cls = Class.forName(className); if (cls.isAnnotationPresent(Component.class)) { Object instance = cls.getDeclaredConstructor().newInstance(); instances.add(instance); } } catch (Exception e) { throw new RuntimeException(e); } } } // for 종료 for (Object instance : instances) { System.out.println(instance.getClass().getName()); } } }
출력 결과
C:\workspace\tools\jdk-21\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2024.3.2.1\lib\idea_rt.jar=54455:C:\Program Files\JetBrains\IntelliJ IDEA 2024.3.2.1\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\workspace\spring_lec\ref\out\production\ref ex04.App ex04.BoardController ex04.UserController Process finished with exit code 0
Share article

parangdajavous