๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
IT/WEB

[38์ผ์ฐจ] AOP/ aop concert project

by GWLEE 2022. 8. 12.

๐Ÿ’™2022-08-12๐Ÿ’™

AOP.pdf
0.66MB

 

• 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

๋Œ“๊ธ€