[EC-Spring] 3주차-DI, IoC, POJO

38018 단어 SpringJavaJava

DI [Dependency Injection] (의존성 주입)
IoC [Inversion of Controll] (제어의 역전)
POJO [Plain Old Java Object] (오래된 방식의 단순 자바 객체)

IoC는 스프링 프레임워크의 심장부
IoC 컨테이너는 POJO를 구성하고 관리
스프링 프레임워크의 가장 중요한 의의는 POJO로 자바 애플리케에션을 개발하는 것
스프링의 주요 기능은 대부분 IoC 컨테이너 안에서 POJO를 구성 및 관리하는 일과 관련

어떤 종류의 프로젝트에 스프링 프레임워크를 활용하더라도 첫 단추는 POJO와 IoC 컨테이너를 다루는 기술

'빈(bean)'과 'POJO 인스턴스'는 자바 클래스로 생성한 객체 인스턴스
'컴포넌트(component)'와 'POJO 클래스'는 객체 인스턴스를 생성하는 데 필요한 실제 자바 클래스

POJO 클래스 설계
@Configuration, @Bean을 붙인 자바 구성 클래스를 만들거나,
@Component, @Repository, @Service, @Controller 등을 붙인 자바 컴포넌트를 구성
IoC 컨테이너는 에너테이션을 붙인 자바 클래스를 스캐닝scanning(탐색)하여 애플리케이션의 일부인 것처럼 POJO 인스턴스/빈을 구성

예제

@Configuration, @Bean을 붙인 자바 구성 클래스를 생성

build.gradle

plugins {
    id 'org.springframework.boot' version '2.6.6'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'org.ec'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
    useJUnitPlatform()
}

SequenceGenerator.java

package org.ec.springcore.sequence;

import java.util.concurrent.atomic.AtomicInteger;

public class SequenceGenerator {
    private String prefix;
    private String suffix;
    private int initial;
    private final AtomicInteger counter = new AtomicInteger();

    public SequenceGenerator() {

    }

    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    public void setSuffix(String suffix) {
        this.suffix = suffix;
    }

    public void setInitial(int initial) {
        this.initial = initial;
    }

    public String getSequence() {
        StringBuilder builder = new StringBuilder();
        builder
                .append(prefix)
                .append(initial)
                .append(counter.getAndIncrement())
                .append(suffix)
                ;
        return builder.toString();
    }
}

SequenceGeneratorConfig.java

package org.ec.springcore.sequence.config;

import org.ec.springcore.sequence.SequenceGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SequenceGeneratorConfig {

    @Bean
    public SequenceGenerator sequenceGenerator() {
        SequenceGenerator sequenceGenerator = new SequenceGenerator();
        sequenceGenerator.setPrefix("30");
        sequenceGenerator.setSuffix("A");
        sequenceGenerator.setInitial(100000);
        return sequenceGenerator;
    }
}

SpringcoreApplication.java

package org.ec.springcore;

import org.ec.springcore.sequence.SequenceGenerator;
import org.ec.springcore.sequence.config.SequenceGeneratorConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringcoreApplication {

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(SequenceGeneratorConfig.class);


        SequenceGenerator generator = context.getBean(SequenceGenerator.class);

        System.out.println(generator.getSequence());
        System.out.println(generator.getSequence());
    }

}
301000000A
301000001A

@Component 등을 붙인 자바 컴포넌트를 구성

Sequence.java

package org.ec.springcore.sequence;

public class Sequence {

    private final String id;
    private final String prefix;
    private final String suffix;

    public Sequence(String id, String prefix, String suffix) {
        this.id = id;
        this.prefix = prefix;
        this.suffix = suffix;
    }

    public String getId() {
        return id;
    }

    public String getPrefix() {
        return prefix;
    }

    public String getSuffix() {
        return suffix;
    }
}

SequenceDao.java

package org.ec.springcore.sequence.dao;

import org.ec.springcore.sequence.Sequence;

public interface SequenceDao {

    Sequence getSequence(String sequenceId);
    int getNextValue(String sequenceId);
}

SequenceDaoImpl.java

package org.ec.springcore.sequence.dao.impl;

import org.ec.springcore.sequence.Sequence;
import org.ec.springcore.sequence.dao.SequenceDao;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

@Component("sequenceDao")
public class SequenceDaoImpl implements SequenceDao {

    private final Map<String, Sequence> sequences = new HashMap<>();
    private final Map<String, AtomicInteger> values = new HashMap<>();

    public SequenceDaoImpl() {
        sequences.put("IT", new Sequence("IT", "30", "A"));
        values.put("IT", new AtomicInteger(10000));
    }

    public Sequence getSequence(String sequenceId) {
        return sequences.get(sequenceId);
    }

    public int getNextValue(String sequenceId) {
        AtomicInteger value = values.get(sequenceId);
        return value.getAndIncrement();
    }
}

SequenceGeneratorConfig.java

package org.ec.springcore.sequence.config;

import org.ec.springcore.sequence.SequenceGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;

@Configuration
@ComponentScan(
        basePackages = "org.ec.springcore.sequence",
        includeFilters = {
                @ComponentScan.Filter(
                        type = FilterType.REGEX,
                        pattern = {"org.ec.springcore.sequence.dao.*Dao"})
        },
        excludeFilters = {
                @ComponentScan.Filter(
                        type = FilterType.ANNOTATION,
                        classes = {org.springframework.stereotype.Controller.class}) }
)
public class SequenceGeneratorConfig {

    @Bean
    public SequenceGenerator sequenceGenerator() {
        SequenceGenerator sequenceGenerator = new SequenceGenerator();
        sequenceGenerator.setPrefix("30");
        sequenceGenerator.setSuffix("A");
        sequenceGenerator.setInitial(100000);
        return sequenceGenerator;
    }
}
package org.ec.springcore;

import org.ec.springcore.sequence.SequenceGenerator;
import org.ec.springcore.sequence.config.SequenceGeneratorConfig;
import org.ec.springcore.sequence.dao.SequenceDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringcoreApplication {

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(SequenceGeneratorConfig.class);

        SequenceDao sequenceDao = context.getBean(SequenceDao.class);

        System.out.println(sequenceDao.getNextValue("IT"));
        System.out.println(sequenceDao.getNextValue("IT"));
    }

}

출처

스프링 5 레시피(4판)

좋은 웹페이지 즐겨찾기