Spring Framework

강호수·2022년 10월 11일
0

Framework란?

소프트웨어의 구체적인 부분에 해당하는 설계와 구현을 재사용이 가능하게끔 협업화된 형태로 클래스들을 제공하는 것

장점

  • 효율적 코드 작성 가능
  • 정해진 규약이 있어 애플리케이션을 효율적으로 관리 가능

단점

  • Framework 자체에 대한 학습이 필요
  • 자유롭고 유연한 개발이 어려움

Framework와 Library의 차이

Library

코드는 개발자가 작성을 하게 될 것이다. 이렇게 개발자가 짜 놓은 코드에서 필요한 기능이 있으면 해당 라이브러리를 호출해서 사용하게 된다. 이를 Library라고 한다.

Framework

프레임워크에서 지원하는 기능, 메서드는 코드 상에는 보이지 않는 상당히 많은 일들을 한다. Framework에서는 개발자가 작성한 코드를 사용해서 애플리케이션의 흐름을 만들어낸다. 즉 애플리케이션 흐름의 주도권이 개발자가 아닌 Framework에 있는 것이다.

Spring Framework 특징

POJO (Plain Old Java Object)


위의 그림은 Spring 삼각형이라는 그림이다. 이는 Spring의 핵심 개념들을 모두 표현하고 있다.

POJO 프로그래밍

이는 POJO를 이용해서 프로그래밍 코드를 작성하는 것을 의미한다. 이 때 POJO 프로그래밍이라 작성된 것이라 불리우기 위해서는 두 가지 정도의 규칙을 지켜야한다.

  • Java나 Java의 스펙에 정의된 것 이외에는 다른 기술이나 규약에 얽매이지 않아야한다.
public class ABC extends ActionForm {
	~~
}

ActionForm 클래스는 Struts라는 웹 프레임워크에서 지원하는 클래스인데, 이렇게 특정 기술에 종속된 채 코드를 작성하게 되면 다른 기술로 변경하고자 할 때 전부 일일이 제거하거나 수정해야한다. 이는 즉 객체지향 설계 기법을 적용하기 어려워짐을 의미한다.

  • 특정 환경에 종속적이지 않아야 한다.

서블릿 기반의 웹 애플리케이션을 실행 시키는 서블릿 컨테이너인 Tomcat을 사용한다고 해보자. 이 때 만약 시스템의 요구사항이 변경되면서 Zetty라는 다른 서블릿 컨테이너를 사용해야하는 상황이 생긴다. 이 때 그 환경에 종속되어 있다면 모든 코드들을 다 걷어내고, Zetty로 수정해야하는 상황이 생길 수도 있다.

IoC (Inversion of Control)

애플리케이션 흐름의 주도권이 뒤바뀐 것을 IoC라고 한다. 즉 주도권이 개발자가 아닌 컴퓨터에게 있게되는 것을 의미한다.


일반적으로 main() 메서드가 호출된 뒤 그 뒤에 이것저것 쓴 것들이 실행된다. 이것은 애플리케이션의 일반적인 제어 흐름이다.
이번에는 서블릿 컨테이너를 통해 실행될 때를 봐보자. Java 콘솔 애플리케이션은 main() 메서드가 종료되면 애플리케이션의 실행이 종료되지만, 서블릿 컨테이너에는 서블릿 클래스만 존재할 뿐 별도의 main() 메서드가 존재하지 않는다. 서블릿 컨테이너 내의 컨테이너 로직이 서블릿을 직접 실행시켜주는 것인데, 이 때 애플리케이션의 주도권은 서블릿 컨테이너에 있다. 이것을 IoC라고 한다.

DI (Dependency Injection)

예를 들어 A class에다가 B class의 객체를 생성하게 되면 A class에서는 B의 기능을 쓸 수 있게 된다. 이 때 A 클래스는 B 클래스에 의존한다 라는 표현을 쓴다.

  • 의존 관계 주입
~~
public static void main(String[] args){
	MenuService menuService = new MenuService();
    ~~
}

위는 의존 관계만 성립시키고 의존성을 주입시키지는 않았다.

  • 의존성 주입
public class MenuController {
	~~
    public MenuController(MenuService menuService){
    	this.menuService = menuService;
	}
    ~~
}

이처럼 생성자를 통해서 어떤 클래스의 객체를 전달받는 것을 의존성 주입이라고 한다. 또한 이것을 외부에서 객체를 주입한다고 한다.

의존성 주입이 되어있는데, 클래스 이름을 바꿔야한다면?

예를 들어 간단한 상황을 보여주기 위해 Stub 형태로 주고받을 때가 생길 것이다. 이 때 MenuService -> MenuServiceStub 으로 변경하게 되면 의존성 주입해주었던 모든 것을 바꾸어야할 수도 있다. 이 때 필요한 것이 느슨한 의존성 주입이다.

public interface MenuService {
	~~
}

public class MenuServiceStub implements MenuService {
	@Override
    public ~~
}

이렇게 의존성 주입을 해둘 경우 Controller에서 인터페이스를 생성자로 받게 되고, MenuService의 인터페이스 구현 클래스이면 어떤 클래스도 전부 주입받을 수 있게 된다.

더욱 느슨하게 하고싶은데, new를 통한 생성 못없앨까?

스프링이 해줄거다! @Bean, @Configuration 등등 그런 것들이 도와줄 것이다. 나중에 공부해보자.

AOP (Aspect Oriented Programming)

이는 관심 지향 프로그래밍으로 해석할 수 있다. AOP에서 Aspect는 애플리케이션에 필요한 기능 중에서 공통적으로 적용되는 공통 기능에 대한 관심과 관련 있다. 이러한 공통 기능들에 대한 관심사를 공통 관심 사항이라고 한다. 그리고 주 목적을 달성하기 위한 핵심 로직에 대한 관심사를 핵심 관심 사항이라고 한다.

  • 공통 관심 사항
    ex) 로깅, 보안, 트랜잭션
  • 핵심 관심 사항
    ex) 메뉴 주문, 변경

AOP라는 것은 애플리케이션의 핵심 업무 로직에서 로깅이나 보안, 트랜잭션 같은 공통 기능 로직들을 분리하는 것이다.

AOP의 필요 이유

  • 코드의 간결성 유지
  • 객체 지향 설계 원칙에 맞는 코드 구현
  • 코드의 재사용

보통 Transaction을 위한 코드가 꽤 길어진다. 이것을 중복된 코드를 공통화해서 재사용 가능하도록 만들어야 한다. 이 때 쓰이는 것이 @Transactional이라는 애노테이션이다.

~~
public class Example{
	~~
    public void registerMember ~~{
    	try {
        	~~
        } catch (SQLException e) {
        	~~
		}
 	}
}

@Transactional
public class Example{
	~~
    public void registerMember ~~{
    	~~
	}
}

위와 같이 애너테이션 하나를 붙여줌으로 인해서 더욱 간결하게 표현될 수 있고, 이것이 AOP를 활용한 대표적인 예시라고 볼 수 있다.

PSA (Portable Service Abstraction)

public abstract class Child {
	~~
    protected abstract void smile();
    ~~
}
public class NewBornBaby extends Child {
	@Override
    protected void smile(){
    	sout("신생아는 가끔 웃어요");
    }
}

public class Infant extends Child {
	@Override
    protected void smile(){
    	sout("영아는 많이 웃어요");
    }
}

public class Toddler extends Child {
	@Override
    protected void smile(){
    	sout("유아는 웃길 때 웃어요");
    }
}

위와 같이 Child 추상 클래스를 만들어둔 뒤 여러 class를 만든다. 그리고 그 때마다의 다른 출력값들을 만들고, 그것을 객체 생성을 통해 다시 사용할 수 있다.
이는 결국 느슨한 결합에 한 몫 하게되고, 일관된 방식으로 해당 서비스의 기능을 사용할 수 있게 된다.

PSA가 필요한 이유는 서비스를 이용하기 위한 접근 방식을 일관된 방식으로 유지함으로써 사용하는 기술이 변경되더라도 최소한의 변경을 갖게 하기 위함이다. 따라서 애플리케이션의 요구 사항 변경에 유연하게 대처할 수 있게 된다.

0개의 댓글