Skip to content

Commit

Permalink
리뷰 빠르게 반영해주셨네요! 테스트가 없어서 아쉽네요, 추후에 꼭 추가해주세요! 고생하셨습니다~
Browse files Browse the repository at this point in the history
리뷰 빠르게 반영해주셨네요!
테스트가 없어서 아쉽네요, 추후에 꼭 추가해주세요! 고생하셨습니다~
  • Loading branch information
younghoondoodoom authored Sep 14, 2023
1 parent 3152d3d commit 1ae5770
Show file tree
Hide file tree
Showing 39 changed files with 643 additions and 581 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
package cache.com.example.cachecontrol;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.WebContentInterceptor;

@Configuration
public class CacheWebConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(final InterceptorRegistry registry) {
final CacheControl cacheControl = CacheControl.noCache()
.cachePrivate();

final WebContentInterceptor webContentInterceptor = new WebContentInterceptor();
webContentInterceptor.addCacheMapping(cacheControl, "/**");

registry.addInterceptor(webContentInterceptor);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package cache.com.example.etag;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.ShallowEtagHeaderFilter;

@Configuration
public class EtagFilterConfiguration {

// @Bean
// public FilterRegistrationBean<ShallowEtagHeaderFilter> shallowEtagHeaderFilter() {
// return null;
// }
@Bean
public FilterRegistrationBean<ShallowEtagHeaderFilter> shallowEtagHeaderFilter() {
final FilterRegistrationBean<ShallowEtagHeaderFilter> filterRegistrationBean = new FilterRegistrationBean<>(new ShallowEtagHeaderFilter());
filterRegistrationBean.addUrlPatterns("/etag");
filterRegistrationBean.addUrlPatterns("/resources/*");
return filterRegistrationBean;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.concurrent.TimeUnit;

@Configuration
public class CacheBustingWebConfig implements WebMvcConfigurer {
Expand All @@ -13,13 +15,14 @@ public class CacheBustingWebConfig implements WebMvcConfigurer {
private final ResourceVersion version;

@Autowired
public CacheBustingWebConfig(ResourceVersion version) {
public CacheBustingWebConfig(final ResourceVersion version) {
this.version = version;
}

@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler(PREFIX_STATIC_RESOURCES + "/" + version.getVersion() + "/**")
.addResourceLocations("classpath:/static/");
.addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS).cachePublic());
}
}
10 changes: 7 additions & 3 deletions study/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ handlebars:

server:
tomcat:
accept-count: 1
max-connections: 1
accept-count: 10
max-connections: 2
threads:
max: 2
max: 10

compression:
enabled: true
min-response-size: 10
17 changes: 8 additions & 9 deletions study/src/test/java/thread/stage0/SynchronizationTest.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package thread.stage0;

import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

import static org.assertj.core.api.Assertions.assertThat;

/**
* 다중 스레드 환경에서 두 개 이상의 스레드가 변경 가능한(mutable) 공유 데이터를 동시에 업데이트하면 경쟁 조건(race condition)이 발생한다.
* 자바는 공유 데이터에 대한 스레드 접근을 동기화(synchronization)하여 경쟁 조건을 방지한다.
* 동기화된 블록은 하나의 스레드만 접근하여 실행할 수 있다.
*
* <p>
* Synchronization
* https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html
*/
Expand All @@ -21,14 +20,14 @@ class SynchronizationTest {
/**
* 테스트가 성공하도록 SynchronizedMethods 클래스에 동기화를 적용해보자.
* synchronized 키워드에 대하여 찾아보고 적용하면 된다.
*
* <p>
* Guide to the Synchronized Keyword in Java
* https://www.baeldung.com/java-synchronized
*/
@Test
void testSynchronized() throws InterruptedException {
var executorService = Executors.newFixedThreadPool(3);
var synchronizedMethods = new SynchronizedMethods();
final var executorService = Executors.newFixedThreadPool(3);
final var synchronizedMethods = new SynchronizedMethods();

IntStream.range(0, 1000)
.forEach(count -> executorService.submit(synchronizedMethods::calculate));
Expand All @@ -41,15 +40,15 @@ private static final class SynchronizedMethods {

private int sum = 0;

public void calculate() {
public synchronized void calculate() {
setSum(getSum() + 1);
}

public int getSum() {
return sum;
}

public void setSum(int sum) {
public void setSum(final int sum) {
this.sum = sum;
}
}
Expand Down
17 changes: 8 additions & 9 deletions study/src/test/java/thread/stage0/ThreadPoolsTest.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
package thread.stage0;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

import static org.assertj.core.api.Assertions.assertThat;

/**
* 스레드 풀은 무엇이고 어떻게 동작할까?
* 테스트를 통과시키고 왜 해당 결과가 나왔는지 생각해보자.
*
* <p>
* Thread Pools
* https://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
*
* <p>
* Introduction to Thread Pools in Java
* https://www.baeldung.com/thread-pool-java-and-guava
*/
Expand All @@ -31,8 +30,8 @@ void testNewFixedThreadPool() {
executor.submit(logWithSleep("hello fixed thread pools"));

// 올바른 값으로 바꿔서 테스트를 통과시키자.
final int expectedPoolSize = 0;
final int expectedQueueSize = 0;
final int expectedPoolSize = 2;
final int expectedQueueSize = 1;

assertThat(expectedPoolSize).isEqualTo(executor.getPoolSize());
assertThat(expectedQueueSize).isEqualTo(executor.getQueue().size());
Expand All @@ -46,7 +45,7 @@ void testNewCachedThreadPool() {
executor.submit(logWithSleep("hello cached thread pools"));

// 올바른 값으로 바꿔서 테스트를 통과시키자.
final int expectedPoolSize = 0;
final int expectedPoolSize = 3;
final int expectedQueueSize = 0;

assertThat(expectedPoolSize).isEqualTo(executor.getPoolSize());
Expand All @@ -57,7 +56,7 @@ private Runnable logWithSleep(final String message) {
return () -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
log.info(message);
Expand Down
8 changes: 4 additions & 4 deletions study/src/test/java/thread/stage1/ConcurrencyTest.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package thread.stage1;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;

/**
* 스레드를 다룰 때 어떤 상황을 조심해야 할까?
* - 상태를 가진 한 객체를 여러 스레드에서 동시에 접근할 경우
* - static 변수를 가진 객체를 여러 스레드에서 동시에 접근할 경우
*
* <p>
* 위 경우는 동기화(synchronization)를 적용시키거나 객체가 상태를 갖지 않도록 한다.
* 객체를 불변 객체로 만드는 방법도 있다.
*
* <p>
* 웹서버는 여러 사용자가 동시에 접속을 시도하기 때문에 동시성 이슈가 생길 수 있다.
* 어떤 사례가 있는지 아래 테스트 코드를 통해 알아보자.
*/
Expand Down
20 changes: 1 addition & 19 deletions tomcat/src/main/java/nextstep/Application.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,11 @@
package nextstep;

import nextstep.jwp.HandlerResolver;
import nextstep.jwp.JwpHttpDispatcher;
import nextstep.jwp.SessionManager;
import nextstep.jwp.handler.get.LoginGetHandler;
import nextstep.jwp.handler.get.RegisterGetHandler;
import nextstep.jwp.handler.get.RootGetHandler;
import nextstep.jwp.handler.post.LoginPostHandler;
import nextstep.jwp.handler.post.RegisterPostHandler;
import org.apache.catalina.startup.Tomcat;
import org.apache.coyote.http11.Handler;
import java.util.Map;

public class Application {

private static final Map<String, Handler> httpGetHandlers =
Map.of("/", new RootGetHandler(),
"/login", new LoginGetHandler(new SessionManager()),
"/register", new RegisterGetHandler());
private static final Map<String, Handler> httpPostHandlers =
Map.of("/login", new LoginPostHandler(new SessionManager()),
"/register", new RegisterPostHandler());

public static void main(final String[] args) {
final var tomcat = new Tomcat(new JwpHttpDispatcher(new HandlerResolver(httpGetHandlers, httpPostHandlers)));
final var tomcat = new Tomcat();
tomcat.start();
}
}
29 changes: 29 additions & 0 deletions tomcat/src/main/java/nextstep/jwp/DispatcherServlet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package nextstep.jwp;

import nextstep.jwp.controller.Controller;
import org.apache.coyote.http11.ContentType;
import org.apache.coyote.http11.HttpServlet;
import org.apache.coyote.http11.StatusCode;
import org.apache.coyote.http11.request.HttpRequest;
import org.apache.coyote.http11.response.HttpResponse;

public class DispatcherServlet implements HttpServlet {

private static final HandlerMapping handlerMapping = new HandlerMapping();

@Override
public void service(final HttpRequest httpRequest, final HttpResponse httpResponse) {
final Controller controller = handlerMapping.findController(httpRequest.getPath());
if (controller == null) {
generateNotFoundController(httpResponse);
return;
}
controller.service(httpRequest, httpResponse);
}

private void generateNotFoundController(final HttpResponse response) {
response.setStatusCode(StatusCode.NOT_FOUND)
.setContentType(ContentType.HTML)
.setRedirect("/404.html");
}
}
19 changes: 19 additions & 0 deletions tomcat/src/main/java/nextstep/jwp/HandlerMapping.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package nextstep.jwp;

import nextstep.jwp.controller.Controller;
import nextstep.jwp.controller.LoginController;
import nextstep.jwp.controller.RegisterController;
import nextstep.jwp.controller.RootGetController;
import java.util.Map;

public class HandlerMapping {

private static final Map<String, Controller> controllers =
Map.of("/", new RootGetController(),
"/login", new LoginController(),
"/register", new RegisterController());

public Controller findController(final String path) {
return controllers.get(path);
}
}
26 changes: 0 additions & 26 deletions tomcat/src/main/java/nextstep/jwp/HandlerResolver.java

This file was deleted.

46 changes: 0 additions & 46 deletions tomcat/src/main/java/nextstep/jwp/JwpHttpDispatcher.java

This file was deleted.

Loading

0 comments on commit 1ae5770

Please sign in to comment.