Spring의 핵심 개념 (POJO, IoC/DI, AOP, PSA)

Doridam·2023년 5월 31일
0

Spring🌱 & Boot 🌼

목록 보기
6/12


Spring의 핵심 개념에 대해 알아보자.


SpringFramework
Spring은 Java를 기반으로 만들어진 엔터프라이즈 경량급 프레임워크다. 다양한 라이브러리와 기능을 제공해 보다 쉽게 어플리케이션을 만들 수 있게 해주며, POJO와 3개의 핵심 개념으로 설명된다.


POJO (Plain Old Java Object) :

"옛날 방식의 간단한 자바 오브젝트"

Spring이 탄생하게된 이유.
JAVA EE와 같은 중량 프레임워크를 사용하게 되면서 "무거운" 객체를 만드는것에 반발해서 나온 용어이다.
순수한 자바객체로 특정 라이브러리, 환경, 프레임워크에 의존하지 않고 종속되지않고 객체지향원리에 충실하며 필요에 따라 재활용될 수 있는 오브젝트라고 할 수 있다.

MVC 패턴의 Model 객체가 하나의 예시다.

public class a {
	private int no;
    private String name;
    public void setNo(int no){
    	this.no = no;
    }
    public int getNo(){
    	return no;
    }
    ...
}

위 코드와 같이 어떠한 라이브러리(의존성 없음)나 환경(상속 없음)에 종속되지 않고 필요에 따라 재활용(DTO)되는 객체를 POJO로 설계된 객체로 볼 수 있다.


IoC (Inversion of Control) / DI (Dependency Injection) :

"제어의 역전"과 "의존성 주입"

제어의 역전 : 객체를 생성, 제거 하는 제어권이 개발자가 아닌 프레임워크(Spring, IoC Container) 에게 위임 되는것을 IoC, "제어의 역전"이라고 한다.

public class A {}
public class B {
	private A a;
    public B(){
    	this.a = new A();
    }
}

1. 개발자의 제어

@Component
public class A {}
public class B{
	private A a;
    @Autowired
    public b(A a){
    	this.a = a;
    }
}

2. IoC container(Spring)의 제어

1번 코드의 경우 new 키워드를 사용하여 직접 객체를 생성 했지만, 2번 코드는 @Component@Autowired를 사용하여 new 키워드가 없음에도 객체가 생성되는 코드이다.
이처럼 개발자가 직접 객체를 관리 하는게 아닌 프레임워크에게 객체 생성 및 생명주기를 맡기는것이 제어의 역전이라 할 수 있다.

의존성 주입 : 객체간의 의존관계를 직접 생성하는것이 아닌 외부(IoC Container)로 부터 주입받아 동적으로 의존관계가 성립되는것을 DI, "의존성 주입"이라고 한다.

의존성 주입 방법에는 3가지가 있다.
※ DI되는 객체는 반드시 Bean 등록이 되어있어야한다. 아래 코드는 @Component 어노테이션을 이용해 Bean을 등록한 상태이다.

@Component
public class A {}
  1. 생성자 주입
public class B{
	private A a;
    @Autowired
    public b(A a){
    	this.a = a;
    }
}
  1. Setter 주입
class A {
	@Autowired
    public void setB(B b){
    	this.b = b;
    }
}

3.필드주입

class A {
	@Autowired
    private B b;
}

이 3가지 방법중 스프링에서 권장하는 방법은 1. 생성자 주입이다.

생성자 주입

  1. 순환참조 예방
    Application 작동시점에서 순환참조를 확인할 수 있다.
    Spring Boot 2.6 부터는 순환참조가 기본적으로 허용되지 않기 때문에
    이하 버전에서만 효과가 있다.
  2. 불변성 보장
    Application 실행 시점에서 의존성이 주입되고 final 키워드를 사용하여 다른 방법과 달리
    객체의 불변성 을 보장할 수 있다.
  3. 테스트의 편리함
    컴파일 시점의 객체를 주입받아 테스트 코드 작성이 가능하고, 누락 객체가 있을 경우
    컴파일 시점에서 확인되기 때문에 테스트를 보다 쉽게 할 수 있다.

Setter 주입

  1. 객체 변경이 필요한 경우 사용된다.

필드 주입

  1. 코드가 간결하다.
  2. 프레임워크에 지나치게 의존적이고 외부에서 변경이 불가능(테스트가 힘들어진다.)하다.

AOP (Aspect Oriented Programming) :

"관점 지향 프로그래밍"

로깅, 보안, 트랜잭션과 같은 공통 기능을 분리하여 하나의 책임을 가지게 하는 프로그래밍 기법.
코드의 재사용으로 생산성을 높이고, 유지보수를 용이하게 만든다.

해당 사진처럼 횡단관심 기능이 핵심관심 기능에 공통으로 들어가는데, 이것을 분리하여 핵심관심에 재사용하는 것이 AOP다.

AOP 용어

Advice : AOP 관점에서 분리된 횡단관심 기능, 실제로 Joinpoint에서 사용될 코드
Target : AOP 관점에서 핵심관심 기능, Advice가 적용될 대상
Joinpoint : Advice를 적용 가능한 지점, 특정 작업이 실행되는 시점
※ 스프링은 메소드에 대한 Joinpoint만 가능하다 : 프록시를 이용해 AOP를 구현하기 때문.
Pointcut : 실제로 Advice가 적용되는 Joinpoint를 나타냄.
Weaving : Joinpoint를 Advice로 감싸는 과정.

Aspect를 사용하는 예시

	// Aspect 어노테이션 사용
	@Aspect
   	class A{		// 이곳에서 타겟은 "b()" 메소드다.
    	// Around: 타켓의 실행 전후로 처리 됨
    	@Around("b()")
		public void test(){
      		// b() 메소드의 적용될 코드
        }
        // Before: 타켓이 실행 전 처리 됨
        @Before("b()")
        public void test2(){
      		// 생략
        }
        // After Returning: 타겟이 실행 후 처리 됨
        @After Returning("b()")
        public void test3(){
  		// 생략
        }
        // After Throwing: 타겟이 예외를 발생시키면 처리 됨
        @After Throwing("b()")
        public void test4(){
  		// 생략
        }
	}

이와같이 Pointcut을 활용하여 특정지점, 또는 시점에 적용할 수 있는 코드를 작성할 수 있다.

PSA (Portable Service Abstraction) :

"간편한 서비스 추상화"

SpringFramework에서 제공하는 서비스 추상화 계층
다양한 서비스 기술을 추상화하여 코드를 특정기술에 종속시켜 구현하는것이 아닌 변경에 용이하게 편의성을 제공해준다.

PSA를 이용한 WAS 변경

해당 프로젝트에는 SpringWeb을 dependency로 가지고 있고, WAS로 Tomcat이 사용되고 있다.
하지만

build.gradle에서 spring-boot-starter-Web을 spring-boot-starter-webflux로 변경하면 내부 코드 변경없이

WAS가 Netty로 변경된다.

Spring 내부에는 이미 추상화 서비스가 구현되어 있기 때문에 같은 서비스내에서는 내부 코드 변경없이 간단하게 서비스를 변경할 수 있다.

이밖에도 트랜잭션, JDBC, 캐시와 관련된 여러가지 부분이 서비스 추상화 계층을 통해 특정 기술에 의존하지 않고 일관된 코드로 구현할 수 있게 해주는 핵심이다.


profile
도리도리담담 🐤🐥🐤🐥🐣🐣

0개의 댓글