‡๐Ÿ‘ฉ‍๐Ÿ’ป ‡/ºSpring

[Spring] AOP(Aspect Oriented Programming) ๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

Trudy | ์†ก์—ฐ 2023. 12. 27. 14:29

๐Ÿ“AOP๋ž€?

AOP๋Š” Aspect Oriented Programming์˜ ์•ฝ์ž๋กœ ๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋ผ๊ณ  ํ•œ๋‹ค. 
๊ด€์  ์ง€ํ–ฅ์€ ์‰ฝ๊ฒŒ ๋งํ•ด ์–ด๋–ค ๋กœ์ง์„ ๊ธฐ์ค€์œผ๋กœ ํ•ต์‹ฌ์ ์ธ ๊ด€์ , ๋ถ€๊ฐ€์ ์ธ ๊ด€์ ์œผ๋กœ ๋‚˜๋ˆ„์–ด์„œ ๋ณด๊ณ  
๊ทธ ๊ด€์ ์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ๊ฐ ๋ชจ๋“ˆํ™”ํ•˜๊ฒ ๋‹ค๋Š” ๊ฒƒ
์ด๋•Œ, ๋ชจ๋“ˆํ™”๋ž€ ์–ด๋–ค ๊ณตํ†ต๋œ ๋กœ์ง์ด๋‚˜ ๊ธฐ๋Šฅ์„ ํ•˜๋‚˜์˜ ๋‹จ์œ„๋กœ ๋ฌถ๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค. 
 


๐Ÿ“AOP ๊ด€๋ จ ์šฉ์–ด

 

Aspect

ํฉ์–ด์ง„ ๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ชจ๋“ˆํ™”ํ•˜์—ฌ ํ•˜๋‚˜๋กœ ๋ฌถ๋Š” ๊ฒƒ, ์ผ๋ฐ˜์ ์œผ๋กœ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ๋ชจ๋“ˆํ™”.

 

Target ; Aspect์„ ์ ์šฉํ•˜๋Š” ๊ณณ

Aspect๋ฅผ ์ ์šฉํ•˜๋Š” ๊ณณ (ํด๋ž˜์Šค, ๋ฉ”์„œ๋“œ ๋“ฑ)

 

Advice ; ์šฐ๋ฆฌ๊ฐ€ ๊ฐœ๋ฐœํ•ด์•ผํ•˜๋Š” ๊ฒƒ

์‹ค์งˆ์ ์œผ๋กœ ์–ด๋–ค ์ผ์„ ํ•ด์•ผํ•  ์ง€์— ๋Œ€ํ•ด ์ •์˜ํ•œ ๊ฒƒ, ์‹ค์งˆ์ ์ธ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ ๊ตฌํ˜„์ฒด

 

JointPoint ; ์–ด๋–ค ์‹œ์ ์— ์ ์šฉ์‹œํ‚ฌ์ง€. ์‹œ์ !

๋ฉ”์„œ๋“œ ์ง„์ž… ์ง€์ , ์ƒ์„ฑ์ž ํ˜ธ์ถœ ์‹œ์ , ํ•„๋“œ์—์„œ ๊ฐ’์„ ๊บผ๋‚ด์˜ฌ ๋•Œ ๋“ฑ๊ณผ ๊ฐ™์ด Advice๊ฐ€ ์ ์šฉ๋  ์œ„์น˜, ๋ผ์–ด๋“ค ์ˆ˜ ์žˆ๋Š” ์ง€์ . 

 

PointCut; ์ ์šฉํ•  ๋ถ€๋ถ„

JointPoint์˜ ์ƒ์„ธํ•œ ์ŠคํŽ™์„ ์ •์˜ํ•œ ๊ฒƒ. 

 

 


๐Ÿ“๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€

pom.xml

							<!--AOP-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>

 

๐Ÿ“AOP ์‚ฌ์šฉ ์˜ˆ์ œ

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

SimpleAop.java

package com.example.demo.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;

//AOP๊ฐ€ ์ ์šฉ๋˜๋Š” ๊ณณ์€ ์Šคํ”„๋ง์˜ ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋˜๋Š” ์• ๋“ค์ด๋‹ค.
//๋”ฐ๋ผ์„œ ์ด ํด๋ž˜์Šค๋„ @Component๋ฅผ ํ†ตํ•ด ๋นˆ์„ ๋‹ฌ์•„์ค˜์•ผ ํ•œ๋‹ค.

//๊ด€์ ์ด๋‹ค ๋ผ๋Š” ์ง€์ •์€ @Aspect ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ํ•œ๋‹ค.
@Component
@Aspect
public class SimpleAop {
    //Pointcut์œผ๋กœ ์ ์šฉํ•  ๋ถ€๋ถ„์„ ์ง€์ •ํ•ด์คŒ
    //member ํŒจํ‚ค์ง€ ์•„๋ž˜ ๋ชจ๋“  ํŒŒ์ผ๋“ค์„ ์ง€์ •
    @Pointcut("execution(* com.example.demo.member..*.*(..))")
    private void cut(){
        System.out.println("์ปท");
    }

    //๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์„ ์ง€์ •
    @Before("cut()")
    public void before(JoinPoint joinPoint){
        Method method = ((MethodSignature)joinPoint.getSignature()).getMethod();

        System.out.println(method.getName() + "๋ฉ”์†Œ๋“œ ์‹คํ–‰ ์ „ ");
    }

    //๋ฉ”์†Œ๋“œ ์‹คํ–‰ ํ›„
    //๋ฉ”์†Œ๋“œ ์ง€์ •, ๋ฐ˜ํ™˜ ๊ฐ’ ์ง€์ •
    @AfterReturning(value = "cut()", returning = "returnObject")
    public void afterReturning(JoinPoint joinPoint, Object returnObject) {
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        System.out.println(returnObject.getClass().getName() + "๋ฐ˜ํ™˜ ");
        System.out.println(method.getName() + "๋ฉ”์†Œ๋“œ ์‹คํ–‰ ํ›„ ");

    }
}

 

@PointCut:

์ ์šฉ๋  ๋ถ€๋ถ„์„ ์ง€์ •

 

@Before:

๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „ ์‹œ์ ์—์„œ ์ฒ˜๋ฆฌ

 

@AfterReturning:

๋ฉ”์†Œ๋“œ ์‹คํ–‰ ํ›„ ์‹œ์ ์—์„œ ์ฒ˜๋ฆฌ 

== ์˜ˆ์ œ ์‹ค์Šต์„ ์œ„ํ•œ Model, Controller, Service, Repository ==

 

[Model] Member.java

package com.example.demo.member.model;

import lombok.*;
import javax.persistence.*;

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Builder
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;

    @Column(unique = true, nullable = false)
    String email;
    String password;
}

 

 

[Controller] MemberController.java

package com.example.demo.member.controller;

import com.example.demo.member.service.MemberService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/member")
public class MemberController {
    private final MemberService memberService;

    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }

    @RequestMapping(method = RequestMethod.POST, value = "/login")
    public ResponseEntity login(){
        memberService.loginService();
        return ResponseEntity.ok().body("login process");
    }

    @RequestMapping(method = RequestMethod.POST, value = "/signup")
    public ResponseEntity signup(String email, String password){
        memberService.signupService(email, password);
        return ResponseEntity.ok().body("signup process");
    }
}

 

[Service] MemberService.java

package com.example.demo.member.service;

import com.example.demo.member.model.Member;
import com.example.demo.member.repository.MemberRepository;
import org.springframework.stereotype.Service;

@Service
public class MemberService {
    MemberRepository memberRepository;

    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    public void signupService(String email, String password) {
        memberRepository.save(Member.builder()
                .email(email)
                .password(password)
                .build());
    }

    public void loginService() {
        System.out.println("๋ฉค๋ฒ„ ์„œ๋น„์Šค์˜ ๋กœ๊ทธ์ธ ๋ฉ”์†Œ๋“œ ์‹คํ–‰");
    }
}

 

[Repository] MemberRepository.java

package com.example.demo.member.repository;

import com.example.demo.member.model.Member;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface MemberRepository extends JpaRepository<Member, Integer> {
    public Optional<Member> findByEmail(String email);
}

๐Ÿ“์‹คํ–‰ ๊ฒฐ๊ณผ

์œ„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ ,  signup์„ ์‹คํ–‰ํ•˜๋ฉด ๋กœ๊ทธ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋œฌ๋‹ค. 

 

@Before์—์„œ ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ์ „์„ ์ถœ๋ ฅํ•˜๊ฒŒ ํ•œ ๊ฒƒ๋„ ์ž˜ ์‹คํ–‰๋œ ๊ฑธ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

Hibernate์œผ๋กœ database์— insert๊ฐ€ ๋˜๊ณ  ๋ฉ”์†Œ๋“œ๊ฐ€ ๋๋‚œ ํ›„์— @AfterReturning์—์„œ ์ฒ˜๋ฆฌํ•œ ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ํ›„ ๋˜ํ•œ ์ž˜ ์ถœ๋ ฅ๋œ๋‹ค. 

signup ์š”์ฒญ์€ postman์„ ์ด์šฉํ•ด์„œ ๋ณด๋‚ด์ฃผ์—ˆ๊ณ , ์˜ค๋ฅธ์ชฝ ๊ทธ๋ฆผ์—์„œ database์—๋„ ์ž˜ ๋“ค์–ด๊ฐ”๋‹ค.