Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions src/main/java/com/diy/app/LectureController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.diy.framework.bean.Autowired;
import com.diy.framework.controller.Controller;
import com.diy.framework.enums.HttpMethod;
import com.diy.framework.enums.RequestMethod;
import com.diy.framework.value.Model;
import com.diy.framework.value.ModelAndView;
import com.fasterxml.jackson.core.type.TypeReference;
Expand All @@ -15,21 +15,18 @@
import java.util.Collection;
import java.util.Map;

@com.diy.framework.bean.Controller
public class LectureController implements Controller {

private final LectureRepository lectureRepository;
private final ObjectMapperConfiguration objectMapperConfiguration;

@Autowired
public LectureController(LectureRepository lectureRepository, ObjectMapperConfiguration objectMapperConfiguration) {
public LectureController(LectureRepository lectureRepository) {
this.lectureRepository = lectureRepository;
this.objectMapperConfiguration = objectMapperConfiguration;
}

@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
return switch (HttpMethod.equals(request.getMethod())) {
return switch (RequestMethod.equals(request.getMethod())) {
case POST -> doPost(request, response);
case GET -> doGet(request, response);
default -> throw new RuntimeException("404 Not Found");
Expand Down
49 changes: 49 additions & 0 deletions src/main/java/com/diy/app/LectureControllerV2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.diy.app;

import com.diy.framework.bean.Autowired;
import com.diy.framework.bean.annotation.Controller;
import com.diy.framework.bean.annotation.RequestMapping;
import com.diy.framework.enums.RequestMethod;
import com.diy.framework.value.Model;
import com.diy.framework.value.ModelAndView;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Map;

@Controller
public class LectureControllerV2 {

private final LectureRepository lectureRepository;

@Autowired
public LectureControllerV2(LectureRepository lectureRepository) {
this.lectureRepository = lectureRepository;
}

@RequestMapping(value = "lectures", method = RequestMethod.GET)
private ModelAndView doGet(HttpServletRequest request, HttpServletResponse response) {
Collection<Lecture> lectures = lectureRepository.findAll();
Model model = new Model(Map.of("lectures", lectures));
return ModelAndView.of("lecture-list", model);
}

private ModelAndView doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
final byte[] bodyData = request.getInputStream().readAllBytes();
final String body = new String(bodyData, StandardCharsets.UTF_8);
Map<String, Object> data = new ObjectMapper().readValue(body, new TypeReference<>() {});

long id = lectureRepository.nextId();
String name = data.get("name").toString();
double price = Double.parseDouble(data.get("price").toString());

lectureRepository.save(new Lecture(id, name, price));

return ModelAndView.fromViewName("redirect:/lectures");
}
}
3 changes: 1 addition & 2 deletions src/main/java/com/diy/app/LectureRepository.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.diy.app;

import com.diy.framework.bean.Component;
import com.diy.framework.bean.Repository;
import com.diy.framework.bean.annotation.Repository;

import java.util.ArrayList;
import java.util.HashMap;
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/com/diy/app/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,35 @@

import com.diy.framework.bean.ApplicationContext;
import com.diy.framework.controller.Controller;
import com.diy.framework.controller.RequestHandler;
import com.diy.framework.controller.RequestHandlerImpl;
import com.diy.framework.controller.RequestKey;
import com.diy.framework.servlet.DispatcherServlet;
import com.diy.framework.value.ModelAndView;
import com.diy.framework.view.ViewResolverFactory;
import com.diy.framework.view.ViewType;
import com.diy.framework.view.resolver.ViewResolver;
import com.diy.framework.web.server.TomcatWebServer;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

public class Main {

public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException {
final ApplicationContext applicationContext = new ApplicationContext(Main.class.getPackageName());
applicationContext.initialize();

System.out.println("Total = " + applicationContext.getBeans().size());
final Map<RequestKey, RequestHandler> handlers = new HashMap<>();

RequestHandlerImpl.handlers.forEach((key, value) ->
handlers.put(key, ((request, response) ->
(ModelAndView) value.method().invoke(value.bean(), request, response)))
);

final Map<String, Controller> controllers = Map.of("/lectures", applicationContext.getBean(LectureController.class));
final List<ViewResolver> viewResolvers = Stream.of(ViewType.REDIRECT, ViewType.JSP)
.map(ViewResolverFactory::of)
Expand Down
15 changes: 0 additions & 15 deletions src/main/java/com/diy/app/ObjectMapperConfiguration.java

This file was deleted.

13 changes: 10 additions & 3 deletions src/main/java/com/diy/framework/bean/ApplicationContext.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package com.diy.framework.bean;

import com.diy.framework.bean.annotation.Bean;
import com.diy.framework.bean.annotation.Component;
import com.diy.framework.bean.annotation.Controller;
import com.diy.framework.bean.annotation.Repository;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
Expand All @@ -10,6 +15,7 @@ public class ApplicationContext {

private final String basePackage;
private final Set<Class<?>> beanClasses = new HashSet<>();
private final Set<Method> beanMethods = new HashSet<>();
private final List<Object> beans = new ArrayList<>();

public ApplicationContext(final String basePackage) {
Expand All @@ -18,16 +24,17 @@ public ApplicationContext(final String basePackage) {

public void initialize() {
final BeanScanner beanScanner = new BeanScanner(basePackage);
// 동적 받아온것을 해당 경로의 모든 애너테이션을 등록하기
beanClasses.addAll(beanScanner.scanClassesTypeAnnotatedWith(Component.class));
beanClasses.addAll(beanScanner.scanClassesTypeAnnotatedWith(Controller.class));
beanClasses.addAll(beanScanner.scanClassesTypeAnnotatedWith(Repository.class));
beanMethods.addAll(beanScanner.scanMethodsAnnotatedWith(Bean.class));

addComponents();
addBeans(beanScanner);
addBeans();
}

private void addBeans(BeanScanner beanScanner) {
final Set<Method> beanMethods = beanScanner.scanMethodsAnnotatedWith(Bean.class);
private void addBeans() {
beanMethods.forEach(method -> {
Object configBean = getBean(method.getDeclaringClass());
try {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/diy/framework/bean/BeanScanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
public class BeanScanner {
private final Reflections reflections;

public BeanScanner(final String basePackage) {
public BeanScanner(final String... basePackage) {
this.reflections = new Reflections(basePackage, Scanners.TypesAnnotated, Scanners.MethodsAnnotated);
}

public Set<Class<?>> scanClassesTypeAnnotatedWith(final Class<? extends Annotation> annotation) {
return reflections.getTypesAnnotatedWith(annotation)
.stream()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.diy.framework.bean;
package com.diy.framework.bean.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.diy.framework.bean;
package com.diy.framework.bean.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.diy.framework.bean;
package com.diy.framework.bean.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.diy.framework.bean;
package com.diy.framework.bean.annotation;

@Component
public @interface Repository {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.diy.framework.bean.annotation;

import com.diy.framework.enums.RequestMethod;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {

String value() default "";
RequestMethod[] method() default {};
}
10 changes: 10 additions & 0 deletions src/main/java/com/diy/framework/controller/HandleMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.diy.framework.controller;

import java.lang.reflect.Method;

public record HandleMethod(
RequestKey requestKey,
Object bean,
Method method
) {
}
11 changes: 11 additions & 0 deletions src/main/java/com/diy/framework/controller/RequestHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.diy.framework.controller;

import com.diy.framework.value.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@FunctionalInterface
public interface RequestHandler {
ModelAndView handleRequest(final HttpServletRequest request, final HttpServletResponse response) throws Exception;
}
63 changes: 63 additions & 0 deletions src/main/java/com/diy/framework/controller/RequestHandlerImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.diy.framework.controller;

import com.diy.framework.bean.ApplicationContext;
import com.diy.framework.bean.BeanScanner;
import com.diy.framework.bean.annotation.Controller;
import com.diy.framework.bean.annotation.RequestMapping;
import com.diy.framework.enums.RequestMethod;
import com.diy.framework.value.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class RequestHandlerImpl implements RequestHandler {

private final ApplicationContext applicationContext;

private final Set<Class<?>> controllers = new HashSet<>();
public static final Set<RequestKey> keys = new HashSet<>();
public static final Map<RequestKey, HandleMethod> handlers = new HashMap<>();

BeanScanner beanScanner = new BeanScanner();

public RequestHandlerImpl(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.controllers.addAll(beanScanner.scanClassesTypeAnnotatedWith(Controller.class));
}

public void registerRequestMapping() {
Set<Method> methodsInner = beanScanner.scanMethodsAnnotatedWith(RequestMapping.class);

for (Method method : methodsInner) {
if (!controllers.contains(method.getDeclaringClass())){
throw new RuntimeException("Illegal method is injected");
}

RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
Object bean = applicationContext.getBean(method.getDeclaringClass());
RequestMethod[] requestMethods = requestMapping.method();

for (RequestMethod requestMethod : requestMethods) {
RequestKey key = new RequestKey(requestMethod.name(), requestMethod);
handlers.put(key, new HandleMethod(key, bean, method));
}
}
}

@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
RequestKey key = new RequestKey(request.getRequestURI(), RequestMethod.valueOf(request.getMethod()));

HandleMethod handle = handlers.get(key);
if (handle == null) {
throw new RuntimeException("404 Not Found");
}

return (ModelAndView) handle.method().invoke(handle.bean(), request, response);
}
}
9 changes: 9 additions & 0 deletions src/main/java/com/diy/framework/controller/RequestKey.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.diy.framework.controller;

import com.diy.framework.enums.RequestMethod;

public record RequestKey(
String path,
RequestMethod httpMethod
) {
}
13 changes: 0 additions & 13 deletions src/main/java/com/diy/framework/enums/HttpMethod.java

This file was deleted.

9 changes: 9 additions & 0 deletions src/main/java/com/diy/framework/enums/RequestMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.diy.framework.enums;

public enum RequestMethod {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;

public static RequestMethod equals(String compare) {
return valueOf(compare);
}
}
Loading