리νλ μ μ΄λ ?
1. 리νλ μ (Reflection)
: μ€ν μ€μΈ νλ‘κ·Έλ¨μ ν΄λμ€, λ©μλ, νλ λ±μ λν μ 보λ₯Ό μ»κ±°λ μ‘°μνλ κΈ°λ₯μ μ 곡νλ API
- ν΄λμ€μ μ 보 λΆμ, μΈμ€ν΄μ€ μμ±, λ©μλ νΈμΆ, νλμ κ°μ κ°μ Έμ€κ±°λ μ€μ λ±μ μμ μν
2. 리νλ μ μ΄ μ΄μ©λλ μν©
1. λ°νμ μμ λμ μΌλ‘ ν΄λμ€λ₯Ό λ‘λν΄μΌ νλ κ²½μ°
2. ν΄λμ€μ ꡬ쑰, λ©μλ, νλ λ±μ λν μ 보λ₯Ό κ°μ Έμμ λΆμν΄μΌ νλ κ²½μ°
3. ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό μμ±νκ±°λ λ©μλλ₯Ό νΈμΆνκ±°λ νλμ κ°μ λ³κ²½ν΄μΌ νλ κ²½μ°
μμ μ€λͺ μΌλ‘λ μ΄ν΄κ° μ΄λ €μ°λ μ‘°κΈ λ μμ보λλ‘ νμ.
# CASE 1
첫λ²μ§Έ κ²½μ°μμ, λ€μκ³Ό κ°μ΄ 1μ°¨ κ°λ°μλ "/login"μ μ λ ₯ λ°μμ λ uc.login() λ©μλκ° νΈμΆλλλ‘,
"/join"μ μ λ ₯ λ°μμ λ uc.join() λ©μλκ° νΈμΆλλλ‘ νλ applicationμ λ§λ€μλ€.
import java.util.Scanner;
// 1μ°¨ κ°λ°μ
public class App {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String path = sc.nextLine();
// path = "/login" -> uc.login()
// path = "/join" -> uc.join();
UserController uc = new UserController();
if(path.equals("/login")){
uc.login();
}else if(path.equals("/join")){
uc.join();
}
}
}
μ΄ νλ‘κ·Έλ¨μ μ€ν μμΌ°μ λ μ λμκ°κΈ° λλ¬Έμ μ λ§λ€μ΄μ§ νλ‘κ·Έλ¨μ΄λΌκ³ λ³Ό μ μλ€.
κ·Έλ λ€λ©΄, μ΄μ κ°μ νλ‘κ·Έλ¨μ 2μ°¨ κ°λ°μκ° μ¬μ©νκΈ° μν΄μλ λ¬΄μ¨ μ λ³΄κ° νμν κΉ ?
λ€μκ³Ό κ°μ΄ 1. λ©μλ λͺ κ³Ό 2. ν΄λμ€ λͺ μ΄ νμν κ²μ΄λ€.
// 2μ°¨ κ°λ°μ
public class UserController {
public void login(){
System.out.println("login() νΈμΆλ¨");
}
public void join(){
System.out.println("join() νΈμΆλ¨");
}
}
νμ§λ§ 1μ°¨ κ°λ°μλ μΌμΌμ΄ λ©μλ λͺ κ³Ό ν΄λμ€ λͺ μ μ λ¬νλ κ²λ³΄λ€ interfaceλ₯Ό ν΅ν΄ λ©μλλ₯Ό μμ±νκ³ , overrideλ₯Ό ν΅ν΄ ꡬννλλ‘ νλ κ²μ΄ λ νΈλ¦¬ν κ²μ΄λ€.
/*
μμ±μ : νκΈΈλ
μ£Όμμ¬ν : ꡬν체λ UserControllerλ‘ ν΄μ£ΌμΈμ
*/
public interface UserCon {
void login();
void join();
}
κ·Έλ°λ° μ¬κΈ°μ 2μ°¨ κ°λ°μκ° μλ‘μ΄ κΈ°λ₯μ μΆκ°νκΈ° μν΄ λ©μλλ₯Ό μλ‘ μμ±νλ€λ©΄ μ΄λ»κ² λ κΉ ?
2μ°¨ κ°λ°μκ° μμ±ν λ©μλλ λΉμ°ν μλλμ§ μμ κ±°κ³ μ΄μ κ°μ μν©μ ν΄κ²°νκΈ° μν΄μλ 1μ°¨ κ°λ°μκ° μμ±ν interfaceλ₯Ό κ°μ΄ μμ ν΄μ€μΌ νλ€. (λΆνμν μ μ§λ³΄μ)
κ²°κ΅ νμ μ΄ μλ, ν맀λ₯Ό μν νλ‘κ·Έλ¨μ΄λΌλ©΄ μ΄ νλ‘κ·Έλ¨μ νλ§€κ° λμ§ μμ κ²μ΄λ€. (OCP μλ°° ?)
# CASE 2
λλ²μ§Έ κ²½μ°μ΄λ€. μ΄λ²μλ μλν μ΄μ μ νμ©ν΄λ³΄λ €κ³ νλ€.
μλμ μλν μ΄μ μ λ©μλκ° μ€νλ λ uriμ μ£Όμλ₯Ό λΆμνλ μλν μ΄μ μ΄λ€.
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD) // μμΉ = λ©μλ
@Retention(RetentionPolicy.RUNTIME) // νμ΄λ° = μ€νμ
public @interface RequestMapping {
String uri();
}
κ·Έ κ²°κ³Όλ‘ @RequestMappingμ uriκ° μ΄λ»κ² λ€μ΄μ€λμ§μ λ°λΌ λ€λ₯Έ λ©μλλ₯Ό μ€ννκ² νλ€.
public class UserController {
@RequestMapping(uri = "/login")
public void login(){
System.out.println("login() νΈμΆλ¨");
}
@RequestMapping(uri = "/join")
public void join(){
System.out.println("join() νΈμΆλ¨");
}
}
λ€μ App ν΄λμ€μμ scannerλ₯Ό ν΅ν΄ uriκ°μ μ λ ₯ λ°κ³ findUriλ‘ UserController() κ°μ²΄μ uriκ° λ§€κ°λ³μλ‘ λ€μ΄κ°λ€.
findUriλ uriλ₯Ό λΆμν΄ μ»¨νΈλ‘€λ¬μ λ©μλλ₯Ό μ€ννλ€.
import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class App {
// λ΄μ© λΆμν΄λ³΄κΈ° νΌμ !!!!!!!!
// uri λΆμν΄ μ»¨νΈλ‘€λ¬μ λ©μλ μ€νν΄
public static void findUri(UserController uc, String uri) throws Exception {
boolean isFind = false;
Method[] methods = uc.getClass().getDeclaredMethods(); // 2κ°
for (Method mt : methods) {
Annotation anno = mt.getDeclaredAnnotation(RequestMapping.class);
RequestMapping rm = (RequestMapping) anno;
if (rm.uri().equals(uri)) {
isFind = true;
mt.invoke(uc); // ν΄λΉ λ©μλλ₯Ό μ€ν μμΌλΌ
}
}
if(isFind == false){
System.out.println("404 Not Found");
}
}
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String uri = sc.nextLine();
findUri(new UserController(), uri);
}
}
μ΄μ λ UserController μμμ μλ‘μ΄ λ©μλλ₯Ό μμ±ν΄λ @RequestMappingμ λΆμ΄λ©΄ μ€νμ΄ λκΈ° λλ¬Έμ ν맀ν μ μλ νλ‘κ·Έλ¨μ΄ λ κ² κ°κΈ°λ νλ€.
νμ§λ§, μλ‘μ΄ μ»¨νΈλ‘€λ¬λ₯Ό λ§λ€κ³ μΆλ€λ©΄?
public class BoardController {
@RequestMapping(uri = "/save")
public void save() { System.out.println("save() νΈμΆλ¨"); }
}
App ν΄λμ€μμ UserController λ©μλλ§ findUriλ‘ μ²λ¦¬νκ³ μκΈ° λλ¬Έμ, μ΄ BoardControllerλ₯Ό νΈμΆν μ μλ λ°©λ²μ μλ€.
# CASE 3
import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class App {
public static Set<Class> componentScan(String pkg) throws Exception {
// νμ¬ App νμΌμ κ²½λ‘
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Set<Class> classes = new HashSet<>();
URL packageUrl = classLoader.getResource(pkg);
File packageDirectory = new File(packageUrl.toURI());
for (File file : packageDirectory.listFiles()) {
if (file.getName().endsWith(".class")) {
String className = pkg + "." + file.getName().replace(".class", "");
//System.out.println(className);
Class cls = Class.forName(className);
classes.add(cls);
}
}
return classes;
}
public static void findUri(Set<Class> classes, String uri) throws Exception {
boolean isFind = false;
for (Class cls : classes) {
if (cls.isAnnotationPresent(Controller.class)) {
Object instance = cls.newInstance();
Method[] methods = cls.getDeclaredMethods();
for (Method mt : methods) {
Annotation anno = mt.getDeclaredAnnotation(RequestMapping.class);
RequestMapping rm = (RequestMapping) anno;
if (rm.uri().equals(uri)) {
isFind = true;
mt.invoke(instance);
}
}
}
}
if(isFind == false){
System.out.println("404 Not Found");
}
}
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String uri = sc.nextLine();
Set<Class> classes = componentScan("ex03");
findUri(classes, uri);
}
}
μ΄μ λ³κ²½μ¬νμ΄ λμ λν λ°, componentScan λ©μλλ₯Ό μ΄μ©ν΄ package λ΄μ μλ λͺ¨λ ν΄λμ€λ₯Ό classesμ λ£λλ€.
μ΄λμ componentScan λ©μλμμλ
1, Thread.currentThread().getContext.ClassLoader()λ₯Ό μ΄μ©νμ¬ νμ¬ μ€ν μ€μΈ μ°λ λμ ν΄λμ€ λ‘λλ₯Ό μ»μ΄μμ ν΄λΉ ν΄λμ€ λ‘λμκ² resource μ°Ύλ μν μ λΆμ¬νκ³ ,
2. classesλΌλ hashsetμ μμ±νλ€.
3. 리μμ€μμ ν΄λΉ ν¨ν€μ§μ Urlμ μ½μ΄ packageDirectoryμ μ μ₯νλ€.
4. μ΄ λλ ν 리μ νμΌλ€μ forλ¬Έμ ν΅ν΄ .classλ‘ λλλ νμΌλ€λ§ μ°Ύλλ€.
5. νμΌλ€μ κ·Έλ κ² μ°Ύμ classλ€μ classesμ μ μ₯νλ€.
κ·Έλ¦¬κ³ findUriλ ν΄λμ€λ€μ κ°―μλ§νΌ forλ¬Έμ ν΅ν΄ λ°λ³΅νκ³ ν΄λΉ ν΄λμ€μ μ΄λ Έν μ΄μ μ΄ controllerμ΄λ©΄ clc.newInstance()λ₯Ό ν΅ν΄ λ©λͺ¨λ¦¬λ₯Ό λμ΄λ€. (λμ λΆμ)
κ·Έ λ€λ case2μ κ²½μ°μ κ°μ΄ λ©μλλ₯Ό λ°λ³΅νλ©° uriλ₯Ό νμΈνκ³ λ©μλλ₯Ό νΈμΆνλ€.
μ΄μ κ°μ΄ λ³κ²½νκ² λλ©΄, λ€λ₯Έ κ°λ°μλ€μ΄ μλ‘μ΄ controllerλ₯Ό λ§λ€λ λ©μλλ₯Ό λ§λ€λ λͺ¨λ μ μ νκ² μ¬μ©λ μ μλ€.
κ²°λ‘
μλ°μμμ 리νλ μ
ꡬ체μ μΈ ν΄λμ€ νμ μ μμ§ λͺ»ν΄λ κ·Έ ν΄λμ€μ λ©μλμ νμ κ·Έλ¦¬κ³ λ³μλ€μ μ κ·Όν μ μλλ‘ ν΄μ£Όλ μλ° API μ΄λ€.
> μμ μμμμ CASE 3μ componentScan λ©μλκ° νλ μΌμ 리νλ μ μ΄λΌκ³ ν μ μλ€.
'π΅ java' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
JAVA | JPA μμ보기 (JPA, JDBC, Hibernate & JPA) (0) | 2023.07.10 |
---|---|
JAVA | DTOλ (0) | 2023.07.07 |
JAVA | enum (0) | 2023.06.13 |
JAVA | List, ArrayListμ μ¬μ© (0) | 2023.06.06 |
JAVA | @RequestParam (0) | 2023.06.05 |