주석을 통해 AOP 구성

AOP 소개

참조 블로그 게시물

Spring의 Spring AOP-aspect-oriented 프로그래밍

1. AOP는 무엇을 생각하고 있습니까?

문자 그대로 번역 된 AOP (Aspect Orient Programming)는 aspect 지향 프로그래밍입니다. AOP는 프로그래밍 아이디어이자 OOP (객체 지향 프로그래밍)에 대한 보완책입니다. 객체 지향 프로그래밍은 프로그램을 다양한 수준의 객체로 추상화하는 반면, 측면 지향 프로그래밍은 프로그램을 다양한 측면으로 추상화합니다.

책 "Spring Actual Combat (4th Edition)"에서 사진을 가져 왔습니다.
여기에 사진 설명 삽입

2. 일반적으로 사용되는 AOP는 무엇입니까?

  1. 트랜잭션 처리 : 메소드 실행 전 트랜잭션을 열고 실행이 완료된 후 트랜잭션을 닫고 예외가 발생하면 트랜잭션을 롤백합니다.
  2. 권한 판단 : 방법을 실행하기 전에 권한이 있는지 판단
  3. 로그 : 실행 전 로그 처리

예를 들어 웹 사이트에 대한 사용자 액세스 로그를 기록하려고합니다.
일부 URL은 기록 할 필요가없고 일부는 기록해야합니다.
OOP, 객체 지향을 계속 사용하는 경우
해당하는 컨트롤러 만 사용할 수 있습니다. URL 코드에서는 로그 레코드에 하나씩 기록되며
AOP를 사용하면 어떻게 될까요?
컨트롤 클래스에 코드를 추가 할 필요는 없지만, aspect를 통해 비 침습적으로 로그를 기록하기 위해 로그 클래스를 직접 추가합니다.

3. AOP의 장점

  1. 반복적 인 코드 감소
  2. 개발 효율성 향상
  3. 간편한 유지 보수

4. AOP 관련 용어

용어 의미
연결 지점 (연결 지점) 소위 연결 지점은 가로채는 지점입니다. Spring에서는 메서드 유형의 연결점 만 지원하므로 이러한 점은 메서드를 참조합니다.
Pointcut (진입 지점) 이른바 진입 점은 우리가 가로 채려는 Joinpoint의 정의를 나타냅니다.
조언 소위 알림은 Joinpoint를 가로 챈 후 알림을 의미합니다. 알림 유형 : 사전 알림, 사후 알림, 예외 알림, 최종 알림, 서라운드 알림.
대리 클래스가 AOP에 의해 짜여지고 향상되면 결과 프록시 클래스가 생성됩니다.
양상 진입 점과 알림 (소개)의 조합입니다.
소개 (引 介) 소개는 특별한 종류의 알림입니다. 클래스 코드를 수정하지 않는다는 전제하에 Introduction은 런타임에 클래스에 일부 메서드 또는 필드를 동적으로 추가 할 수 있습니다.
표적 에이전트의 대상 개체입니다.

주석을 통해 AOP 구성

1. Pointcut 문법

여기에 사진 설명 삽입
실행 인디케이터를 사용하여 악기의 재생 방법을 선택합니다. 메소드 표현식은 *로 시작하여 메소드의 반환 값 유형에 관심이 없음을 나타냅니다. 그런 다음 정규화 된 클래스 이름과 메서드 이름을 지정했습니다. 메소드 매개 변수 목록의 경우, 메소드의 입력 매개 변수가 무엇이든 상관없이 재생 방법을 선택하기 위해 컷 포인트를 식별하기 위해 ...를 사용합니다.
우리는 링크 기호 사이에 두 개 이상의 일치를 사용할 수 있습니다 &&, ||, 의미 "와"의 "또는"관계 "없습니다"하는. 그러나 XML 파일 구성을 사용할 때 이러한 기호는 특별한 의미가 있으므로 " and", " or", " not”를 사용하여 표시합니다.

예 :
패키지와 일치하도록 pointcut을 제한하면 com.sharpcj.aopdemo.test1다음을 사용할 수 있습니다.

execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..)) && within(com.sharpcj.aopdemo.test1.*)

포인트 컷에서 콩을 선택하면

execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..)) && bean(girl)

2. 5 가지 알림 유형

댓글 (이름) 효과
@전에 알림 메서드는 대상 메서드가 호출되기 전에 실행됩니다.
@후 알림 메서드는 대상 메서드가 반환되거나 비정상적인 후에 호출됩니다.
@AfterReturning 알림 메서드는 대상 메서드가 반환 된 후 호출되며 예외가 발생하면 호출되지 않습니다.
안녕하세요. 알림 메서드는 대상 메서드가 예외를 throw 한 후 호출됩니다.
@Around (서라운드 알림) 알림 방법은 대상을 캡슐화합니다.

3. 간단한 예

사용자 클래스

package test_aop.pojo;

import org.springframework.stereotype.Component;

@Component
public class User {
    
    

	public String point(boolean s) {
    
    

		System.err.println("User.point() arg s is==" + s);

		return "message";
	}

}

AdviceConfig 클래스

package test_aop.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

// 一定要是用aspect注解
// true代表使用cglib代理方式(使用注解)  false代表使用jdk动态代理模式
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Component
@Aspect
public class UserAdvice {
    
    

	// 方法路径
	final static String FUNTION_NAME = "execution(* test_aop.pojo.User.point(..))";

	// 在point调用之前执行
	// point参数代表当前的目标方法,我们可以通过这个参数获取目标方法的 参数,返回值等相关信息
	@Before(value = FUNTION_NAME)
	public void before(JoinPoint point) {
    
    
		System.out.println("UserAdvice.before()");
	}

	// 在point调用之后执行
	// point参数代表当前的目标方法,我们可以通过这个参数获取目标方法的 参数,返回值等相关信息
	@After(value = FUNTION_NAME)
	public void after(JoinPoint point) {
    
    
		System.out.println("UserAdvice.after()");
	}

	// 该通知方法会目标方法返回后调用,如果出现异常则不会调用
	// returning参数指定用什么参数名接受返回的值
	@AfterReturning(pointcut = FUNTION_NAME, returning = "re")
	public void afterReturning(Object re) {
    
    
		System.out.println("UserAdvice.afterReturning() re==" + re);
	}

	// 该通知方法会在目标方法抛出异常后调用
	// throwing参数指定用什么名称的参数接受异常
	@AfterThrowing(pointcut = FUNTION_NAME, throwing = "e")
	public void afterThrowing(Exception e) {
    
    
		System.err.println(e);
	}

	// 该通知法会将目标封装起来,必须执行proceed方法,相当与放行的操作
	@Around(value = FUNTION_NAME)
	public void arround(ProceedingJoinPoint p) throws Throwable {
    
    

		System.out.println("UserAdvice.arround() before");
		p.proceed();
		System.out.println("UserAdvice.arround() after");

	}
}

메인 클래스

package test_aop;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

import test_aop.pojo.User;

@SpringBootApplication
// 扫描注解
@ComponentScan(basePackages = {
    
     "test_aop.pojo", "test_aop.advice" })
public class App {
    
    

	public static void main(String[] args) {
    
    
		ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
		User user = context.getBean(User.class);
		user.point(true);
	}

}

결과
여기에 사진 설명 삽입

추천

출처blog.csdn.net/qq_42418169/article/details/112847020