Spring

[Spring] 스프링 프레임워크

yn98 2024. 10. 1. 17:26

Spring Framework의 구조

  • Spring은 개발 양식을 제시하여 개발자의 역량을 획일화하고, 일관성 있는 코드를 작성할 수 있게 도와준다.
  • 장점으로는 쉬운 관리, 구현 시간 단축, 유지보수 용이, 재사용성 증가가 있다.

Spring FrameWork란?

한 문장으로 말하면, "IoCAOP를 지원하는 경량의 프레임워크"

 

여기서 IoC란, (Inversion of Control) 제어의 역행을 뜻한다.

제어의 역행이란, 객체 관리의 주체가 개발자에서 프레임워크로 바뀌는 개념이다.

예전에는 개발자가 직접 생성(new)하고 관리했다면, Spring에서는 컨테이너가 이 역할을 대신한다.

서블릿컨테이너(예: 톰캣)가 서블릿을 대신 생성하고 관리해주듯이, Spring 컨테이너는 개발자가 직접 new를 사용하지 않고도 객체를 관리해준다.

 

예를 들어, 아래 코드에서는 Spring 컨테이너가 GalaxyPhone 객체를 생성하고 관리한다.

// 스프링 컨테이너 구동
AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");

// 컨테이너에 미리 생성된 bean을 가져옴 (싱글톤 패턴)
Phone p1 = (Phone) factory.getBean("samsung");
Phone p2 = (Phone) factory.getBean("samsung");
Phone p3 = (Phone) factory.getBean("samsung");

p1.powerOn();
p2.powerOn();
p3.powerOn();

factory.close();

 

위 코드에서 getBean() 메서드를 호출할 때마다 samsung이라는 객체가 반환되지만, Spring이 객체를 단 한 번만 생성하여 관리하기 때문에 동일한 인스턴스를 참조한다. 이는 Spring이 자동으로 싱글톤 패턴을 유지하고 있다는 것을 의미한다.

 

AOP란, 풀어 말하면 (Aspect-Oriented Programming, 관점 지향 프로그래밍) 이다. AOP는 비즈니스 로직과 별개로 공통적인 기능(로깅, 트랜잭션 관리 등)을 모듈화하여 코드 간결화 및 유지보수를 용이하게 한다.

 

경량이라는 개념은 소프트웨어 개발에서 주로 간결하고 효율적인 구조를 의미한다. Spring Framework와 같은 프레임워크에서 경량이라는 단어를 사용하면, 불필요한 무거운 코드나 복잡한 설정을 최소화한, 효율적인 설계 방식을 가리킨다.

 

Spring Framework복잡한 객체나 설정을 피하고, 단순하고 가벼운 방식으로 소프트웨어를 개발할 수 있도록 지원하는 경량 프레임워크다. 이를 통해 개발자들은 POJO 객체를 사용하여 더욱 간편하게 애플리케이션을 설계할 수 있다.

 

Spring은 기본적으로 싱글톤 패턴을 유지하여, 객체가 메모리에 단 한 번만 생성된다. 따라서 xml에 scope를 조절하지 않으면 아래와 같은 콘솔 출력이 나타날 수 있다.

 

<예시 코드> - Client.java

package test;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

public class Client {
	public static void main(String[] args) {
		
		//스프링컨테이너 factory = new 스프링컨테이너();
		AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
		// 컨테이너를 구동시키는 코드
		
		//Phone phone = factory야.폰객체좀("아이폰");
		Phone phone = (Phone)factory.getBean("apple");
		
		//Phone phone = new GalaxyPhone();
		// Bean == 자바객체 == 객체 == POJO
		// 객체를 요청하다.
		// == look up
		phone.powerOn();
		phone.powerOff();
		
		Phone p1 = (Phone)factory.getBean("samsung");
		Phone p2 = (Phone)factory.getBean("samsung");
		Phone p3 = (Phone)factory.getBean("samsung");
		p1.powerOn();
		p2.powerOn();
		p3.powerOn();
		
		factory.close(); // 안정성을 위해 적음
	}

}

 

GalaxyPhone.java

package test;

import java.util.Random;

public class GalaxyPhone implements Phone {
	private int num;
	
	public GalaxyPhone() {
		this.num = new Random().nextInt(100);
		System.out.println("갤럭시 객체 생성");
	}

	@Override
	public void powerOn() {
		System.out.println("갤럭시 전원 ON"+this.num);	
	}

	@Override
	public void powerOff() {
		System.out.println("갤럭시 전원 OFF");	
	}
	
	

}

<결과>

 

 

 

위 출력은 동일한 갤럭시 객체가 메모리 상에 하나만 존재한다는 것을 의미한다.

그러나 여러 개의 인스턴스가 필요하다면, Spring의 scope 설정을 통해 객체의 생성 방식을 바꿀 수 있다.

  • 싱글톤 (Singleton): 기본 설정. 객체가 한 번만 생성됨.
  • 프로토타입 (Prototype): 요청할 때마다 새로운 객체가 생성됨.

 

이를 변경하려면, xml 코드에 scope를 prototype로 변경하면 된다.

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
                  http://www.springframework.org/schema/beans/spring-beans.xsd">
   
   <!-- scope 값 설정하기 -->
   <bean class="test.IPhone" id="apple" lazy-init="true" init-method="initMethod" scope="singleton" />
   <bean class="test.GalaxyPhone" id="samsung" lazy-init="true" scope="prototype"/>
   
</beans>

 

scope 값을 설정하지 않으면 default값은 singleton이기 때문에, 위처럼 랜덤값을 여러개 설정하고 싶으면 scope를 prototype로 설정하면 된다.

 

위처럼 설정하면

 

객체가 3번 생성되고, 각 값이 랜덤으로 잘 출력된 것을 볼 수 있다.

 


프로젝트 구조

  • src/main/java: 자바 코드를 작성하는 곳
  • src/main/resources: 설정 파일을 작성하는 곳
  • src/main/webapp: 프론트엔드 작업을 하는 곳
  • pom.xml: 프로젝트의 설정 파일