멀티캠퍼스

[2026.06.18] - TIL 54일차 Spring Annotation 기반 DI와 AOP 개념 정리

buckwheat 2026. 6. 18. 17:51

 

 

목차
1 오늘 학습 흐름
2 XML 설정 방식에서 Annotation 방식으로 전환
3 @Component
4 Component Scan
5 @Autowired
6 @Qualifier
7 @Value
8 필드 주입과 생성자 주입
9 @Configuration과 @Bean
10 Annotation 기반 설정의 핵심 흐름
11 AOP 개요
12 AOP 핵심 용어
13 Advice의 종류
14 Spring AOP의 동작 구조
15 Spring AOP의 특징
16 AOP 구현 방식
17 JoinPoint와 ProceedingJoinPoint
18 오늘 학습한 핵심 정리

1 오늘 학습 흐름

1) Spring05_Anno 실습

 

    (1) 오늘의 실습 범위

    오늘은 Spring05_Anno 프로젝트의 test01부터 test05까지를 학습했다.

    전체 코드를 하나씩 분석하기보다는, XML 설정 방식에서 Annotation 기반 설정 방식으로 넘어가는 흐름을 중심으로 복습했다.

 

    (2) 이전 수업과의 연결

    이전에는 applicationContext.xml에 bean 태그를 작성해서 Bean을 등록했다.

    또한 property, constructor-arg, ref, autowire 같은 XML 설정을 이용해 의존성을 주입했다.

 

    (3) 오늘의 핵심 변화

    오늘은 XML에 Bean을 하나하나 등록하는 방식에서 벗어나, Java 클래스에 직접 Annotation을 붙여 Spring이 Bean을 자동으로 찾고 등록하게 만드는 방법을 학습했다.

    즉, Bean 등록과 의존성 주입을 XML 중심이 아니라 Annotation 중심으로 처리하는 흐름을 배웠다.

 

    (4) 함께 학습한 AOP

    실습 이후에는 Spring AOP 개념을 학습했다.

    AOP는 로그, 트랜잭션, 보안처럼 여러 클래스에서 반복되는 공통 기능을 핵심 로직과 분리해서 관리하는 기술이다.


2 XML 설정 방식에서 Annotation 방식으로 전환

1) XML 기반 설정

 

    (1) 기존 방식

    기존 XML 방식에서는 applicationContext.xml 안에 bean 태그를 직접 작성했다.

    어떤 클래스를 Bean으로 만들지, 어떤 값을 넣을지, 어떤 Bean을 연결할지를 XML에 명시했다.

 

    (2) 장점

    XML 파일만 보면 Bean 등록 정보와 의존 관계를 한눈에 볼 수 있다.

    Java 코드와 설정 코드가 분리된다는 장점도 있다.

 

    (3) 단점

    Bean이 많아지면 XML 코드가 길어진다.

    클래스가 많아질수록 bean 태그, property 태그, constructor-arg 태그를 계속 작성해야 해서 관리가 불편해질 수 있다.

 

2) Annotation 기반 설정

 

    (1) Annotation 방식

    Annotation 방식은 클래스나 필드, 생성자, 메소드에 Annotation을 붙여 Spring 설정을 처리하는 방식이다.

    대표적으로 @Component, @Autowired, @Qualifier, @Value, @Configuration, @Bean 등이 있다.

 

    (2) 장점

    Java 클래스 안에서 Bean 등록과 의존성 주입 정보를 바로 확인할 수 있다.

    XML 설정이 줄어들어 코드가 간결해진다.

 

    (3) 핵심

    Annotation을 붙인다고 Spring이 무조건 자동으로 인식하는 것은 아니다.

    Spring이 해당 패키지를 스캔하도록 Component Scan 설정이 필요하다.


3 @Component

1) @Component의 의미

 

    (1) @Component

    @Component는 해당 클래스를 Spring Bean으로 등록하겠다는 Annotation이다.

    XML에서 bean 태그를 작성하던 것을 클래스 위에 @Component를 붙이는 방식으로 대체할 수 있다.

 

    (2) 기존 XML 방식과 비교

    XML 방식에서는 다음과 같이 작성했다.

 

    <bean id="nickName" class="com.test01.anno.NickName"/>

 

    Annotation 방식에서는 클래스에 다음처럼 작성한다.

 

    @Component

    public class NickName {

    }

 

    (3) 핵심

    @Component가 붙은 클래스는 Spring이 스캔할 때 자동으로 Bean으로 등록된다.

    즉, 개발자가 XML에 bean 태그를 직접 작성하지 않아도 된다.

 

2) Bean 이름

 

    (1) 기본 Bean 이름

    @Component만 붙이면 클래스 이름의 첫 글자를 소문자로 바꾼 이름이 기본 Bean 이름이 된다.

    예를 들어 LgTV 클래스는 기본적으로 lgTV라는 이름의 Bean으로 등록된다.

 

    (2) 이름 직접 지정

    @Component("sam")처럼 작성하면 Bean 이름을 직접 지정할 수 있다.

    이 경우 SamsungTV 클래스는 samsungTV가 아니라 sam이라는 이름으로 등록된다.

 

    (3) 사용하는 이유

    같은 타입의 Bean이 여러 개 있을 때 Bean 이름이 중요해진다.

    나중에 @Qualifier로 특정 Bean을 선택할 때 이 이름을 사용할 수 있다.


4 Component Scan

1) Component Scan의 의미

 

    (1) Component Scan

    Component Scan은 Spring이 특정 패키지 아래의 클래스들을 검사하면서 @Component가 붙은 클래스를 자동으로 Bean으로 등록하는 기능이다.

 

    (2) 필요한 이유

    클래스에 @Component를 붙여도 Spring이 그 클래스를 찾아보지 않으면 Bean으로 등록되지 않는다.

    그래서 applicationContext.xml 또는 설정 클래스에서 어느 패키지를 스캔할지 알려줘야 한다.

 

    (3) 쉽게 말하면

    @Component는 “나 Bean으로 등록해줘”라는 표시이다.

    Component Scan은 “어디를 찾아보면서 Bean 후보를 찾을지” 정하는 설정이다.

 

2) 실습에서의 의미

 

    (1) test01

    test01에서는 NickName과 myNickName을 Annotation 방식으로 Bean 등록하는 흐름을 확인했다.

    NickName 클래스에 @Component를 붙이고, myNickName 클래스에서도 @Component를 붙여 Spring이 두 객체를 관리하게 했다.

 

    (2) test03

    test03에서는 LgTV와 SamsungTV를 @Component로 등록했다.

    LgTV는 기본 Bean 이름인 lgTV로 등록되고, SamsungTV는 @Component("sam")으로 인해 sam이라는 이름으로 등록되었다.

 

    (3) 핵심

    Component Scan이 설정되어 있어야 @Component가 붙은 클래스들이 Spring 컨테이너에 등록된다.

    따라서 Annotation 기반 설정에서는 Component Scan이 매우 중요하다.


5 @Autowired

1) @Autowired의 의미

 

    (1) @Autowired

    @Autowired는 필요한 의존 객체를 Spring이 자동으로 찾아서 주입하게 하는 Annotation이다.

    XML에서 property ref나 constructor-arg ref로 직접 연결하던 작업을 Annotation으로 처리하는 것이다.

 

    (2) 기존 방식과 비교

    XML에서는 다음처럼 직접 연결했다.

 

    <property name="nickName" ref="nickName"/>

 

    Annotation 방식에서는 필드나 생성자에 @Autowired를 붙인다.

 

    @Autowired

    private NickName nickName;

 

    (3) 핵심

    @Autowired는 Spring 컨테이너 안에서 타입이 맞는 Bean을 찾아 자동으로 넣어준다.

    즉, 개발자가 직접 new를 하지 않아도 되고, XML에서 ref를 명시하지 않아도 된다.

 

2) @Autowired의 기본 동작

 

    (1) 타입 기준 탐색

    @Autowired는 기본적으로 타입을 기준으로 Bean을 찾는다.

    예를 들어 NickName 타입 필드가 있으면 Spring 컨테이너에서 NickName 타입 Bean을 찾는다.

 

    (2) 타입이 하나일 때

    해당 타입의 Bean이 하나만 있으면 자동으로 주입된다.

    이 경우 별도의 이름 지정 없이도 정상적으로 동작한다.

 

    (3) 타입이 여러 개일 때

    같은 타입의 Bean이 여러 개 있으면 Spring은 어떤 Bean을 주입해야 할지 판단하기 어렵다.

    이때 @Qualifier를 함께 사용해 특정 Bean을 지정할 수 있다.


6 @Qualifier

1) @Qualifier의 의미

 

    (1) @Qualifier

    @Qualifier는 @Autowired가 주입할 Bean을 이름으로 더 정확하게 지정할 때 사용하는 Annotation이다.

 

    (2) 필요한 이유

    같은 타입의 Bean이 여러 개 있을 때 @Autowired만 사용하면 충돌이 발생할 수 있다.

    이때 @Qualifier를 사용하면 어떤 Bean을 넣을지 명확하게 지정할 수 있다.

 

    (3) 예시

    Emp 타입 Bean이 lee, kim처럼 여러 개 있다면 @Autowired만으로는 어떤 Emp를 넣을지 모호하다.

    이때 @Qualifier("lee")를 사용하면 lee라는 이름의 Bean을 주입한다.

 

2) 실습에서의 의미

 

    (1) test02

    School 클래스에서는 Student 타입 객체를 주입받는다.

    @Autowired와 @Qualifier를 함께 사용해 특정 Student Bean을 person 필드에 주입하는 흐름을 확인했다.

 

    (2) test04

    Developer 클래스에서는 Emp 타입 객체를 주입받는다.

    @Autowired와 @Qualifier("lee")를 사용해 여러 Emp 중 lee Bean을 선택해서 주입했다.

 

    (3) test05

    Developer 생성자에서는 @Qualifier("employee2")를 사용해 employee2라는 이름의 Emp Bean을 주입했다.

    Engineer 필드에서는 @Qualifier("emp1")을 사용해 emp1 Bean을 주입했다.

 

    (4) 핵심

    @Autowired는 타입을 기준으로 찾고, @Qualifier는 이름으로 대상을 좁혀준다.

    따라서 같은 타입 Bean이 여러 개 있을 때는 @Qualifier가 매우 중요하다.


7 @Value

1) @Value의 의미

 

    (1) @Value

    @Value는 문자열, 숫자 같은 단순 값을 주입할 때 사용하는 Annotation이다.

    XML에서 value 속성으로 값을 넣던 것을 Annotation으로 처리하는 방식이다.

 

    (2) 기존 방식과 비교

    XML에서는 다음처럼 작성했다.

 

    <property name="dept" value="개발"/>

 

    Annotation 방식에서는 다음처럼 작성한다.

 

    @Value("개발")

    private String dept;

 

    (3) 핵심

    @Autowired가 Bean 객체를 주입하는 데 사용된다면, @Value는 단순 값을 주입하는 데 사용된다.

 

2) 실습에서의 의미

 

    (1) grade 값 주입

    test02의 School 클래스에서는 @Value("5")를 사용해 grade 값을 주입했다.

    XML에서 숫자를 넣는 대신 Annotation으로 필드에 직접 값을 넣은 것이다.

 

    (2) dept 값 주입

    test04의 Developer 클래스에서는 @Value("개발")을 사용해 부서명을 주입했다.

    test05의 Engineer 클래스에서는 @Value("기술팀")을 사용했고, Developer 생성자에서는 @Value("개발팀")을 사용했다.

 

    (3) 핵심

    객체는 @Autowired로 주입하고, 단순 값은 @Value로 주입한다.

    이 둘의 역할을 구분해야 Annotation 기반 DI를 이해하기 쉽다.


8 필드 주입과 생성자 주입

1) 필드 주입

 

    (1) 필드 주입의 의미

    필드 주입은 클래스의 필드 위에 @Autowired나 @Value를 붙여 바로 값을 주입하는 방식이다.

 

    (2) 예시

    Engineer 클래스에서 Emp 필드에는 @Autowired와 @Qualifier를 붙이고, dept 필드에는 @Value를 붙였다.

    Spring은 객체를 생성한 후 해당 필드에 필요한 값을 넣어준다.

 

    (3) 특징

    코드가 짧고 보기 쉽다.

    하지만 객체 생성 시점에 필수 의존성이 명확하게 드러나지 않을 수 있다.

 

2) 생성자 주입

 

    (1) 생성자 주입의 의미

    생성자 주입은 생성자에 @Autowired를 붙여 객체가 생성될 때 필요한 의존성을 주입받는 방식이다.

 

    (2) 예시

    Developer 클래스에서는 생성자에 @Autowired를 붙였다.

    생성자의 Emp 매개변수에는 @Qualifier("employee2")를 붙이고, dept 매개변수에는 @Value("개발팀")을 붙여 값을 주입했다.

 

    (3) 특징

    객체가 생성될 때 반드시 필요한 의존성을 함께 받을 수 있다.

    따라서 객체가 불완전한 상태로 생성되는 것을 줄일 수 있다.

 

3) 필드 주입과 생성자 주입 비교

 

    (1) 필드 주입

    필드에 직접 Annotation을 붙인다.

    코드가 간단하지만 의존성이 숨겨져 보일 수 있다.

 

    (2) 생성자 주입

    생성자의 매개변수를 통해 값을 받는다.

    객체가 생성될 때 필요한 값이 무엇인지 명확하게 드러난다.

 

    (3) 오늘 실습의 의미

    test04에서는 필드 주입을 중심으로 확인했고, test05에서는 생성자 주입까지 함께 확인했다.

    이를 통해 Annotation 기반 DI에서도 다양한 주입 방식이 가능하다는 것을 알 수 있었다.


9 @Configuration과 @Bean

1) @Configuration

 

    (1) @Configuration의 의미

    @Configuration은 해당 클래스가 Spring 설정 클래스라는 뜻이다.

    XML 설정 파일처럼 Bean 등록 정보를 Java 코드로 작성할 수 있게 해준다.

 

    (2) XML 설정과 비교

    XML에서는 bean 태그로 Bean을 등록했다.

    Java 설정 방식에서는 @Configuration 클래스 안에 @Bean 메소드를 작성해서 Bean을 등록한다.

 

    (3) 실습에서의 의미

    test05의 Config 클래스에는 @Configuration이 붙어 있다.

    이 클래스는 XML을 대신해서 일부 Bean을 등록하는 설정 파일 역할을 한다.

 

2) @Bean

 

    (1) @Bean의 의미

    @Bean은 메소드가 반환하는 객체를 Spring Bean으로 등록하겠다는 Annotation이다.

    @Configuration 클래스 안에서 주로 사용한다.

 

    (2) 기본 Bean 이름

    @Bean 메소드의 이름이 기본 Bean 이름이 된다.

    예를 들어 emp1 메소드는 emp1이라는 이름의 Bean을 등록한다.

 

    (3) Bean 이름 직접 지정

    @Bean(name = "employee2")처럼 작성하면 Bean 이름을 직접 지정할 수 있다.

    이 경우 메소드 이름은 emp2지만 Bean 이름은 employee2가 된다.

 

3) @Component와 @Bean의 차이

 

    (1) @Component

    @Component는 클래스 자체를 Bean으로 등록할 때 사용한다.

    개발자가 만든 클래스에 직접 붙이는 방식이다.

 

    (2) @Bean

    @Bean은 메소드가 반환하는 객체를 Bean으로 등록할 때 사용한다.

    직접 수정하기 어려운 외부 클래스나, 생성 로직을 직접 제어하고 싶은 객체를 등록할 때 유용하다.

 

    (3) 핵심 차이

    @Component는 클래스 선언부에 붙인다.

    @Bean은 설정 클래스 안의 메소드에 붙인다.


10 Annotation 기반 설정의 핵심 흐름

1) Bean 등록 흐름

 

    (1) @Component 방식

    클래스에 @Component를 붙인다.

    Component Scan이 해당 클래스를 찾아 Bean으로 등록한다.

 

    (2) @Configuration + @Bean 방식

    설정 클래스에 @Configuration을 붙인다.

    그 안에서 @Bean 메소드를 작성해 반환 객체를 Bean으로 등록한다.

 

2) 의존성 주입 흐름

 

    (1) 객체 주입

    객체가 필요한 경우 @Autowired를 사용한다.

    같은 타입 Bean이 여러 개 있으면 @Qualifier로 구체적인 Bean 이름을 지정한다.

 

    (2) 단순 값 주입

    문자열이나 숫자 같은 단순 값은 @Value를 사용한다.

 

    (3) 주입 위치

    필드에 직접 주입할 수도 있고, 생성자를 통해 주입할 수도 있다.

    실습에서는 두 방식을 모두 확인했다.

 

3) test01부터 test05까지의 개념 흐름

 

    (1) test01

    @Component와 @Autowired를 통해 Bean 자동 등록과 자동 주입의 기본 흐름을 학습했다.

 

    (2) test02

    @Autowired, @Qualifier, @Value를 사용해 객체와 단순 값을 함께 주입하는 방법을 학습했다.

 

    (3) test03

    인터페이스 TV와 구현체 LgTV, SamsungTV를 통해 Annotation 기반 Bean 등록과 Bean 이름 지정 방식을 학습했다.

 

    (4) test04

    Developer, Engineer, Emp 구조를 통해 Annotation 방식과 XML 설정을 함께 사용하는 흐름을 학습했다.

 

    (5) test05

    @Configuration과 @Bean을 사용해 Java 설정 클래스로 Bean을 등록하고, 생성자 주입과 필드 주입을 함께 복습했다.


11 AOP 개요

1) AOP의 의미

 

    (1) AOP

    AOP는 Aspect Oriented Programming의 약자로 관점 지향 프로그래밍을 의미한다.

    핵심 기능과 공통 기능을 분리해서 관리하는 프로그래밍 방식이다.

 

    (2) 핵심 기능

    핵심 기능은 해당 클래스가 원래 해야 하는 주요 기능이다.

    예를 들어 게시판 서비스라면 글 작성, 글 수정, 글 삭제가 핵심 기능이다.

 

    (3) 공통 기능

    공통 기능은 여러 클래스와 메소드에서 반복적으로 필요한 기능이다.

    대표적으로 log 처리, commit, rollback, 보안, 인증, 트랜잭션 처리 등이 있다.

 

    (4) AOP를 사용하는 이유

    공통 기능을 여러 클래스에 직접 작성하면 코드 중복이 많아진다.

    AOP를 사용하면 공통 기능을 별도의 영역으로 분리하고, 필요한 시점에 자동으로 적용할 수 있다.

 

2) AOP를 쉽게 이해하기

 

    (1) 기존 방식

    기존 방식에서는 Service나 DAO 메소드 안에 핵심 로직과 로그, 트랜잭션 코드가 함께 들어간다.

    그러면 핵심 기능 코드가 지저분해지고 중복도 많아진다.

 

    (2) AOP 방식

    AOP에서는 로그, 트랜잭션 같은 공통 기능을 따로 분리한다.

    그리고 메소드 실행 전, 실행 후, 예외 발생 시점 등에 공통 기능을 끼워 넣는다.

 

    (3) 핵심

    AOP는 핵심 기능을 수정하지 않고도 공통 기능을 적용할 수 있게 해준다.

    그래서 코드 중복을 줄이고 유지보수를 쉽게 만든다.


12 AOP 핵심 용어

1) Aspect

 

    (1) Aspect

    Aspect는 공통 기능을 모아둔 모듈이다.

    Advice와 PointCut을 합친 개념이다.

 

    (2) 공식처럼 정리

    Advice + PointCut = Aspect

 

    (3) 의미

    Advice는 실제 실행할 공통 코드이고, PointCut은 그 공통 코드를 어디에 적용할지 정하는 조건이다.

    따라서 Aspect는 “무엇을, 어디에 적용할지”를 함께 가진 개념이다.

 

2) Advice

 

    (1) Advice

    Advice는 JoinPoint에 삽입되어 동작하는 공통 코드이다.

    실제로 로그를 찍거나, 실행 시간을 측정하거나, 트랜잭션을 처리하는 메소드가 Advice에 해당한다.

 

    (2) 쉽게 말하면

    Advice는 AOP에서 실행될 부가 기능 코드이다.

 

3) JoinPoint

 

    (1) JoinPoint

    JoinPoint는 Advice가 적용될 수 있는 지점이다.

    객체 생성 시점, 메소드 호출 시점, 예외 발생 시점 등이 JoinPoint가 될 수 있다.

 

    (2) Spring AOP에서의 JoinPoint

    Spring AOP는 프록시 기반으로 동작하기 때문에 메소드 호출 시점만 JoinPoint로 지원한다.

    즉, Spring AOP에서는 메소드 실행 전후에 공통 기능을 붙이는 방식이 중심이다.

 

4) PointCut

 

    (1) PointCut

    PointCut은 여러 JoinPoint 중에서 실제로 Advice를 적용할 지점을 선택하는 조건이다.

 

    (2) 쉽게 말하면

    JoinPoint가 후보라면, PointCut은 그중 실제 적용 대상을 고르는 필터이다.

 

5) Weaving

 

    (1) Weaving

    Weaving은 Advice를 핵심 로직에 끼워 넣는 작업이다.

    즉, 공통 기능이 실제 메소드 실행 흐름에 적용되는 과정이다.

 

    (2) Spring에서의 Weaving

    Spring은 런타임 시점에 프록시 객체를 만들어 AOP를 적용한다.

    클래스 파일 자체를 직접 수정하는 것이 아니라, 중간에 Proxy를 세워 요청을 가로채는 방식이다.

 

6) Proxy

 

    (1) Proxy

    Proxy는 대상 객체를 직접 호출하지 못하게 하고, 대신 요청을 받아 처리하는 대리 객체이다.

 

    (2) AOP에서의 역할

    클라이언트가 Target Object를 직접 호출하는 것이 아니라 Proxy를 먼저 호출한다.

    Proxy는 Advice를 실행한 뒤 실제 대상 객체의 메소드를 호출한다.

 

7) Target Object

 

    (1) Target Object

    Target Object는 Advice가 적용될 실제 대상 객체이다.

    즉, 핵심 기능을 가지고 있는 원래 객체이다.

 

    (2) 예시

    BoardService의 글 작성 메소드에 로그 기능을 붙인다면 BoardService가 Target Object가 될 수 있다.


13 Advice의 종류

1) Before Advice

 

    (1) 의미

    Before Advice는 대상 메소드가 실행되기 전에 실행되는 Advice이다.

 

    (2) 사용 예

    메소드 실행 전에 로그를 남기거나, 권한을 확인하거나, 입력값을 검사할 때 사용할 수 있다.

 

2) Around Advice

 

    (1) 의미

    Around Advice는 대상 메소드 실행 전과 실행 후를 모두 감쌀 수 있는 Advice이다.

 

    (2) 특징

    대상 메소드를 직접 실행할지 말지도 제어할 수 있다.

    실행 시간 측정처럼 메소드 앞뒤 모두에서 작업이 필요한 경우 사용한다.

 

    (3) ProceedingJoinPoint

    Around Advice에서는 ProceedingJoinPoint가 필요하다.

    proceed 메소드를 호출해야 실제 대상 메소드가 실행된다.

 

3) After Advice

 

    (1) 의미

    After Advice는 대상 메소드 실행이 끝난 뒤 실행되는 Advice이다.

    정상 종료인지 예외 발생인지와 상관없이 실행된다.

 

    (2) 사용 예

    무조건 실행되어야 하는 정리 작업에 사용할 수 있다.

 

4) After Returning Advice

 

    (1) 의미

    After Returning Advice는 대상 메소드가 정상적으로 실행되고 리턴된 후 실행되는 Advice이다.

 

    (2) 사용 예

    메소드의 반환값을 확인하거나, 정상 처리 로그를 남길 때 사용할 수 있다.

 

5) After Throwing Advice

 

    (1) 의미

    After Throwing Advice는 대상 메소드에서 예외가 발생했을 때 실행되는 Advice이다.

 

    (2) 사용 예

    예외 로그를 남기거나, 예외 발생 시 추가 처리를 할 때 사용할 수 있다.


14 Spring AOP의 동작 구조

1) 기본 흐름

 

    (1) 클라이언트 요청

    클라이언트가 어떤 메소드를 호출한다.

 

    (2) Proxy 호출

    Spring AOP에서는 대상 객체를 직접 호출하지 않고 Proxy 객체가 먼저 호출된다.

 

    (3) Advice 실행

    Proxy는 PointCut 조건에 맞는지 확인하고, 조건에 맞으면 Advice를 실행한다.

 

    (4) Target Object 호출

    Advice 실행 전후로 실제 대상 객체의 핵심 메소드가 호출된다.

 

    (5) 응답 반환

    핵심 메소드와 공통 기능 처리가 끝나면 결과가 클라이언트에게 반환된다.

 

2) 중요한 흐름

 

    (1) 직접 호출이 아니다

    AOP가 적용되면 클라이언트는 실제 객체를 직접 호출하는 것처럼 보이지만, 내부적으로는 Proxy가 먼저 호출된다.

 

    (2) Proxy가 중간에서 가로챈다

    Proxy는 대상 객체의 호출을 가로챈다.

    이를 Intercept라고 한다.

 

    (3) 공통 기능 삽입

    Proxy는 Advice를 실행하고, 필요하면 대상 객체의 메소드를 호출한다.

    이 구조 덕분에 핵심 기능 코드를 수정하지 않고 공통 기능을 붙일 수 있다.


15 Spring AOP의 특징

1) Proxy 기반 AOP

 

    (1) Spring AOP의 핵심 특징

    Spring AOP는 Proxy 기반으로 동작한다.

    대상 객체를 감싸는 Proxy 객체를 만들고, 이 Proxy가 대상 객체 호출을 대신 처리한다.

 

    (2) 런타임 생성

    Spring의 Proxy는 서버 Runtime 시점에 생성된다.

    즉, 프로그램 실행 중에 대상 객체를 감싸는 대리 객체가 만들어진다.

 

2) 메소드 JoinPoint만 지원

 

    (1) Spring AOP의 제한

    Spring AOP는 메소드 호출 JoinPoint만 지원한다.

    즉, 메소드 실행 전후에 Advice를 적용하는 방식이 중심이다.

 

    (2) 지원하지 않는 범위

    객체 생성 시점, 필드 값 조회와 조작, static 메소드 호출 같은 지점은 Spring AOP만으로는 제한적이다.

 

    (3) AspectJ와의 차이

    AspectJ 같은 고급 AOP 프레임워크를 사용하면 객체 생성, 필드 조작, static 메소드 호출 등 더 다양한 지점에 부가기능을 적용할 수 있다.


16 AOP 구현 방식

1) XML 기반 AOP

 

    (1) XML 방식

    XML 기반 AOP는 XML 설정 파일에 aop 설정을 작성하는 방식이다.

 

    (2) 구현 흐름

    먼저 부가기능을 제공하는 Advice 클래스를 작성한다.

    그 다음 XML 설정 파일에서 aop:config를 이용해 Aspect를 설정한다.

 

    (3) 설정 내용

    XML에는 어떤 Advice를 어느 PointCut에 적용할지 작성한다.

    즉, XML에서 Advice와 PointCut을 연결해 Aspect를 구성한다.

 

2) Annotation 기반 AOP

 

    (1) Annotation 방식

    Annotation 기반 AOP는 @Aspect를 사용해 Aspect 클래스를 작성하는 방식이다.

 

    (2) 구현 흐름

    @Aspect가 붙은 클래스 안에 Advice 메소드와 PointCut을 작성한다.

    XML 설정 파일에는 aop:aspect-autoproxy를 설정해 Annotation 기반 AOP가 동작하도록 한다.

 

    (3) 주요 Annotation

    @Before는 메소드 실행 전 Advice이다.

    @Around는 메소드 실행 전후를 감싸는 Advice이다.

    @After는 정상 종료와 예외 발생 여부와 상관없이 실행되는 Advice이다.

    @AfterReturning은 정상 반환 후 실행되는 Advice이다.

    @AfterThrowing은 예외 발생 시 실행되는 Advice이다.


17 JoinPoint와 ProceedingJoinPoint

1) JoinPoint

 

    (1) JoinPoint 객체

    Advice 메소드에서는 JoinPoint 타입의 파라미터를 사용할 수 있다.

    이를 통해 실행 중인 대상 메소드의 정보나 전달된 파라미터 정보를 확인할 수 있다.

 

    (2) 주요 메소드

    getArgs는 대상 메소드의 매개변수 값을 반환한다.

    getThis는 현재 사용 중인 Proxy 객체를 반환한다.

    getTarget은 실제 대상 객체를 반환한다.

    getSignature는 대상 메소드의 이름, 리턴 타입 같은 정보를 반환한다.

    toString은 대상 메소드 정보를 문자열로 출력한다.

 

2) ProceedingJoinPoint

 

    (1) Around Advice에서 사용

    Around Advice에서는 JoinPoint의 하위 타입인 ProceedingJoinPoint를 사용한다.

 

    (2) proceed

    ProceedingJoinPoint의 proceed 메소드를 호출해야 실제 대상 메소드가 실행된다.

    proceed를 호출하지 않으면 대상 메소드가 실행되지 않을 수 있다.

 

    (3) 실행 시간 측정 예시

    Around Advice에서는 메소드 실행 전 시간을 기록하고, proceed로 대상 메소드를 실행한 뒤, 실행 후 시간을 다시 기록할 수 있다.

    이를 이용해 메소드 수행 시간을 측정할 수 있다.


18 오늘 학습한 핵심 정리

1) Annotation 기반 Bean 등록

 

    (1) @Component

    클래스를 Spring Bean으로 자동 등록할 때 사용한다.

 

    (2) Component Scan

    @Component가 붙은 클래스를 Spring이 찾도록 하는 설정이다.

    Annotation 기반 Bean 등록에서는 반드시 필요하다.

 

    (3) Bean 이름

    기본 Bean 이름은 클래스명의 첫 글자를 소문자로 바꾼 이름이다.

    @Component("이름")으로 Bean 이름을 직접 지정할 수 있다.

 

2) Annotation 기반 DI

 

    (1) @Autowired

    Spring 컨테이너에서 타입이 맞는 Bean을 찾아 자동으로 주입한다.

 

    (2) @Qualifier

    같은 타입의 Bean이 여러 개 있을 때 주입할 Bean 이름을 지정한다.

 

    (3) @Value

    문자열, 숫자 같은 단순 값을 주입한다.

 

    (4) 필드 주입과 생성자 주입

    필드에 바로 주입할 수도 있고, 생성자 매개변수를 통해 주입할 수도 있다.

    생성자 주입은 객체 생성 시점에 필요한 의존성이 명확하게 드러난다.

 

3) Java 설정 방식

 

    (1) @Configuration

    Java 클래스를 Spring 설정 파일처럼 사용한다.

 

    (2) @Bean

    메소드가 반환하는 객체를 Spring Bean으로 등록한다.

 

    (3) 사용 의미

    XML bean 태그 없이도 Java 코드로 Bean을 등록할 수 있다.

    특히 외부 클래스나 생성 과정을 직접 제어해야 하는 객체를 등록할 때 유용하다.

 

4) AOP

 

    (1) AOP의 목적

    로그, 트랜잭션, 보안, 인증처럼 여러 곳에서 반복되는 공통 기능을 핵심 기능과 분리한다.

 

    (2) Aspect

    Advice와 PointCut을 합친 개념이다.

 

    (3) Advice

    실제 실행될 공통 기능 코드이다.

 

    (4) PointCut

    Advice를 적용할 위치를 정하는 조건이다.

 

    (5) JoinPoint

    Advice가 적용될 수 있는 지점이다.

    Spring AOP에서는 메소드 호출 시점이 중심이다.

 

    (6) Weaving

    Advice를 핵심 로직에 끼워 넣는 작업이다.

 

    (7) Proxy

    대상 객체 대신 호출을 받아 Advice를 적용하고 Target Object를 호출하는 대리 객체이다.

 

5) Spring AOP의 특징

 

    (1) Proxy 기반

    Spring AOP는 대상 객체를 감싸는 Proxy를 만들어 동작한다.

 

    (2) 런타임 적용

    Spring AOP는 런타임 시점에 Proxy를 통해 공통 기능을 적용한다.

 

    (3) 메소드 중심

    Spring AOP는 메소드 JoinPoint만 지원한다.

    더 다양한 JoinPoint가 필요하면 AspectJ 같은 프레임워크를 사용할 수 있다.

 

6) 오늘 배운 점

 

    (1) XML 설정에서 Annotation 설정으로 발전했다

    이전에는 Bean 등록과 의존성 주입을 XML에 직접 작성했다.

    오늘은 @Component, @Autowired, @Qualifier, @Value를 사용해 Java 코드 안에서 Bean 등록과 주입을 처리하는 방식을 배웠다.

 

    (2) Bean 등록 방식이 다양해졌다

    @Component로 클래스 자체를 Bean으로 등록할 수도 있고, @Configuration과 @Bean을 이용해 메소드 반환 객체를 Bean으로 등록할 수도 있었다.

 

    (3) 자동 주입도 기준이 필요하다

    @Autowired는 편리하지만 같은 타입 Bean이 여러 개 있으면 모호해질 수 있다.

    이때 @Qualifier로 어떤 Bean을 사용할지 명확하게 지정해야 한다.

 

    (4) AOP는 공통 기능 분리 기술이다

    로그, 트랜잭션, 보안처럼 여러 곳에서 반복되는 코드를 핵심 로직에서 분리할 수 있다.

    AOP를 사용하면 핵심 기능 코드는 깔끔하게 유지하고, 공통 기능은 필요한 시점에 적용할 수 있다.

 

    (5) 앞으로의 흐름

    Annotation 기반 DI와 AOP는 Spring MVC와 Spring Boot에서도 계속 사용되는 중요한 개념이다.

    Controller, Service, DAO 자동으로 Bean으로 등록하고, 트랜잭션이나 로그 같은 공통 기능을 AOP 처리하는 구조로 확장될 있다.