인터뷰어: Spring Aop 공통 주석 및 실행 순서
최근 많은 분들을 대상으로 이력서 수정 및 모의면접을 하던 중 몇몇 친구들이 Spring AOP 면접 질문에 대한 피드백을 줬는데, 오늘 물어보겠습니다.
처음에 Spring의 가장 강력한 점은 IOC/AOP의 두 가지 핵심 기능입니다. 오늘은 Spring AOP의 공통 주석과 실행 순서에 대해 알아 보겠습니다.
Spring 인터뷰 핵심 포인트:
IOC, AOP, Bean 주입, Bean 수명 주기, Bean 순환 종속성
먼저 Spring Aop에서 일반적으로 사용되는 몇 가지 주석을 검토해 보겠습니다.
@Before 사전 알림: 대상 메서드 전에 실행됨 @Before
前置通知:目标方法之前执行@After
后置通知:目标方法之后执行(始终执行)@AfterReturning
返回之后通知:执行方法结束之前执行(异常不执行)@AfterThrowing
异常通知:出香异常后执行@Around
@After
게시물 알림 : 실행됨 대상 메소드 이후(항상 실행됨)
@ AfterReturning
반환 후 알림: 실행 메서드가 끝나기 전에 실행됨(예외는 실행되지 않음) @AfterThrowing
예외 알림: 향 예외 이후 실행
@Around
Around 알림: Surround 대상 메서드 실행🎜🎜🎜🎜🎜🎜FAQ🎜🎜🎜 🎜🎜🎜1. 꼭 알아두셔야 할 점 Spring, Aop의 모든 알림 순서에 대해 이야기해 보겠습니다. Spring Boot 또는 Spring Boot 2는 Aop의 실행 순서에 어떤 영향을 줍니까? 🎜🎜2. AOP에서 겪은 함정에 대해 알려주세요. 🎜샘플 코드
Spring AOP에 대한 몇 가지 세부 사항을 논의하기 위해 Spring AOP 데모 프로그램을 빠르게 구축해 보겠습니다.
구성 파일
빠른 프로젝트 구축을 위해 spring-boot를 직접 활용하기 쉽도록 아이디어의 spring-boot 프로젝트 빠른 생성 기능을 이용하거나 에 들어가시면 됩니다. ="글꼴 크기: 14px; 패딩: 2px 4px; 테두리 반경: 4px; 여백 오른쪽: 2px; 여백 왼쪽: 2px; 배경 색상: rgba(27, 31, 35, 0.05); 글꼴 계열: "Operator Mono" , Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">start.spring.io 위의 스프링- 부팅 응용 프로그램. start.spring.io
上面去快速创建spring-boot 应用。
因为本人经常手动去网上贴一些依赖导致,依赖冲突服务启动失败等一些问题。
plugins { id 'org.springframework.boot' version '2.6.3' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' } group 'io.zhengsh' version '1.0-SNAPSHOT' repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } maven { url 'https://repo.spring.io/snapshot' } } dependencies { # 其实这里也可以不增加 web 配置,为了试验简单,大家请忽略 implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-aop' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() }
接口类
首先我们需要定义一个接口。我们这里可以再来回顾一下 JDK 的默认代理实现的选择:
如果目标对象实现了接口,则默认采用JDK动态代理 如果目标对象没有实现接口,则采用进行动态代理 如果目标对象实现了接口,且强制Cglib,则使用cglib代理
这块的逻辑在 DefaultAopProxyFactory
몇 가지 종속성을 온라인에 수동으로 게시하는 경우가 많기 때문에 종속성 충돌이 발생합니다. 서비스 시작 실패와 같은 일부 문제.
public interface CalcService { public int div(int x, int y); }
Interface class
먼저 인터페이스를 정의해야 합니다. 여기에서 JDK의 기본 프록시 구현 선택을 검토할 수 있습니다.
대상 객체인 경우 인터페이스가 구현되면 JDK 동적 프록시가 기본적으로 사용됩니다. 대상 객체가 인터페이스를 구현하지 않는 경우 동적 프록시를 사용하세요 대상 객체가 인터페이스를 구현하고 Cglib를 강제하는 경우 cglib 프록시를 사용하세요
논리 이 부분은 < code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px; background-color: rgba(27, 31, 35, 0.05);font- family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">DefaultAopProxyFactory 관심이 있으시면 , 살펴볼 수 있습니다.
🎜여기서는 간단히 나누기 연산을 수행해 보겠습니다. 이는 정상적인 연산을 시뮬레이션할 수 있고 오류도 쉽게 시뮬레이션할 수 있습니다. 🎜 구현 클래스@Aspect @Component public class MyAspect { @Pointcut("execution(* io.zhengsh.spring.service.impl..*.*(..))") public void divPointCut() { } @Before("divPointCut()") public void beforeNotify() { System.out.println("----===>> @Before 我是前置通知"); } @After("divPointCut") public void afterNotify() { System.out.println("----===>> @After 我是后置通知"); } @AfterReturning("divPointCut") public void afterReturningNotify() { System.out.println("----===>> @AfterReturning 我是前置通知"); } @AfterThrowing("divPointCut") public void afterThrowingNotify() { System.out.println("----===>> @AfterThrowing 我是异常通知"); } @Around("divPointCut") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { Object retVal; System.out.println("----===>> @Around 环绕通知之前 AAA"); retVal = proceedingJoinPoint.proceed(); System.out.println("----===>> @Around 环绕通知之后 BBB"); return retVal; } }
其实这块我刚开始也不是很理解,但是我看了 Aspect 注解的定义我就清楚了

这里面根本就没有 Bean 的定义。所以我们还是乖乖的加上两个注解。
还有就是如果当测试的时候需要开启Aop 的支持为配置类上增加@EnableAspectJAutoProxy
注解。
其实 Aop 使用就三个步骤:
定义 Aspect 定义切面 定义 Pointcut 就是定义我们切入点 定义具体的通知,比如: @After, @Before 等。
@Aspect @Component public class MyAspect { @Pointcut("execution(* io.zhengsh.spring.service.impl..*.*(..))") public void divPointCut() { } @Before("divPointCut()") public void beforeNotify() { System.out.println("----===>> @Before 我是前置通知"); } @After("divPointCut") public void afterNotify() { System.out.println("----===>> @After 我是后置通知"); } @AfterReturning("divPointCut") public void afterReturningNotify() { System.out.println("----===>> @AfterReturning 我是前置通知"); } @AfterThrowing("divPointCut") public void afterThrowingNotify() { System.out.println("----===>> @AfterThrowing 我是异常通知"); } @Around("divPointCut") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { Object retVal; System.out.println("----===>> @Around 环绕通知之前 AAA"); retVal = proceedingJoinPoint.proceed(); System.out.println("----===>> @Around 环绕通知之后 BBB"); return retVal; } }
测试类
其实我这个测试类,虽然用了 @Test 注解,但是我这个类更加像一个 main 方法把:如下所示:

执行结论
结果记录:spring 4.x, spring-boot 1.5.9
无法现在依赖,所以无法试验
我直接说一下结论:Spring 4 中环绕通知是在最里面执行的
结果记录:spring 版本5.3.15 springboot 版本2.6.3

多切面的情况
多个切面的情况下,可以通过@Order指定先后顺序,数字越小,优先级越高。如下图所示:

代理失效场景
下面一种场景会导致 aop 代理失效,因为我们在执行 a 方法的时候其实本质是执行 AServer#a
的方法拦截器(MethodInterceptor
)链, 当我们在 a 方法内直接执行b(), 其实本质就相当于 this.b() , 这个时候由执行 a方法是调用到 a 的原始对象相当于是 this 调用,那么会导致 b() 方法的代理失效。这个问题也是我们开发者在开发过程中最常遇到的一个问题。
@Service public class AService { public void a() { System.out.println("...... a"); b(); } public void b() { System.out.println("...... b"); } }
위 내용은 인터뷰어: Spring Aop 공통 주석 및 실행 순서의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제









Java의 난수 생성기 안내. 여기서는 예제를 통해 Java의 함수와 예제를 통해 두 가지 다른 생성기에 대해 설명합니다.

자바의 암스트롱 번호 안내 여기에서는 일부 코드와 함께 Java의 Armstrong 번호에 대한 소개를 논의합니다.

Java의 Weka 가이드. 여기에서는 소개, weka java 사용 방법, 플랫폼 유형 및 장점을 예제와 함께 설명합니다.

Java의 Smith Number 가이드. 여기서는 정의, Java에서 스미스 번호를 확인하는 방법에 대해 논의합니다. 코드 구현의 예.

이 기사에서는 가장 많이 묻는 Java Spring 면접 질문과 자세한 답변을 보관했습니다. 그래야 면접에 합격할 수 있습니다.

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다
