Spring 기본 원리

zihooy·2023년 6월 13일
0

Spring

목록 보기
1/3
post-thumbnail

Spring의 기본 원리에 대해 알아보자.

🏹 Spring이란

Spring은 Java 기반의 오픈 소스 애플리케이션 개발 프레임워크이다.
개발자들이 Java 애플리케이션을 보다 쉽고 효율적으로 개발할 수 있도록 도와주는 도구와 라이브러리의 집합이다.

Spring은 다양한 모듈과 기능을 제공하여 애플리케이션 개발을 단순화하고 생산성을 향상시킨다.
주요 기능으로는 의존성 주입(Dependency Injection), 관점 지향 프로그래밍(Aspect-Oriented Programming), 데이터 액세스, 웹 개발, 보안 등이 있다.

IoC (제어의 역전)

IoC(Inversion of Control)란, 말 그대로 제어의 주체가 역전되어, 개발자가 아닌 외부에서 제어가 되게 하는 것이다.
조금 더 구체적으로 말하자면, 객체의 생성과 생명주기 관리를 개발자가 직접 제어하는 것이 아니라, 외부에서 제어되도록 하는 것이다.

일반적으로 Spring에서는 프레임워크나 컨테이너가 객체의 생명주기를 관리하고 필요에 따라 객체를 생성하고 주입한다. 이는 개발자가 객체의 생성과 관리에 신경 쓰지 않고 핵심 비즈니스 로직에 집중할 수 있도록 도와준다.

IoC는 객체지향 프로그래밍의 구현 원칙 중 하나로, 객체 간의 결합도를 낮추고 유연하고 확장 가능한 코드를 작성하는 데 도움이 된다.

DI (의존성 주입)

DI(Dependency Injection)는 IoC의 구체적인 구현 방법 중 하나로, 객체가 다른 객체에 의존하는 경우 해당 의존성을 외부에서 주입받는 것이다. 즉, 객체가 필요로 하는 의존성을 직접 생성하거나 찾는 것이 아니라, 외부에서 주입되어 사용된다. 이를 통해 객체 간의 결합도를 낮출 수 있고, 코드의 재사용성과 유지보수성을 높일 수 있다. DI는 주로 생성자 주입, setter 주입, interface 주입 등의 방식으로 이루어진다.

🏹 Spring Container와 Spring Bean

이제 IoC와 DI가 Spring에서 어떻게 구현되는지 살펴보자.
이 때, Spring Container와 Spring Bean에 대한 이해가 있어야 한다.

Spring Container는 bean을 생성하고 관리하는 객체이며, bean은 Container에 의해 생성되고 관리되는 Spring 애플리케이션의 핵심 구성 요소이다.

Spring Container

Spring 컨테이너는 Spring 프레임워크에서 IoC(Inversion of Control)와 DI(Dependency Injection)를 구현하고 관리하는 핵심 컴포넌트이다. 컨테이너는 Spring 애플리케이션의 실행 시점에서 객체를 생성, 구성 및 관리하는 역할을 담당한다.

Spring 컨테이너는 빈(Bean)의 인스턴스화, 의존성 주입, 빈의 생명주기 관리 등을 담당한다. 애플리케이션에서 필요한 객체들을 컨테이너에 등록하고, 컨테이너는 이들 객체를 필요에 따라 생성하고 관리한다.

Spring Bean

Spring에서 "Bean"은 Spring IoC 컨테이너에 의해 관리되는 객체이다.
Bean은 Spring 애플리케이션의 핵심 구성 요소이며, 스프링의 IoC 기능을 통해 생성, 구성 및 관리된다.

Bean의 특징은 다음과 같다.

생명주기 관리

Spring 컨테이너는 Bean의 생명주기를 관리한다. Bean의 생성, 초기화, 소멸 등의 작업을 컨테이너가 수행하여 개발자는 이에 대한 신경쓰지 않고 Bean을 사용할 수 있다.

의존성 주입(Dependency Injection)

Spring은 의존성 주입(DI)을 통해 Bean에 필요한 의존 객체를 주입한다. 이를 통해 개발자는 직접 의존 객체를 생성하거나 관리하지 않고, 컨테이너가 자동으로 의존성을 처리한다.

스코프 관리

Bean은 여러 가지 스코프를 가질 수 있다. 예를 들어, 싱글톤 스코프는 컨테이너당 하나의 인스턴스가 생성되는 반면, 프로토타입 스코프는 요청마다 새로운 인스턴스가 생성된다. Spring은 이러한 스코프를 제공하고 관리한다.

어노테이션 기반 설정

Spring은 XML 이외에도 어노테이션 기반의 설정을 지원한다. @Component, @Service, @Repository 등의 어노테이션을 사용하여 Bean을 정의하고 컨테이너에 등록할 수 있다.

코드를 통해 Spring Container, Bean 이해하기

// Bean class
public class MyBean {
    private String message;

    // Setter method for message
    public void setMessage(String message) {
        this.message = message;
    }

    // Business method
    public void greet() {
        System.out.println("Message from MyBean: " + message);
    }
}

// Configuration class
@Configuration
public class AppConfig {

    // Bean definition method
    @Bean
    public MyBean myBean() {
        MyBean bean = new MyBean();
        bean.setMessage("Hello, Spring!");
        return bean;
    }
}

// Main class
public class Main {

    public static void main(String[] args) {
        // Creating the Spring container
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

        // Retrieving the bean from the container
        MyBean bean = context.getBean(MyBean.class);

        // Using the bean
        bean.greet();
    }
}

위의 예시에서 MyBean이라는 Bean class를 정의한다.
이 class는 message property와 greet 메서드를 가지고 있다.

AppConfig는 스프링에서 사용되는 설정 class이다. 스프링 애플리케이션에서 빈(Bean)을 정의하고 구성하기 위해 사용된다. @Configuration 어노테이션을 클래스에 붙여서 스프링에게 해당 클래스가 설정 클래스임을 알려준다.

myBean 메서드에서는 MyBean 인스턴스를 생성하고 메시지를 설정한다.

Main 클래스에서는 Spring 컨테이너(ApplicationContext)를 생성하기 위해 설정 클래스를 준다. 그 후, getBean 메서드를 사용하여 컨테이너로부터 빈을 검색한다. 마지막으로, 검색한 빈을 사용하여 greet 메서드를 호출한다.

Spring 컨테이너는 빈의 생명주기를 관리하며 의존성 주입을 처리한다. 컨테이너는 MyBean 객체를 인스턴스화하고 메시지 프로퍼티를 주입한 완전히 구성된 빈을 제공한다.

🏹 IoC, DI의 구현

XML 설정 파일

전통적인 방식으로, XML 파일에 빈의 정의와 의존성 설정을 작성한다.
XML 파일은 ApplicationContext의 ClassPathXmlApplicationContext 등과 같은 구현체를 사용하여 로드되고 해석된다.

<bean> 요소는 bean의 정의를 나타내며, id 속성은 bean의 고유한 식별자를 나타낸다. class 속성은 해당 bean이 어떤 클래스를 인스턴스화할지를 나타낸다.

<property> 요소는 bean에 속성 값을 주입하는데 사용된다. name 속성은 주입할 속성의 이름을 지정하고, ref 속성은 주입할 bean의 참조를 나타낸다.

아래의 코드를 살펴보자.

<!-- applicationContext.xml -->

<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">

    <!-- bean 정의 -->
    <bean id="userService" class="com.example.UserService">
        <property name="userRepository" ref="userRepository" />
    </bean>

    <bean id="userRepository" class="com.example.UserRepositoryImpl" />

</beans>

위의 예시에서는 UserService라는 bean을 정의하고, UserRepository라는 의존성을 주입하고 있다. UserRepository는 UserRepositoryImpl 클래스의 인스턴스로 주입되며, 이를 위해 userRepository라는 식별자를 사용한다.

어노테이션

Spring 2.5 버전부터 지원되는 어노테이션 기반의 설정 방식이다.
@Component, @Service, @Repository 등의 어노테이션을 사용하여 클래스를 Spring Bean으로 등록하고, @Autowired, @Inject 등의 어노테이션을 사용하여 의존성을 주입한다.

@Autowired

@Autowired를 통해 해당 필드, 생성자 또는 메서드 매개변수에 자동으로 의존성을 주입하여 객체를 생성하고 초기화할 수 있다.

아래는 @Autowired를 사용하여 필드에 의존성을 주입하는 예시이다.

@Component
public class MyComponent {

    @Autowired
    private MyDependency myDependency;

    // ...
}

위의 예시에서 MyComponent 클래스의 myDependency 필드에 @Autowired 어노테이션을 사용하여 MyDependency 타입의 빈을 자동으로 주입한다. 이렇게 하면 스프링은 MyDependency 타입에 해당하는 빈을 찾아서 필드에 자동으로 주입한다.

Component Scan

스프링이 자동으로 빈을 검색하고 등록하는 방식으로, 클래스 경로를 스캔하여 특정 패키지나 어노테이션을 기준으로 빈을 찾아 등록한다. 이를 위해 @ComponentScan 어노테이션을 사용하며, 일반적으로 어노테이션 기반의 설정 방식과 함께 사용된다.

Componet Scan 사용하기

  1. 컴포넌트 스캔을 활성화하는 설정 추가
    스프링 설정 파일(예: XML 설정 파일 또는 Java 설정 클래스)에 컴포넌트 스캔을 활성화하는 설정을 추가해야 한다.

  2. 컴포넌트에 어노테이션 추가
    컴포넌트 스캔 대상이 되는 클래스에 @Component 어노테이션 또는 그와 유사한 어노테이션을 추가한다. 이러한 어노테이션은 스프링에게 해당 클래스가 빈으로 등록되어야 함을 알려준다.

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
    // 추가적인 설정
}

위의 예시에서 @ComponentScan 어노테이션은 com.example 패키지와 그 하위 패키지를 스캔하여 컴포넌트를 찾는다. 이 패키지에 속한 클래스 중 @Component 어노테이션이나 그와 유사한 어노테이션이 있는 경우 해당 클래스는 스프링 컨테이너에 빈으로 등록된다.

profile
thisIsZihooLog

0개의 댓글