ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] Spring MVC์—์„œ AOP ์„ค์ • (feat. ๋ฃจํŠธ ์ปจํ…์ŠคํŠธ์™€ ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ)
    Backend/Spring 2023. 10. 24. 11:56

    ๐Ÿฅ‘ AOP

    • ๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(Aspect Oriented Programming)
    • ํ•ต์‹ฌ ๊ด€์‹ฌ ์‚ฌํ•ญ๊ณผ ๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ์„ ๋ถ„๋ฆฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹
    • ํ•ต์‹ฌ ๊ด€์‹ฌ ์‚ฌํ•ญ์— ์ ์šฉ๋˜๋Š” ๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ๋ชจ๋“ˆ๋กœ ๋งŒ๋“ค์–ด ์ฝ”๋“œ์˜ ์ค‘๋ณต์„ ์ค„์ด๊ณ  ํ•ต์‹ฌ ๋กœ์ง์— ์ง‘์ค‘ํ•œ๋‹ค.
    • ์Šคํ”„๋ง์—์„œ AOP
      • target์— ๋Œ€ํ•ด ํ”„๋ก์‹œ๋กœ ๊ฐ์‹ธ๊ณ 
      • ํ”„๋ก์‹œ๊ฐ€ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ์ด๋‚˜ ๋ฐ˜ํ™˜ ์‹œ์— ์ด๋ฅผ ๊ฐ€๋กœ์ฑ„์„œ
      • advice์— ๋”ฐ๋ผ Aspect์˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜ target ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

     

    ๐Ÿ“ Spring MVC์— AOP ์ ์šฉํ•˜๊ธฐ

    ๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ (Aspect)

    • ๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ๋ชจ๋“ˆ ์ƒ์„ฑ
    • @Aspect ์• ๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ์ž„์„ ์„ค์ •
    • @Pointcut ์• ๋…ธํ…Œ์ด์…˜๊ณผ, ์‹œ์ (@Before, @AfterReturning, @AfterThrowing, @After, @Around)์„ ์„ค์ •ํ•˜์—ฌ Advice ์ƒ์„ฑ

     

    Controller, Service, Repository ๋ชจ๋“  ๋ฉ”์†Œ๋“œ๋งˆ๋‹ค ๋กœ๊ทธ๋ฅผ ์ฐ๋Š” Aspect

    @Component
    @Aspect
    public class LoggingAspect {
    	
    	private final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);
    	
    	@Pointcut("execution(* com..*.controller.*.*(..)) || execution(* com..*.model..*.*(..))")
    	public void allMethod() {};
    	
    	@Before("allMethod()")
    	public void debug(JoinPoint jp) {
    		logger.debug("{} ๋ฉ”์†Œ๋“œ ์‹คํ–‰ - ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ {}",
    				jp.getSignature(),
    				jp.getArgs());
    	}
    }

     

    xml ์„ค์ •

    root-contex.xml

    • ์›น๊ณผ ๊ด€๋ จ๋œ ์„ค์ •์„ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ์„ค์ •์„ ํ•˜๋Š” xml
    • controller๋ฅผ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ๋นˆ ๋“ฑ๋ก
    • aop๋ฅผ ์œ„ํ•œ auto-proxy ์„ค์ •
    <context:component-scan base-package="com..model, com..util, com..aop"></context:component-scan>
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

     

    servlet-contex.xml

    • ์›น๊ณผ ๊ด€๋ จ๋œ ์„ค์ •์„ ํ•˜๋Š” xml
    • controller ๋นˆ ๋“ฑ๋ก
    • controller์— ๋Œ€ํ•ด aop๋ฅผ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•œ auto-proxy ์„ค์ •
    <context:component-scan base-package="com.*.controller" />
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

     

     

    ๐Ÿ“‘ AOP ์„ค์ •์— ๋”ฐ๋ฅธ ์ž‘๋™ ๋ฐฉ์‹

    ์ค‘๋ณต๋œ ๋นˆ์— ๋Œ€ํ•œ Spring MVC์˜ ๋นˆ ์„ ํƒ

    • ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ์™€ ๋ฃจํŠธ ์ปจํ…์ŠคํŠธ์— ๋นˆ์„ ์ค‘๋ณต์œผ๋กœ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์ด๋•Œ ์„œ๋ธ”๋ฆฟ ์ปจํ…์Šค์˜ ๋นˆ์ด ๋ฃจํŠธ ์ปจํ…์ŠคํŠธ์˜ ๋นˆ์„ ๊ฐ€๋ฆฐ๋‹ค.
      • ์ฆ‰ ๋™์ผํ•œ ์ด๋ฆ„์˜ ๋นˆ์ด ์ •์˜๋˜์–ด ์žˆ๋‹ค๋ฉด ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ์˜ ๋นˆ์„ ์šฐ์„ ์ ์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
    • ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ์—์„œ ๋นˆ์„ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋ฉด ๋ฃจํŠธ ์ปจํ…์ŠคํŠธ์˜ ๋นˆ์„ ์‚ฌ์šฉํ•œ๋‹ค.
      • ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ์— ํ•ด๋‹น ์ด๋ฆ„์˜ ๋นˆ์ด ์—†๋‹ค๋ฉด, ์Šคํ”„๋ง์€ ๋ฃจํŠธ ์ปจํ…์ŠคํŠธ์—์„œ ํ•ด๋‹น ์ด๋ฆ„์˜ ๋นˆ์„ ๊ฒ€์ƒ‰ํ•œ๋‹ค.
    • ๋นˆ์˜ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ์™€ ๋ฃจํŠธ ์ปจํ…์ŠคํŠธ์˜ ๋นˆ์„ ๊ตฌ์„ฑํ•  ๋•Œ ์ค‘๋ณต ์ •์˜์— ์ฃผ์˜ํ•ด์•ผํ•œ๋‹ค.
      • ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ํŠนํ™”๋œ ๋นˆ(ex controller)๋ฅผ ์ •์˜ํ•˜๊ณ , 
      • ๋ฃจํŠธ ์ปจํ…์ŠคํŠธ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด์—์„œ ๊ณต์œ ํ•ด์•ผํ•˜๋Š” ๋นˆ(ex service, repository)๋ฅผ ์ •์˜ํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.

     

     

    1. ๋ชจ๋“  ๋นˆ์— aop๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ

    # servlet-context.xml
    <context:component-scan base-package="com.*.controller" />
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    
    # root-context.xml
    <context:component-scan base-package="com..model, com..util, com..aop"></context:component-scan>
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    • ์œ„์˜ ์„ค์ •ํŒŒ์ผ ์ฒ˜๋Ÿผ ์„ค์ •ํ–ˆ์„ ๊ฒฝ์šฐ root, servlet context ๋ชจ๋‘ auto-proxy ์„ค์ •์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—
    • ๋ชจ๋“  ๋นˆ์— ๋Œ€ํ•ด์„œ proxy๋กœ ๊ฐ์‹ธ์ง„๋‹ค.
    • ๋”ฐ๋ผ์„œ ๋ชจ๋“  controller, service, repository ์š”์ฒญ ์‹œ์— ๋กœ๊น… ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
    • ์ด๋•Œ controller๋Š” ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ์˜ ๋นˆ, ๋‚˜๋จธ์ง€๋Š” ๋ฃจํŠธ ์ปจํ…์ŠคํŠธ์˜ ๋นˆ์„ ์‚ฌ์šฉํ•œ๋‹ค.

     

    2. controller ๋นˆ์— aop๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ๊ฒฝ์šฐ

    # servlet-context.xml
    <context:component-scan base-package="com.*.controller" />
    
    # root-context.xml
    <context:component-scan base-package="com..model, com..util, com..aop"></context:component-scan>
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    • ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ์—์„œ auto-proxy ์„ค์ •์„ ์ œ๊ฑฐํ•œ๋‹ค.
    • ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ์˜ ๋นˆ์„ ์‚ฌ์šฉํ•˜๋Š” controller๋Š” ํ”„๋ก์‹œ๋กœ ๊ฐ์‹ธ์ง€์ง€ ์•Š๊ณ 
    • ๋ฃจํŠธ ์ปจํ…์ŠคํŠธ์˜ ๋นˆ์„ ์‚ฌ์šฉํ•˜๋Š” ๋‚˜๋จธ์ง€ ๋นˆ๋“ค์— ๋Œ€ํ•ด์„œ๋Š” ๋ฃจํŠธ ์ปจํ…์ŠคํŠธ์˜ ์„ค์ •์— ๋”ฐ๋ผ auto-proxy๊ฐ€ ์ ์šฉ๋œ๋‹ค.

     

    3. ์„œ๋ธ”๋ฆฟ, ๋ฃจํŠธ ๋ชจ๋‘ controller ๋นˆ์„ ๊ฐ€์งˆ ๋•Œ aop๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ๊ฒฝ์šฐ

    # servlet-context.xml
    <context:component-scan base-package="com.*.controller" />
    
    # root-context.xml
    <context:component-scan base-package="com" />
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    • ๋ฃจํŠธ ์ปจํ…์ŠคํŠธ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ๋นˆ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
    • ์ด๋•Œ ์Šคํ”„๋ง์€ ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ์˜ controller ๋นˆ์„ ์„ ํƒํ•˜๊ณ  ๋‚˜๋จธ์ง€ ๋นˆ์€ ๋ฃจํŠธ ์ปจํ…์ŠคํŠธ์—์„œ ์„ ํƒํ•œ๋‹ค.
    • ๋”ฐ๋ผ์„œ ๋‚˜๋จธ์ง€ ๋นˆ์— ๋Œ€ํ•ด์„œ๋งŒ auto-proxy๊ฐ€ ์ ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— controller ๋นˆ์— ๋Œ€ํ•ด์„œ๋Š” aop๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.
      • controller์˜ ๋นˆ์ด ๋ฃจํŠธ ์ปจํ…์ŠคํŠธ์—๋„ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— auto-proxy ์„ค์ •์ด ์ ์šฉ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ
      • ์Šคํ”„๋ง์ด ์‚ฌ์šฉํ•˜๋Š” controller ๋นˆ์€ ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ์˜ ๋นˆ์ด๊ธฐ ๋•Œ๋ฌธ์— aop๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค

     

    ๐Ÿ’ก ๊ฒฐ๋ก 

    • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ์ž‘๋™ ๋ฐฉ์‹์— ๋”ฐ๋ผ aop ์„ค์ •์„ ์œ ์˜
    • ์ค‘๋ณต๋œ ๋นˆ ์„ค์ •์„ ํ”ผํ•˜๊ณ , aop๋ฅผ ์ ์šฉํ•  ์ปจํ…์ŠคํŠธ์— ๋Œ€ํ•ด auto-proxy ์„ค์ •

    ๋Œ“๊ธ€

Designed by Tistory.