๐2022-08-12๐
• AOP (Aspect Oriented Programming)
• cross-cutting concerns - ๋ก๊น , ๋ณด์, ํธ๋์ญ์ ๊ด๋ฆฌ ๋ฑ ๋๋ถ๋ถ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ๋๋ ๊ธฐ๋ฅ
- ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฌ ๋ถ๋ถ์ ๊ฑธ์ณ ์๋ ๊ธฐ๋ฅ
- AOP๋ ์ด๋ฌํ cross-cutting concerns ์ ๋ถ๋ฆฌ๋ฅผ ์ํ ๊ฒ
- AOP์ ๋ชฉ์ ์ cross-cutting concerns ์ ์ด์ ์ํฅ์ ๋ฐ๋ ๊ฐ์ฒด ๊ฐ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๋ ๊ฒ
Advice ๋ญ๊ฐ ํด์ผํ ์์
1. AOP ์ฉ์ด ์ ์
1) Advice โช Aspect ๊ฐ ํด์ผ ํ ์์
โช Aspect ์ "What", "When" ์ ์ ์
โช ์คํ๋ง aspect ๊ฐ ์ง์ํ๋ advice before :
advice ๋์ ๋ฉ์๋๊ฐ ํธ์ถ๋๊ธฐ ์ ์ advice ๊ธฐ๋ฅ์ ์ํ
after : ๊ฒฐ๊ณผ์ ์๊ด์์ด advice ๋์ ๋งค์๋๊ฐ ์๋ฃ๋ ํ์ advice ๊ธฐ๋ฅ์ ์ํ
after-returning : advice ๋์ ๋งค์๋๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋ ํ์ advice ๊ธฐ๋ฅ์ ์ํ
after-throwing : advice ๋์ ๋ฉ์๋๊ฐ exception์ ๋ฐ์ ์ํจ ํ์ advice ๊ธฐ๋ฅ์ ์ ํ
around : advice๊ฐ advice ๋์ ๋ฉ์๋๋ฅผ ๊ฐ์ธ์ advice ๋์ ๋ฉ์๋ ํธ์ถ ์ /ํ์ ๊ธฐ ๋ฅ์ ์ํ
2) Join Points
โช Advice๋ฅผ ์ ์ฉํ ์ ์๋ ๊ณณ ์ฌ๋ฌ ๊ณณ์ด๋ผ s ๋ถ์
โช ์ ํ๋ฆฌ์ผ์ด์ ์คํ์ aspect๋ฅผ ๋ผ์ ๋ฃ์ ์ ์๋ ์ง์
โช ๋ฉ์๋ ํธ์ถ, ์์ธ ๋ฐ์, ํ๋ ๊ฐ ์์ ๋ฑ
3) Pointcuts
โช Aspect ๊ฐ advice ํ Join Points์ ์์ญ์ ์ ํํ๋ ์ญํ
โช Aspect๊ฐ "์ด๋์" ํ ์ง๋ฅผ ์ ์
โช Advice๊ฐ weaving ๋์ด์ผ ํ๋ ํ๋ ์ด์์ Join Points๋ฅผ ์ ์
โช ํด๋์ค๋ ๋ฉ์๋ ๋ช ์ ์ง์ ํ ์ ๋ ์๊ณ , ์ ๊ท ํํ์์ ์ ์ ํ ์๋ ์์
์คํ๋ง์ ๋งค์๋ join point ๋ง ์ง์ ํ๋์ ์ง์ํ์ง ์๊ณ ๋ฉ์๋์๋ง ์ง์ํ๋ค.
https://mvnrepository.com/artifact/org.aspectj/aspectjrt/1.9.9.1
https://mvnrepository.com/artifact/org.aspectj/aspectjweaver
pom.xml (runtime์ ์ง์ฐ๊ธฐ )
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gyuone</groupId>
<artifactId>aopProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.22</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.9.1</version>
</dependency>
</dependencies>
</project>
com.gyuone\
concert
Audience.java
package com.gyuone.concert;
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 Audience {
@Pointcut("execution(* com.gyuone.concert.Performance.perform(..))")
public void performance() {}
// @Before("execution(* com.gyuone.concert.Performance.perform(..))")
// @Before("performance()")
// public void silenceCellPhones() {
// System.out.println("ํด๋ํฐ์ ๊บผ์ฃผ์ธ์!");
// }
// @Before("execution(* com.gyuone.concert.Performance.perform(..))")
// @Before("performance()")
// public void takeSeats() {
// System.out.println("๋ชจ๋ ์๋ฆฌ์ ์์์ฃผ์ธ์!");
// }
// @AfterReturning("execution(* com.gyuone.concert.Performance.perform(..))")
// @AfterReturning("performance()")
// public void applause() {
// System.out.println("๋ฐ์~~~~~ ์ง์ง์ง!!");
// }
// @AfterThrowing("execution(* com.gyuone.concert.Performance.perform(..))")
// @AfterThrowing("performance()")
// public void demandRefund() {
// System.out.println("ํ๋ถํด๋ฌ๋ผ~~~~~~");
// }
@Around("performance()")
public void watchPerformance(ProceedingJoinPoint jp) {
try {
System.out.println("ํด๋ํฐ์ ๊บผ์ฃผ์ธ์!");
System.out.println("๋ชจ๋ ์๋ฆฌ์ ์์์ฃผ์ธ์!");
jp.proceed();
System.out.println("๋ฐ์~~~~~ ์ง์ง์ง!!");
} catch (Throwable e) {
// TODO: handle exception
System.out.println("ํ๋ถํด๋ฌ๋ผ~~~~~~");
}
}
}
IUConcert.java
package com.gyuone.concert;
import org.springframework.stereotype.Component;
@Component("iuConcert")
public class IUConcert implements Performance {
@Override
public void perform() throws Exception {
// TODO Auto-generated method stub
System.out.println("๋
ธ๋๋ ์ ๋ถ๋ฌ, ๋ง์จ๋ ๊ณ ์, ์ฐ๊ธฐ๋ ์ ํด, ๋์ฒด ๋ชปํ๋๊ฒ ๋ญ๋ฐ????");
throw new Exception();
}
}
Performance.java (์ธํฐํ์ด์ค)
package com.gyuone.concert;
public interface Performance {
public void perform() throws Exception;
}
PianoConcert.java
package com.gyuone.concert;
import org.springframework.stereotype.Component;
@Component("pianoConcert")
public class PianoConcert implements Performance{
@Override
public void perform() throws Exception {
// TODO Auto-generated method stub
System.out.println("ํผ์๋
ธ ์ฐ์ฃผ");
}
}
config
ConcertConfig.java
package com.gyuone.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import com.gyuone.concert.Audience;
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan(basePackages= {"com.gyuone.concert"})
public class ConcertConfig {
@Bean
public Audience audience() {
return new Audience();
}
}
main
ConcertMain.java
package com.gyuone.main;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import com.gyuone.concert.IUConcert;
import com.gyuone.concert.Performance;
import com.gyuone.concert.PianoConcert;
import com.gyuone.config.ConcertConfig;
public class ConcertMain {
public static void main(String[] args) throws Exception{
AbstractApplicationContext ctx = new AnnotationConfigApplicationContext(ConcertConfig.class);
System.out.println("-------------------<PiaonoConcert>-------------------");
Performance performance = ctx.getBean("pianoConcert", PianoConcert.class);
performance.perform();
System.out.println("-------------------<IU Concert>-------------------");
performance = ctx.getBean("iuConcert", IUConcert.class);
performance.perform();
ctx.close();
}
}
Aspect ์ ์
- ๊ณต์ฐ์ ๊ด๊ฐ ์์ด๋ ์ด๋ฃจ์ด ์ง ์ ์์
- ๊ณต์ฐ ๊ด์ ์์, ๊ด๊ฐ์ ์ค์ํ์ง๋ง ๊ณต์ฐ ๊ทธ ์์ฒด์ ํต์ฌ ๊ธฐ๋ฅ์ ์๋
- ๊ด๊ฐ์ ๊ณต์ฐ์ ์ ์ฉํ ์ ์๋ aspect๋ก ์ ์
โช perform ๋งค์๋๊ฐ ์คํ๋ ๋๋ง๋ค advice๋ฅผ ํ๊ธฐ ์ํด ์ฌ์ฉํ ์ ์๋ pointcut ํํ์
execution(* com.adacho.concert.Performance.perform(..))
โช execution ์ง์ ์๋ฅผ ์ด์ฉํ์ฌ Performance์ perform() ๋งค์๋๋ฅผ ์ ํ
โช ๋งค์๋ ๋ช ์ธ์ "*" ๋ ๋ฆฌํด ํ์ ์ด ๋ฌด์์ด๋ ๋๋ค๋ ํ์
โช perform ๋งค์๋์ ์ธ์ ๋ชฉ๋ก์ (..) ๋ ์ธ์๊ฐ ๋ฌด์์ด ์ ๋ฌ๋์ด๋ perform() ๋งค์๋๋ฅผ ์ ํํ๋ค๋ ์๋ฏธ
โช Pointcut์ ๋ฒ์๋ฅผ concert ํจํค์ง๋ก๋ง ์ ํํ๊ณ ์ ํ๋ค๋ฉด within() ์ง์ ์๋ฅผ ์ฌ์ฉํ ์ ์์
execution(* com.adacho.concert.Performance.perform(..) && within(com.adacho.concert.*))
ConcertConfig.java
@EnableAspectJAutoProxy
โช @EnableAspectJAutoProxy(proxyTargetClass = true)
@Aspect ์ ๋ํ
์ด์
๋ ํด๋์ค๋ฅผ ์คํ์๊ฐ์ ์๋์ผ๋ก ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ฒ ํจ
- Aspect ๋์ ๊ฐ์ฒด(piano concert)๊ฐ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ํด๋์ค ์ด๋ฉด
- proxy ๊ฐ์ฒด๋ ํด๋น ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ฒ ์์ฑ๋๋ฏ๋ก getBean() ๋งค์๋๋ก
- ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ค๋ ค๊ณ ์๋ํ ๋ ํ์ ์ด ๋ง์ง ์์์ ์๋ฌ๊ฐ ๋ฐ์ํ๊ฒ ๋จ,
- ์ด ๋ proxy ๊ฐ์ฒด๋ฅผ ๋์ ํด๋์ค๋ฅผ ์ง์ ์์๋ฐ์ ๋ง๋ค๊ฒ ํ์ฌ์ผ ํ๋๋ฐ ์ด ๋ ์ฌ์ฉํ๋ ๊ฒ์ด proxyTargetClass = true ์
'IT > WEB' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[38์ผ์ฐจ] ๊ฒ์ํ ๋ง๋ค๊ธฐ (0) | 2022.08.12 |
---|---|
[38์ผ์ฐจ] FirstSpring (0) | 2022.08.12 |
[37์ผ์ฐจ] AutoDi (0) | 2022.08.11 |
[37์ผ์ฐจ] dISample project (0) | 2022.08.11 |
[37์ผ์ฐจ] Spring Bean (0) | 2022.08.11 |
๋๊ธ