본문 바로가기

학원/스프링-학원

AOP(Aspect Oriented Programming)

728x90

관점 지향 프로그래밍이라는 뜻

 

 

공통과 핵심 기능으로 나눔

스프링에서는 주로 로그를 찍을 때 사용

 

AOP 의존설정

 

<!-- AOP -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>

 

오류가 발생하면 위의 내용을 붙여 넣으면 됨

 

AOP

 

 

공통에 해당하는 것이 Aspect

공통에서의 기능을 Advice

공통 기능을 적용시킬 대상을 Jointpoint

적용시킨 대상을 Pointcut

적용하는 행위를 Weaving

 

XML 기반의 AOP구현

 

Advice 종류

 

디펜던시스 안에 세팅해야 하는 것

 

<!-- AOP -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.7.4</version>
</dependency>
        
<!-- cglib -->
<dependency>
    <groupId>com.kenai.nbpwr</groupId>
    <artifactId>net-sf-cglib</artifactId>
    <version>2.1.3-201003011305</version>
</dependency> 

 

예제

<클래스>

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//Student 
package com.javalec.spring_9_1;
 
public class Student {
    private String name;
    private int age;
    private int gradeNum;
    private int classNum;
    
    //이 메서드가 핵심기능이 됨
    public void getSudentInfo() {
        System.out.println("이름 : "+getName());
        System.out.println("나이 : "+getAge());
        System.out.println("학년 : "+getGradeNum());
        System.out.println("반 : "+getClassNum());
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public int getGradeNum() {
        return gradeNum;
    }
    public void setGradeNum(int gradeNum) {
        this.gradeNum = gradeNum;
    }
    public int getClassNum() {
        return classNum;
    }
    public void setClassNum(int classNum) {
        this.classNum = classNum;
    }
}
 
//Worker 
package com.javalec.spring_9_1;
 
public class Worker {
    private String name;
    private int age;
    private String job;
    
    //핵심 기능이 됨
    public void getWorkerInfo() {
        System.out.println("이름 : "+getName());
        System.out.println("나이 : "+getAge());
        System.out.println("직업 : "+getJob());
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getJob() {
        return job;
    }
    public void setJob(String job) {
        this.job = job;
    }
    
}
 
//LogAop 
package com.javalec.spring_9_1;
 
import org.aspectj.lang.ProceedingJoinPoint;
 
//공통기능 클래스
public class LogAop {
    public Object loggerAop(ProceedingJoinPoint joinPoint) throws Throwable {
        //핵심기능 클래스의 메서드 정보를 가지고 옴
        String signatureStr = joinPoint.getSignature().toShortString();
        //공통기능 실행 - 핵심기능이 start 되었다..
        System.out.println(signatureStr+"is start.");
        long st = System.currentTimeMillis();
        //값을 리턴하기 위한 오브젝트 객체 생성
        Object obj = null;
        
        //try-catch문 안에서 실행
        try {
            //핵심기능 실행
            obj = joinPoint.proceed();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //공통기능 실행 - 핵심기능이 finsh 되었다..
            long et = System.currentTimeMillis();            
            System.out.println(signatureStr+"is finsh.");
            System.out.println(signatureStr+"경과시간 : "+(et-st));
        }
        //핵심기능을 실행시키는 객체를 리턴
        return obj;
    }
}
 
//MainCalss 
package com.javalec.spring_9_1;
 
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
 
public class MainCalss {
    public static void main(String[] args) {
        AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationCTX.xml");
        
        Student student = ctx.getBean("student",Student.class);
        //핵심기능
        student.getSudentInfo();
        
        Worker worker = ctx.getBean("worker",Worker.class);
        //핵심기능
        worker.getWorkerInfo();
        
        //핵심기능이 실행될 때 공통기능이 각각 실행됨
    }
}
cs

 

 

이런식으로  catch를 생략하고  try에서 바로 리턴을 해서 사용할 수도 있음

 

<xml>

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
 
    <bean class="com.javalec.spring_9_1.LogAop" id="logAop"></bean>
    
    <aop:config>
        <aop:aspect id="logger" ref="logAop">
                                    <!-- wihtin으로 범위지정 - 패키지 -->
            <aop:pointcut expression="within(com.javalec.spring_9_1.*)" id="publicM"/>
            <aop:around method="loggerAop" pointcut-ref="publicM"/>
        </aop:aspect>
    </aop:config>
    
    <bean class="com.javalec.spring_9_1.Student" id="student">
        <property name="name" value="홍길동"></property>
        <property name="age" value="10"></property>
        <property name="gradeNum" value="3"></property>
        <property name="classNum" value="5"></property>
    </bean>
    
    <bean class="com.javalec.spring_9_1.Worker" id="worker">
        <property name="name" value="홍길순"></property>
        <property name="age" value="35"></property>
        <property name="job" value="개발자"></property>
    </bean>
</beans>
cs

 

문제

 

 

<클래스>

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//Professor 
package com.javalec.spring_ex9_1;
 
public class Professor {
    private String name;
    private String subject;
    private int age;
    
    public void getProfessorInfo() {
        System.out.println("이름 : "+getName());
        System.out.println("나이 : "+getAge());
        System.out.println("과목 : "+getSubject());
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
 
//Singer 
package com.javalec.spring_ex9_1;
 
public class Singer {
    private String name;
    private String song;
    private int member;
    
    public void getSingerInfo() {
        System.out.println("이름 : "+getName());
        System.out.println("멤버 : "+getMember());
        System.out.println("노래 : "+getSong());
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSong() {
        return song;
    }
    public void setSong(String song) {
        this.song = song;
    }
    public int getMember() {
        return member;
    }
    public void setMember(int member) {
        this.member = member;
    }
}
 
//LogAop
package com.javalec.spring_ex9_1;
 
import org.aspectj.lang.ProceedingJoinPoint;
 
public class LogAop {
    public Object loggerAop(ProceedingJoinPoint joinPoint) throws Throwable {
        String str = joinPoint.getSignature().toShortString();
        System.out.println("@@@### start====>"+str);
        Object obj = null;
        
        try {
            obj = joinPoint.proceed();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            System.out.println("@@@### end====>"+str);
        }
        return obj;
    }
}
 
//MainClass 
package com.javalec.spring_ex9_1;
 
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
 
public class MainClass {
    public static void main(String[] args) {
        AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationCTX.xml");
        
        Professor professor = ctx.getBean("professor", Professor.class);
        professor.getProfessorInfo();
        
        Singer singer = ctx.getBean("singer",Singer.class);
        singer.getSingerInfo();
        
    }
}
cs

 

<xml>

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
 
    <bean class="com.javalec.spring_ex9_1.LogAop" id="logAop"></bean>
    
    <aop:config>
        <aop:aspect id="logger" ref="logAop">
            <aop:pointcut expression="within(com.javalec.spring_ex9_1.*)" id="publicM"/>
            <aop:around method="loggerAop" pointcut-ref="publicM"/>
        </aop:aspect>
    </aop:config>
    
    <bean class="com.javalec.spring_ex9_1.Professor" id="professor">
        <property name="name" value="김교수"></property>
        <property name="age" value="33"></property>
        <property name="subject" value="스프링"></property>
    </bean>
    
    <bean class="com.javalec.spring_ex9_1.Singer" id="singer">
        <property name="name" value="방탄소년단"></property>
        <property name="member" value="7"></property>
        <property name="song" value="다이너마이트"></property>
    </bean>
</beans>
cs

 

@Aspect를 이용한 AOP 구현

 

xml을 사용한 것과 어노테이션을 사용한 것 비교

 

 

- public void 형태의 모든 get메소드 사용

- ex안에 있는 모든 파라미터가 없는 메소드

- ex 하위 패키지에 있는 모든 파라미터가 없는 메소드

 

예제

<클래스>

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//LogAop
package com.javalec.spring_10_1;
 
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
 
//앞선 예제에서 xml에서 설정했던 값들이 여기에서 세팅됨
 
//공통기능이라고 명시
@Aspect
public class LogAop {
    //범위
    @Pointcut("within(com.javalec.spring_10_1.*)")
    private void pointCutMethod() {}
    
    //범위값 설정
    @Around("pointCutMethod()")
    public Object loggerAop(ProceedingJoinPoint joinPoint) throws Throwable {
        //핵심기능 클래스의 메서드 정보를 가지고 옴
        String signatureStr = joinPoint.getSignature().toShortString();
        //공통기능 실행 - 핵심기능이 start 되었다..
        System.out.println(signatureStr+"is start.");
        long st = System.currentTimeMillis();
        //값을 리턴하기 위한 오브젝트 객체 생성
        Object obj = null;
        
        try {
            //핵심기능 실행
            obj = joinPoint.proceed();
            return obj;
        }finally {
            //공통기능 실행 - 핵심기능이 finsh 되었다..
            long et = System.currentTimeMillis();            
            System.out.println(signatureStr+"is finsh.");
            System.out.println(signatureStr+"경과시간 : "+(et-st));
        }
    }
}
cs

 

 

<xml>

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
    
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    <bean class="com.javalec.spring_10_1.LogAop" id="logAop"></bean>
    
    <bean class="com.javalec.spring_10_1.Student" id="student">
        <property name="name" value="홍길동"></property>
        <property name="age" value="10"></property>
        <property name="gradeNum" value="3"></property>
        <property name="classNum" value="5"></property>
    </bean>
    
    <bean class="com.javalec.spring_10_1.Worker" id="worker">
        <property name="name" value="홍길순"></property>
        <property name="age" value="35"></property>
        <property name="job" value="개발자"></property>
    </bean>
</beans>
cs

 

다른 파일들(Student, Worker, MainClass)은 앞선 예제와 동일

 

문제

 

 

<클래스>

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//Car
package com.javalec.spring_ex10_1;
 
public class Car {
    private String company;
    private String product;
    private int capRank;
    
    public void getCarInfo() {
        System.out.println("회사 : "+getCompany());
        System.out.println("시총 : "+getCapRank());
        System.out.println("제품 : "+getProduct());
    }
    
    public String getCompany() {
        return company;
    }
    public void setCompany(String company) {
        this.company = company;
    }
    public String getProduct() {
        return product;
    }
    public void setProduct(String product) {
        this.product = product;
    }
    public int getCapRank() {
        return capRank;
    }
    public void setCapRank(int capRank) {
        this.capRank = capRank;
    }
}
 
//Graphic
package com.javalec.spring_ex10_1;
 
public class Graphic {
    private String company;
    private int capRank;
    
    public void getGraphicInfo() {
        System.out.println("회사 : "+getCompany());
        System.out.println("시총 : "+getCapRank());
    }
    
    public String getCompany() {
        return company;
    }
    public void setCompany(String company) {
        this.company = company;
    }
    public int getCapRank() {
        return capRank;
    }
    public void setCapRank(int capRank) {
        this.capRank = capRank;
    }
}
 
//LogAop 
package com.javalec.spring_ex10_1;
 
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
 
@Aspect
public class LogAop {
    @Pointcut("within(com.javalec.spring_ex10_1.*)")
    private void pointCutMethod() {}
    @Around("pointCutMethod()")
    public Object loggerAop(ProceedingJoinPoint joinPoint)throws Throwable {
        String str = joinPoint.getSignature().toShortString();
        System.out.println("@@@###start===>"+str);
        Object obj =null;
        
        try {
            obj = joinPoint.proceed();
            return obj;
        } finally {
            System.out.println("@@@###end===>"+str);
        }
    }
}
 
//MainClass 
package com.javalec.spring_ex10_1;
 
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
 
public class MainClass {
    public static void main(String[] args) {
        AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationCTX.xml");
        
        Car car = ctx.getBean("car",Car.class);
        car.getCarInfo();
        
        Graphic graphic = ctx.getBean("graphic",Graphic.class);
        graphic.getGraphicInfo();
    }
}
cs

 

<xml>

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
 
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    <bean class="com.javalec.spring_ex10_1.LogAop" id="logAop"></bean>
    
    <bean class="com.javalec.spring_ex10_1.Car" id="car">
        <property name="company" value="테슬라"></property>
        <property name="capRank" value="6"></property>
        <property name="product" value="모델S"></property>
    </bean>
    
    <bean class="com.javalec.spring_ex10_1.Graphic" id="graphic">
        <property name="company" value="엔비디아"></property>
        <property name="capRank" value="7"></property>
    </bean>
 
</beans>
cs

 

 

728x90

'학원 > 스프링-학원' 카테고리의 다른 글

스프링 MVC 게시판 - 가입, 수정, 삭제  (0) 2022.05.18
MVC 기초  (0) 2022.05.16
외부 파일을 이용한 설정  (0) 2022.05.11
생명주기(LIFE CYCLE)와 범위(SCOPE)  (0) 2022.05.11
DI 설정 방법  (0) 2022.05.10