[WEB] Interceptor, Sevlet, Filter, Resource Handler ์•Œ์•„๋ณด๊ธฐ

2021. 12. 20. 19:51ใ†Back-End ์ž‘์—…์‹ค/Spring Framework

728x90
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š”? ์ฃผ๋‹ˆํ•˜๋ž‘ ์ž…๋‹ˆ๋‹ค.

์˜ค๋Š˜์€ ์ œ๋ชฉ์— ์—ด๊ฑฐํ•œ ๊ฒƒ๋“ค์— ๋Œ€ํ•ด ํ•œ๋ฒˆ ์•Œ์•„๋ณด๋Š” ๊ฒƒ์ด์—์š”.

์šฐ๋ฆฌ๊ฐ€ WEB์„ ๋งŒ๋“ค ๋•Œ, ์ธ์ฆ์ด๋‚˜, ํŒŒ์ผ ์—…๋กœ๋“œ ๋“ฑ์„ ํ•  ๋•Œ ํ•„์š”ํ•œ ๊ฐœ๋…์œผ๋กœ ์–ด๋–ค ์‹์œผ๋กœ ์š”์ฒญ์„ ๋ฐ›์•„๋“œ๋ฆฌ๋Š”์ง€ ์•Œ์•„์•ผ ํ•˜๋Š” ๋ถ€๋ถ„์ด๋ผ ์ •๋ฆฌ๋ฅผ ํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿผ ๋ฐ”๋กœ ์‹œ์ž‘ ํ•ด ๋ณผ๊ฒŒ์š”!

 

 


 

๐Ÿš€ Interceptor, Servlet Filter

Spring Filter์™€ Intercptor๋Š” ์–ด๋–ค ์ฐจ์ด์ ์ด ์žˆ์„๊นŒ์š”?
Filter๋Š” Servlet Container์— ์ด ์ „์— ๊ณตํ†ต์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ๋˜๋Š” ๋ถ€๋ถ„์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๊ณ , Interceptor๋Š” AOP์ฒ˜๋Ÿผ ํŠน์ • ์‹œ์ ์— ๊ฐ€๋กœ์ฑ„๊ธฐ ํ•˜์—ฌ ์–ด๋–ค ํ–‰์œ„๋ฅผ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด์—์š”.

Spring ๋˜๋Š” Spring Boot ํ”„๋ ˆ์ž„์›Œํฌ๋กœ Web Application์„ ๊ฐœ๋ฐœํ•˜๋‹ค ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์š”๊ตฌ์‚ฌํ•ญ์ด ์ƒ๊ธฐ๊ธฐ ๋งˆ๋ จ์ธ ๊ฒƒ์ด์—์š”.

1. ํŠน์ • URL ์ง„์ž… ์‹œ Login(์ธ๊ฐ€)๋œ ์ด์šฉ์ž๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ
2. ํŠน์ • URL ์ง„์ž… ์‹œ JWT์™€ ๊ฐ™์€ Token๊ฐ’ ๊ฒ€์‚ฌ
3. ํŠน์ • URL ์ง„์ž… ์‹œ ๊ณ„์ •์— ๊ถŒํ•œ์— ๋”ฐ๋ผ ์ ‘๊ทผ ํ—ˆ์šฉ ๋ฐ ์ฐจ๋‹จ(์ธ๊ฐ€)
    ์ด ๋ถ€๋ถ„์€ View(Front End)์—์„œ๋„ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

 

์ธํ„ฐ์…‰ํ„ฐ๋Š” ๋ฌด์–ธ๊ฐ€๋ฅผ ์ง„ํ–‰ํ•˜๊ธฐ ์ „ ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด์—์š”.

JAVA WEB Programming์—์„œ๋Š” ์ด๋Ÿฐ ์ž‘์—…์„ ํ•˜๋Š” ๊ธฐ์ˆ ๋กœ Servlet Filter, Interceptor, AOP๋“ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด์—์š”.

 

 

์œ„์˜ ์‚ฌ์ง„์€ Spring Request Life Cycle์„ ๋„์‹ํ™”ํ•œ ์ž๋ฃŒ์ธ ๊ฒƒ์ด์—์š”.
์‚ฌ์ง„์„ ๋ณด๋ฉด ์ด์šฉ์ž์˜ ์š”์ฒญ ๋’ค์— Filter์™€ DispatcherServlet์ด ๋ณด์ด๋Š” ๊ฒƒ์ด์—์š”.

Interceptor๋Š” Dispatcher Servlet ๋’ค์˜ Handler ์˜์—ญ์—์„œ ์š”์ฒญ ์ •๋ณด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์นœ๊ตฌ ์ธ ๊ฒƒ์ด์—์š”.

Servlet Filter์˜ ๊ฒฝ์šฐ J2EE์˜ ํ‘œ์ค€ ์ŠคํŽ™์— ์ •์˜๋˜์–ด ์žˆ์ง€๋งŒ, Interceptor๋Š” Spring ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ž์ฒด ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ ์ด๋ž๋‹ˆ๋‹ค.

 

1. Contoller์— ๋“ค์–ด์˜ค๋Š” HttpRequest์™€ ์‘๋‹ตํ•˜๋Š” HttpResponse ๊ฐ’์„ ๊ฐ€๋กœ์ฑ„์–ด ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ์—ญํ• 
2. ๊ด€๋ฆฌ์ž๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ด€๋ฆฌ์ž ์ธ์ฆ์˜ ์šฉ๋„๋กœ ๋งŽ์ด ํ™œ์šฉ
3. Filter๋Š” DispatcherServlet์ด ์‹คํ–‰๋˜๊ธฐ ์ „์— ํ˜ธ์ถœ๋˜๋‚˜, Interceptor๋Š” DispatcherServlet์ด ์‹คํ–‰๋œ ๋’ค ํ˜ธ์ถœ
4. Filter๋Š” web.xml์—์„œ ๊ด€๋ฆฌํ•˜๊ณ , Interceptor๋Š” spring-servlet.xml์—์„œ ๊ด€๋ฆฌ

 

Servlet Filter๋Š” Dispatcher Servlet ์•ž๋‹จ์—์„œ ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ ์ •๋ณด๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ , Dispatcher Servle ์ „์— ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์— Spring๊ณผ ๋ฌด๊ด€ํ•œ ์ž‘์—…๋“ค์„ ์ฒ˜๋ฆฌ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด์—์š”.

 

์ด์šฉ์ž ์š”์ฒญ(Request) -> Servlet Filter -> Dispatcher Servlet -> Interceptor -> Controller

 

 

 

 

    ๐Ÿ”ฝ  Filter, Interceptor, AOP

        ๐Ÿ“ฆ ๊ธฐ๋Šฅ๋ณ„ ์œ„์น˜

Filter & Interceptor ์œ„์น˜ (์ถœ์ฒ˜: https://justforchangesake.wordpress.com/2014/05/07/spring-mvc-request-life-cycle/)

Filter์™€ Interceptor๋Š” ์œ„์˜ ๊ทธ๋ฆผ์—์„œ ๋‚˜์˜ค๋Š” ์œ„์น˜์— ์žˆ์–ด์š”.


AOP ์œ„์น˜ (์ถœ์ฒ˜: https://programming.vip/docs/spring-aop-basic-use.html)


AOP๋Š” ์œ„์˜ ์œ„์น˜์— ์žˆ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์–ด์š”.





        ๐Ÿ“ฆ Filter

Filter๋Š” Web Application(์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜)์— ๋“ฑ๋กํ•ด์š”. ์ฆ‰, Request Thread๊ฐ€ Servlet Container์— ๋„์ฐฉํ•˜๊ธฐ ์ „์— ์ˆ˜ํ–‰ ๋œ๋‹ต๋‹ˆ๋‹ค. Filter๋Š” ์ด์šฉ์ž์˜ ์š”์ฒญ ์ •๋ณด์— ๋Œ€ํ•œ ๊ฒ€์ฆ์„ ํ•  ์ˆ˜ ์žˆ๊ณ , ํ•„์š”์— ๋”ฐ๋ผ Data๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, ๋ณ€์กฐํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ฃผ๋Š” ์—ญํ• ์„ ํ•ด์š”.

์‘๋‹ต ์ •๋ณด์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ๋„ ๋‹น์—ฐํžˆ ๊ฐ€๋Šฅํ•˜๋‹ต๋‹ˆ๋‹ค.

์ฃผ๋กœ ์ „์—ญ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ์ธ์ฝ”๋”ฉ, ๋ณด์•ˆ ๊ด€๋ จ๋œ ์ผ์„ ์ด๊ฒƒ์„ ํ†ตํ•ด ์ˆ˜ํ–‰ํ•œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์–ด์š”.

Filter ์‚ฌ์šฉ ์˜ˆ์‹œ

โˆ™ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ
โˆ™ ์ธ์ฝ”๋”ฉ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ
โˆ™ ์›น ๋ณด์•ˆ ๊ด€๋ จ ๊ธฐ๋Šฅ
โˆ™ Data ์••์ถ• ๋ฐ ๋ณ€ํ™˜ ๊ธฐ๋Šฅ
โˆ™ ์š”์ฒญ, ์‘๋‹ต์— ๋Œ€ํ•œ Loging
โˆ™ Login ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ ๊ถŒํ•œ ๊ฒ€์‚ฌ์™€ ๊ฐ™์€ ์ธ์ฆ, ์ธ๊ฐ€ ๊ธฐ๋Šฅ



Filter Method

โˆ™ init() : Filter ์ธ์Šคํ„ด์Šค ์ดˆ๊ธฐํ™”
โˆ™ doFilter() - ์ „/ํ›„ ์ฒ˜๋ฆฌ
โˆ™ destroy() : Filter ์ธ์Šคํ„ด์Šค ์ข…๋ฃŒ


Filet ๊ตฌํ˜„ ์˜ˆ์ œ

โˆ™ Filter ๊ตฌํ˜„
โˆ™ doFilter() ์žฌ์ •์˜
โˆ™ init(), destroy()๋Š” Default Method์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”์— ๋”ฐ๋ผ ๊ตฌํ˜„ ์ฆ‰, ํ•„์ˆ˜ ์‚ฌํ•ญ ์•„๋‹˜

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import lombok.extern.log4j.Log4j2;

@Slf4j
public class JunyHarangFilter implements Filter {

    private final String value;

    public JunyHarangFilter(String value) {
        this.value = value;
    }


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("==========\t" + value + " init filter");
    }

    @Override
    public void destroy() {
        log.info("==========\t" + value + " destroy filter");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("==========\t" + value + " before doFilter");
        chain.doFilter(request, response);
        log.info("==========\t" + value + " after doFilter");
    }
}





WebMvcConfiguration Class

โˆ™ Spring Boot์—์„œ๋Š” web.xml์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— FilterRegistrationBean์„ ์ •์˜ํ•˜์—ฌ Filter๋ฅผ ๋“ฑ๋ก
โˆ™ Filter๊ฐ€ ์ฒ˜๋ฆฌํ•  Path ์ง€์ •
โˆ™ WebMvcConfigurer ์ธํ„ฐํŽ˜์ด์Šค ์ƒ์†๊ณผ๋Š” ๋ฌด๊ด€

import junyhararang.in.action.filters.BlogFilter;
import junyhararang.in.action.interceptor.BlogHandlerInterceptor;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(new BlogFilter(BlogFilter.class.getSimpleName()));
        registrationBean.addUrlPatterns("/*");
        registrationBean.setOrder(1);
        return registrationBean;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new BlogHandlerInterceptor())
            .addPathPatterns("/**");
    }
}





        ๐Ÿ“ฆ Interceptor

์ธํ„ฐ์…‰ํ„ฐ๋Š” Spring Context์— ๋“ฑ๋กํ•ด์š”.
Servlet Container๋ฅผ ์ง€๋‚œ ๋’ค Controller์— ์š”์ฒญ์ด ์ „๋‹ฌ๋˜๊ธฐ ์ง์ „๊ณผ ์งํ›„์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ์นœ๊ตฌ์—์š”.
Spring Context ์•ˆ์— ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  Bean ๊ฐ์ฒด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , Session ์ฒ˜๋ฆฌ, Login ์ฒ˜๋ฆฌ, ๊ถŒํ•œ ์ฒ˜๋ฆฌ, Program ์‹คํ–‰ ์‹œ๊ฐ„ ๊ณ„์‚ฐ๋“ฑ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์–ด์š”.

Filter์™€ ๋‹ค๋ฅด๊ฒŒ handlerMethod Parameter๋ฅผ ์ด์šฉํ•˜์—ฌ AOP์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ ์ˆ˜ํ–‰๋„ ๊ฐ€๋Šฅํ•˜๋‹ต๋‹ˆ๋‹ค.


์ธํ„ฐ์…‰ํ„ฐ Method

โˆ™ preHandler() - Controller ์‹คํ–‰๋˜๊ธฐ ์ „ ์ž‘์—… ์ฒ˜๋ฆฌ
โˆ™ postHandler() - Controller ์‹คํ–‰ ๋’ค View Page Randering ์ „ ์ž‘์—… ์ฒ˜๋ฆฌ
โˆ™ afterCompletion() - View Page Randering ๋’ค ์ž‘์—… ์ฒ˜๋ฆฌ



์ธํ„ฐ์…‰ํ„ฐ ๊ตฌํ˜„ ์˜ˆ์ œ

โˆ™ HandlerInterceptor Interface ๊ตฌํ˜„์ฒด

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.log4j.Log4j2;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Slf4j
public class JunyHarangHandlerInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("==========\tinterceptor preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("==========\tinterceptor postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("==========\tinterceptor afterCompletion");
    }
}




WebMvcConfiguration Class

โˆ™ WebMvcConfigurer Interface ๊ตฌํ˜„
โˆ™ addInterceptors() ์žฌ ๊ตฌํ˜„์„ ํ†ตํ•ด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๊ตฌํ˜„ํ•œ Interceptor ๋“ฑ๋ก
โˆ™ Interceptor ์ฒ˜๋ฆฌ Path ์ง€์ •

import junyharang.in.action.filters.JunyHarangFilter;
import junyharang.in.action.interceptor.BlogHandlerInterceptor;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(new BlogFilter(BlogFilter.class.getSimpleName()));
        registrationBean.addUrlPatterns("/*");
        registrationBean.setOrder(1);
        return registrationBean;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new BlogHandlerInterceptor())
            .addPathPatterns("/**");
    }
}






        ๐Ÿ“ฆ AOP(Aspect Oriented Programming)

๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜ํ–‰์— ์žˆ์–ด ์ค‘๋ณต๋˜๋Š” Code๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋ฒ•์ด์—์š”.
๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์˜ ํŠน์ • ์‹œ์ ์„ ๋ฐ”๋ผ๋ณด๊ณ , ํ•ด๋‹น ์‹œ์ ์ด ์ˆ˜ํ–‰๋˜๋Š” ์ˆœ๊ฐ„์„ ๊ฐ€๋กœ์ฑ„์–ด ์ „, ํ›„ ๊ธฐ๋Šฅ์„ ์ฒ˜๋ฆฌ ํ•œ๋‹ต๋‹ˆ๋‹ค.
์ฃผ๋กœ Loging, ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ, Exception ์ฒ˜๋ฆฌ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•˜๊ฒŒ ๋˜์š”.

AOP ๊ธฐ๋Šฅ์€ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์ ์„ ์žŠ์œผ๋ฉด ์•ˆ๋˜์š”.


AOP ๊ตฌํ˜„ ์˜ˆ์ œ

โˆ™ Service Bean์ด ์ˆ˜ํ–‰ํ•˜๋Š” Method ๋™์ž‘ ์‹œ์ž‘ ์‹œ์ ์„ ๊ฐ€๋กœ์ฑ„์–ด ์ „, ํ›„ ๋™์ž‘ ์ˆ˜ํ–‰
โˆ™ Controller Bean์ด ์ˆ˜ํ–‰ํ•˜๋Š” Method ๋™์ž‘ ์‹œ์ž‘ ์‹œ์ ์„ ๊ฐ€๋กœ์ฑ„์–ด ์ „, ํ›„ ๋™์ž‘ ์ˆ˜ํ–‰


import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect
@Component
public class JunyHarangAop {

    @Around("execution(* blog.in.action.service.BlogService.*(..))")
    public Object aroundServiceFoo(ProceedingJoinPoint pjp) throws Throwable {
        log.info("==========\taround service before foo");
        Object result = pjp.proceed();
        log.info("==========\taround service after foo");
        return result;
    }

    @Around("execution(* blog.in.action.controller.BlogController.*(..))")
    public Object aroundControllerFoo(ProceedingJoinPoint pjp) throws Throwable {
        log.info("==========\taround controller before foo");
        Object result = pjp.proceed();
        log.info("==========\taround controller after foo");
        return result;
    }
}








 

๐Ÿš€ Resource Handler

 

๋ฐ˜์‘ํ˜•

 

1. Servlet Container๊ฐ€ ์ œ๊ณตํ•˜๋Š” DefaultServlet์œผ๋กœ Resource ์˜์—ญ์— ์กด์žฌํ•˜๋Š” ํŒŒ์ผ(/Images, /css, /js, /html ๋“ฑ)์„ ์ฒ˜๋ฆฌ
2. ๋ชจ๋“  ํ†ฐ์ผ“์— ๋“ฑ๋ก
3. $CATALINA_BASE/conf/web.xml์— ์ „์—ญ์ ์œผ๋กœ ๋“ฑ๋ก
4. DefaultServlet์— ์š”์ฒญ์„ '์œ„์ž„'ํ•˜์—ฌ Resource ์š”์ฒญ ์ฒ˜๋ฆฌ

728x90
๋ฐ˜์‘ํ˜•

'Back-End ์ž‘์—…์‹ค > Spring Framework' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Spring boot - Gradle] JPA ์—ฐ๊ฒฐ ์ •๋ณด ์•”ํ˜ธํ™”(jasypt)  (0) 2021.12.31
[Spring Boot] @Order  (0) 2021.12.21
[Spring] Spring MVC๋ž€?  (0) 2021.12.20
[Spring] @Builder (Builder Patter)  (0) 2021.10.11
[Spring] Bean Scope  (0) 2021.10.10