[Spring] AOP(01)


AOP(Aspect Oriented Programing)

๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

ํŠน์ • ํ–‰์œ„๋ฅผ ํŠน์ • ์‹œ์ ๋งˆ๋‹ค ์‹คํ–‰ํ•  ๊ฒฝ์šฐ ์‚ฌ์šฉํ•œ๋‹ค.

AOP๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์—” 2๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

  1. java ์ฝ”๋“œ๋กœ ๊ตฌํ˜„
  2. spring์—์„œ ์ œ๊ณตํ•˜๋Š” aspect ์‚ฌ์šฉ



1. java ์ฝ”๋“œ๋กœ ๊ตฌํ˜„

์–ด๋–ค ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋“  proxy ํด๋ž˜์Šค๋ฅผ ๋ฌด์กฐ๊ฑด ์ง€๋‚˜๊ฐ€๋„๋ก ์„ค์ •ํ•ด์„œ ํŠน์ • ํ–‰์œ„๋ฅผ ํ•˜๋„๋ก ์„ค์ •

์–ด๋–ค ๊ฐ์ฒด์ด๋“  usingComputer() ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ง์ „์— โ€œ๋ถ€ํŒ… ํ›„ [๋น„๋ฐ€๋ฒˆํ˜ธ] ์ž…๋ ฅํ•˜์—ฌ ๋กœ๊ทธ์ธโ€ ์„ ์ถœ๋ ฅํ•ด๋ณด์ž.

  1. ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ–๊ณ ์žˆ๋Š” interface Person์„ ์ƒ์„ฑํ•œ๋‹ค. ๋ชจ๋“  ํด๋ž˜์Šค๋Š” ํ•ด๋‹น interface๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.
     public interface Person {
         public int usingComputer(String pwd);
     }
    
  2. Person์„ ๊ตฌํ˜„ํ•˜๋Š” program ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
     public class Program implements Person{
         @Override
         public int usingComputer(String pwd) {		
             try {
                 // ํ•ต์‹ฌ ๊ธฐ๋Šฅ
                 System.out.println("[๊ฒŒ์ž„์„ ํ•œ๋‹ค.]");
             }catch(Exception e) {
                 if(e.getMessage().equals("์˜ค๋ฅ˜!")) {
                     System.out.println("AS๋ฅผ ์‹ ์ฒญํ•œ๋‹ค.");
                 }
             }
             System.out.println("์ปดํ“จํ„ฐ ์ข…๋ฃŒ");
             return 100; 
         }
     }
    
  3. Person์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ชจ๋“  ํด๋ž˜์Šค๊ฐ€ ์ง€๋‚˜๊ฐ€๋Š” Proxy ํด๋ž˜์Šค ์„ ์–ธ
     public class Proxy implements Person {
         private Person delegate;
    
         public Proxy(Person delegate) {
             this.delegate = delegate;
         }
    
         @Override
         public int usingComputer(String pwd) {
             System.out.println("๋ถ€ํŒ… ํ›„ " + pwd + "์ž…๋ ฅํ•˜์—ฌ ๋กœ๊ทธ์ธ");
             return delegate.usingComputer(pwd);
         }
     }
    
  4. ์‹คํ–‰ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธ
     public class Main {
         public static void main(String[] args) {
             Person p1 = new Proxy(new Program());
             int useT1 = p1.usingComputer("1234");
             System.out.println(p1.getClass().getName() + "์ด์šฉ์‹œ๊ฐ„:" + useT1);
         }
     }
    
    • ์‹คํ–‰ ๊ฒฐ๊ณผ

        ๋ถ€ํŒ… ํ›„ 1234์ž…๋ ฅํ•˜์—ฌ ๋กœ๊ทธ์ธ
        [๊ฒŒ์ž„์„ ํ•œ๋‹ค.]
        ์ž‘์—… ์ข…๋ฃŒ
        ์ปดํ“จํ„ฐ ์ข…๋ฃŒ
        aop01.Proxy์ด์šฉ์‹œ๊ฐ„:100
      

[Main] -> [Proxy] -> [Program] ์ˆœ์„œ๋กœ ์ง„ํ–‰๋˜๋ฉฐ usingComputer()๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์—๋Š” ๋ฌด์กฐ๊ฑด Proxy์˜ ์ถœ๋ ฅ๋ฌธ์ด ์‹คํ–‰๋œ๋‹ค.



2. aspect ์ด์šฉ

spring์—์„œ ์ œ๊ณตํ•˜๋Š” aspect๋ฅผ ํ†ตํ•ด ํŠน์ • ์กฐ๊ฑด์„ ์„ค์ •ํ•œ ํ›„ before, after ๋“ฑ์„ ํ†ตํ•ด์„œ ์–ด๋–ค ์‹œ์ (joinPoint)์— ํ–‰์œ„๋ฅผ ์‹คํ–‰ํ•  ๊ฒƒ์ธ์ง€ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. xml์„ ์ˆ˜์ •ํ•œ๋‹ค.
    • pom.xml์— aop์— ๋Œ€ํ•œ dependency๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.0.8.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>
      
    • ์„ค์ • xml ํŒŒ์ผ์— aop ํƒœ๊ทธ๋ฅผ ๋„ฃ๋Š”๋‹ค.
        <beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:context="http://www.springframework.org/schema/context"
            xmlns:aop="http://www.springframework.org/schema/aop"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context.xsd
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop.xsd">
      
            <!-- bean ๊ฐ์ฒด ์ค‘ @Aspect ๋ฅผ ์ฐพ์•„ aop๋กœ ์ธ์ง€ํ•œ๋‹ค. -->
            <aop:aspectj-autoproxy />
      
            <bean id="myAspect" class="aop02.MyAspect" />
            <bean id="programmer" class="aop02.Programmer" />
        </beans>
      
  2. aop๋ฅผ ์‚ฌ์šฉํ•  ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
     @Aspect
     public class MyAspect {
         @Before("execution(public int aop02.*.usingComputer(String))")
         public void bootingAndLogin(JoinPoint jp) {
             String pwd = (String) jp.getArgs()[0];
             System.out.println("์ปดํ“จํ„ฐ ๋ถ€ํŒ… ์‹œ์ž‘. " + pwd + " ์ž…๋ ฅ ๋กœ๊ทธ์ธ");
         }
     }
    
    • @Before - ์ง€์ •ํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ํ•˜๋‹จ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. (Advice types์— ๋Œ€ํ•œ ์ •๋ฆฌ ๋ณด๊ธฐ)
    • "execution(* usingComputer(..))" - ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฌด์—‡์„ ๋ฐ›๋“  ๋ชจ๋“  ํด๋ž˜์Šค์˜ usingComputer() ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ ์ง€์ ์œผ๋กœ ์ง€์ •ํ•œ๋‹ค.
    • JoinPoint - joinํ•œ ์ง€์ ์„ ์˜๋ฏธํ•œ๋‹ค.
      • join๋œ ์ง€์ ์—์„œ ์‹คํ–‰๋œ ๋ฉ”์„œ๋“œ์™€ ์ „๋‹ฌ๋œ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋“ฑ ๋‹ค์–‘ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.
      • getArgs() - ์ „๋‹ฌ๋œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ Object[]๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  3. ์‹คํ–‰ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธ
    • Person interface๋ฅผ ๊ตฌํ˜„ํ•œ Programmer ํด๋ž˜์Šค ์ƒ์„ฑ
        public class Programmer implements Person{
            public int usingComputer(String pwd) {				
                try {
                    //ํ•ต์‹ฌ๊ธฐ๋Šฅ
                    System.out.println("[์ฝ”๋”ฉ์„ ํ•œ๋‹ค.]");
                }catch(Exception e) {
                    if(e.getMessage().equals("์˜ค๋ฅ˜!")) {
                        System.out.println("AS๋ฅผ ์‹ ์ฒญํ•œ๋‹ค.");
                    }
                }
                System.out.println("์ปดํ“จํ„ฐ ์ข…๋ฃŒ");
                return 200;
            }
        }
      
    • main
        public class Main {
            public static void main(String[] args) {
                ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("config.xml");
      				
                // interface๋ฅผ ๊ตฌ์ฒดํ™”ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์œ„ ํด๋ž˜์Šค๋กœ get์„ ํ•ด์•ผํ•œ๋‹ค.
                Person p1 = ctx.getBean("programmer", Person.class);			int useT1 = p1.usingComputer("1234");
                System.out.println(p1.getClass().getName() + "์ด์šฉ์‹œ๊ฐ„:" + useT1);
            }
        }
      
    • ์‹คํ–‰ ๊ฒฐ๊ณผ
        ์ปดํ“จํ„ฐ ๋ถ€ํŒ… ์‹œ์ž‘. 1234 ์ž…๋ ฅ ๋กœ๊ทธ์ธ
        [์ฝ”๋”ฉ์„ ํ•œ๋‹ค.]
        ์ปดํ“จํ„ฐ ์ข…๋ฃŒ
        com.sun.proxy.$Proxy5์ด์šฉ์‹œ๊ฐ„:200
      





ยฉ 2022. by Yejin Ha

Powered by JihyunRyu