728x90
반응형

spring

Spring Framework의 특징 세 가지중 하나인 AOP를 알아볼 것이다.

Spring삼각형

1. AOP

: 관점지향프로그래밍(Aspect Oriented Programming)이다. 쉽게 말해서 관점을 나눠서 프로그래밍 하겠다는 건데, 특정 로직을 비즈니스적인 관점과 부가적인 관점으로 나눠서 나눈 관점 기준으로 모듈화하여 프로그래밍하는 것이다.

AOP

예를 들면, 비즈니스적인 관점이라 하면 말그대로 우리가 구현하고자 하는 서비스의 핵심적인 로직부분을 가리키는 관점이고, 부가적인 관점은 해당 로직이 없어도 비즈니스에 아무런 영향이 없는 부분을 가리키는 DB연결로직이나 로깅 등을 가리키는 관점이다.

그리고 각 로직마다 반복되는 부분을 흩어진 관심사(Crosscutting Concerns)라고 하는데, AOP에서는 이러한 부분을 위에서 언급한 관점지향적으로 모듈화하여 프로그래밍할 것이다.

2. AOP의 사례

AOP의 대표적인 2가지 사례를 알아볼 것이다.

A. logging

: 로깅(logging) 기능은 로직마다 반복적이고 공통적으로 활용되는 대표적인 부가기능 중 하나이다. 이러한 로깅기능을 AOP를 활용하여 프로그래밍 한다면 아래와 같이 코딩할 수 있다.

  • ParameterAop.java
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class ParameterAop {

    @Pointcut("execution(* com.example.aop.controller..*.*(..))")
    private void cut(){}

    @Before("cut()")
    public void before(JoinPoint joinPoint){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        System.out.println(method.getName());
        Object[] args = joinPoint.getArgs();
        for(Object obj : args){
            System.out.println("type : "+obj.getClass().getSimpleName());
            System.out.println("value : "+obj);
        }
    }

    @AfterReturning(value = "cut()", returning = "returnObj")
    public void afterReturn(JoinPoint joinPoint, Object returnObj){
        System.out.println("return obj");
        System.out.println(returnObj);
    }
}
  • RestApiController.java
import com.example.aop.annotation.Decode;
import com.example.aop.annotation.Timer;
import com.example.aop.dto.User;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class RestApiController {

    @GetMapping("/get/{id}")
    public String get(@PathVariable Long id, @RequestParam String name){
        // TODO

        return id+ " "+ name;
    }

    @PostMapping("/post")
    public User post(@RequestBody User user){


        return user;
    }

}

ParameterAop.java파일에서 AOP로 모듈화할 클래스를 정의하였다.
AOP로 모듈화하기 위해서는 클래스명에 @Aspect어노테이션을 명시해주어야 한다.
@PointCut어노테이션은 모듈화된 클래스가 적용될 클래스의 경로를 지정해준다.
지정된 경로의 클래스의 메소드가 실행될 때마다 AOP로 정의된 클래스의 메소드가 실행될 것이다.
위의 코드에서 cut()메소드는 @PointCut으로 적용된 클래스의 메소드인 RestApiController.get()RestApiController.post()를 가리키게 된다.

@Before어노테이션은 지정된 메소드가 실행되기 바로 이전에 실행될 메소드에 명시된다. 해당 어노테이션에 지정된 메소드는 cut()메소드이다.
위 코드에서 before()메소드의 파라미터로 받는 JoinPointcut()메소드에서 정보를 가져올 때 활용되는 객체이다.
위 코드에서 JoinPoint객체는 HTTP 메소드와 cut()메소드에서 활용된 파라미터 값을 가져오기 위해서 활용되고 있다.

@AfterReturning어노테이션은 @Before어노테이션과 반대로 지정된 메소드가 실행된 후 바로 실행될 메소드에 명시된다. 해당 어노테이션에 지정된 메소드 역시 cut()메소드이다.
그리고 @AfterReturning어노테이션에서 returning값을 지정해주면 cut()메소드에서 반환된 값이 returning값으로 지정된 변수에 입력되어 활용할 수 있다. 위 코드에서는 returnObj변수에 활용되고 있다.

위 사례의 코드와 같이 프로그래밍을 한다면, 특정 비즈니스 로직이 실행되기 전후에 로깅기능을 모듈화하여 사용할 수 있다.

B. Timer

: 타이머(Timer)기능은 특정 로직의 실행시간을 확인시켜주는 기능이다. 이 또한 비즈니스로직과 관련이 없는 기능이기 때문에 아래와 같이 AOP로 모듈화할 수 있다.

  • TimerAop.java
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Aspect
@Component
public class TimerAop {

    @Pointcut("execution(* com.example.aop.controller..*.*(..))")
    private void cut(){}

    @Pointcut("@annotation(com.example.aop.annotation.Timer)")
    private void enableTimer(){}

    @Around("cut() && enableTimer()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        Object result = joinPoint.proceed();

        stopWatch.stop();
        System.out.println("total time : "+stopWatch.getTotalTimeSeconds());
    }
}
  • Timer.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Timer {
}
  • RestApiController.java
import com.example.aop.annotation.Decode;
import com.example.aop.annotation.Timer;
import com.example.aop.dto.User;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class RestApiController {

    @Timer
    @DeleteMapping("/delete")
    public void delete() throws InterruptedException {

        // db logic
        Thread.sleep(1000 * 2);

    }

}

Timer 기능도 역시 로깅 기능을 구현할 때와 마찬가지로 AOP를 활용하여 모듈화시켰고 코드상의 차이도 크게 없다.
하지만 두 가지정도 차이나는 부분이 있는데, 해당부분만 언급해보겠다.

첫 번째 차이는 로깅 기능을 구현할 때에는 경로 지정방식으로 @PointCut어노테이션에 해당 기능이 활용될 클래스의 경로를 지정하였는데,
Timer 기능을 구현할 때에는 @PointCut어노테이션에 특정 어노테이션을 지정하여, 지정된 어노테이션이 붙은 클래스나 메소드가 실행될 때에만 Timer기능이 실행될 수 있도록 하였다.
이를 위해 Timer라는 별도의 인터페이스를 Timer.java와 같이 작성하였다.
여기서 @Target어노테이션은 임의로 선언된 어노테이션인 @Timer어노테이션이 붙을 수 있는 타입을 지정하는 어노테이션이다.
위 코드에서는 메소드와 클래스에 붙을 수 있도록 지정하였다.
그리고 @Retention어노테이션은 임의로 선언된 어노테이션인 @Timer어노테이션의 생명주기(Life Cycle)을 지정하는 어노테이션이다.
위 코드에서는 런타임으로 생명주기를 지정하였고, 실행될 동안에는 계속 유효한 어노테이션으로 사실상 안죽는 어노테이션이라는 말이다.

두 번째 차이는 로깅 기능을 구현할 때에는 @Before어노테이션과 @AfterReturning어노테이션을 활용하여 실행시점과 동작을 정의하였는데,
타이머 기능을 구현할 때에는 @Around어노테이션을 활용하여 비즈니스로직의 전후를 하나의 메소드에서 정의할 수 있도록 하였다.
이를 활용한 이유는 타이머 기능같은 경우는 시간데이터를 비즈니스로직이 실행되기 전후에 공유되어야 하는데, before/after로 메소드가 나뉘어 실행될 경우 시간데이터가 공유될 수 없기 때문이다.
@Around어노테이션도 마찬가지로 타겟 메소드를 지정하여 특정 로직이 실행될 때마다 실행될 수 있도록 설정할 수 있다.
그리고 before/after 어노테이션을 활용할 때와 다른점은 비즈니스 로직을 감싸는 형태로 메소드가 실행된다는 점이다.
TimerAop.javaaround()메소드를 보면, joinPoint.proceed()로 비즈니스 로직이 실행되는 부분이 있고,
전후로 stopWatch.start()stopWatch.stop()이 실행시켜서 전후에 어떤 메소드가 실행될지 프로그래밍 하였다.
그리고 stopWatch객체를 활용하여 비즈니스 로직의 시작시간과 끝나는시간을 기록하였고, stopWatch.getTotalTimeSeconds()메소드를 통해 기록된 시간의 차이를 알 수 있다.

마무리

: 위 두 사례에서 본 것과 같이 AOP는 비즈니스 관점과 부가적인 관점을 나누어 비즈니스 로직과 부가적인 로직을 분리시켜주는 프로그래밍 방식이다.
@Aspect가 명시된 클래스에서 부가 기능들이 비즈니스 로직의 어떤 시점에 실행되고 어떤 방식으로 실행되는지, 어떤 타겟에서 실행되는지 설정할 수 있고, 이를통해 부가 기능을 철처하게 모듈화시킬 수 있다.

이어서

기존 계획은 AOP를 알아본 이후에 PSA도 함께 알아보려 했으나, DB와 같이 보는 것이 좋을 것 같아서 후순위로 조금 미루려한다.
대신 이어서 SOAP를 알아보려 한다. 요즘은 REST연동 방식이 대세라곤 하지만, 레거시한 시스템에서는 아직 많이 활용되는 방식이라 알아두면 좋을 것 같고, 실제로 나는 로그인 연동기능을 구현할 때, SOAP때문에 많이 애먹었어서 해당 부분을 까먹기전에 다뤄보려한다.

다음은 SOAP을 알아보자!

반응형
728x90
반응형

spring

Web Application 개발에 Spring framework가 주로 활용되는 이유가 있다.
그 이유는 Spring의 특징으로 설명이 될 것이다.

1. Spring의 역사

특징을 살펴보기 전에 Spring의 역사를 되짚어보고자 한다. 역사를 알면 Spring이 아래와 같은 특징을 갖게된 배경에 대해 쉽게 납득할 수 있을 것이다.
Spring Framwork 탄생 이전에 기업들은 Java의 표준 기술로 EJB를 사용하였다. 하지만 이러한 EJB에는 많은 단점들이 있었고, 이러한 단점들을 보완하기 위해 Spring Framework가 등장하였다.

A. EJB(Enterprise Java Beans)란?

EJB는 대규모 기업환경의 시스템을 구현하기 위한 서버측 컴포넌트 모델이다.
다양한 Platform에서의 제품 독립성을 위해 비즈니스 로직과 시스템 로직을 분산하는 규약을 규정하고 있다.

기업의 IT시스템 규모가 커지면서 많은 트래픽을 빠르고 안정적으로 처리하기 위해 다양한 기술들(트랜잭션, 멀티스레딩, 리소스폴링, 보안 등)이 시스템에 적용되기 시작했다. 이러한 많은 기술들을 적용하여 개발해야했기 때문에 개발 난이도가 높아지기 시작했고, 이를 보완하기 위해 EJB가 탄생하였다.

  • Bean : 컨테이너 내에서 미리 생성되어 대기하고 있는 객체

B. EJB의 특징

EJB구조

EJB는 서버 컴포넌트인 하나의 Enterprise Bean으로 나타낼 수 있고, 이러한 Bean은 크게 세 가지로 나뉜다.

  1. 세션 빈(Session Bean) : DB연동이 필요없는 영속적이지 않고 비즈니스 로직을 표현하는 Bean. 해당 Bean은 상태유지여부에 따라 다시 Stateful, Stateless로 나뉠 수 있는데, 식별 가능한 고유성 여부에 따라 차이가 있다.
  2. 엔티티 빈(Entity Bean) : 데이터베이스의 데이터를 관리하는 Bean.
  3. Message-Driven Bean : queue나 listener를 통해 비동기 메세지 형태로 들어온 요청을 받아서 처리하는 Bean

C. EJB의 장단점

위 사진처럼 EJB서버에 EJB Container가 있고, EJB Container가 bean을 type별로 나누어 관리함으로서 아래와 같은 이점을 가질 수 있다.

  1. 객체를 미리 생성하여 메모리에 저장함으로서 많은 트래픽에 대한 안정성 지원
  2. 컨테이너가 자동으로 트랜잭션 처리를 진행함으로서 안정적인 데이터 조작 가능
  3. Bean 사용여부에 따라 자동적으로 활성화 및 비활성화 시킴으로서 효율적인 메모리 사용 가능
  4. 기존 EJB 컴포넌트들이 loading되어 컴포넌트의 라이프사이클을 관리하고 보안, 스레딩 등의 서비스를 제공함으로서 개발자는 비즈니스로직 개발에 더욱 집중 가능

하지만 아래와 같은 단점도 있었다.

  1. 객체지향적이지 않음 => 복잡한 프로그래밍 모델
  2. 특정 환경과 기술에 종속적 => 성능 및 이동성(portablity) 저하
  3. 컨테이너 안에서만 동작가능한 구조 => 반복되는 수정-빌드-배포-테스트 과정 => 개발생산성 저하

정리하면,
EJB가 대량 트래픽에 안정적이고, 데이터 처리 또한 안정적으로 할 수 있고, 비즈니스 로직에 집중 가능하다는 장점이 있다.
하지만 복잡한 프로그래밍 모델에 특정 환경과 기술에 종속되어 있어서 성능과 이동성이 저하된다는 치명적인 단점이 있었고,
컨테이너 안에서만 동작이 되기 때문에 개발생산성이 저하된다는 단점 또한 있었다.

D. Spring Framework의 대두

EJB는 안정적이라는 장점이 있지만, 복잡성이 크고 취약한 성능 및 이동성이라는 단점이 있다.

이에 따라 객체지향 원리에 따라 만들어진 Java 언어의 기본 기술에 충실하여 비즈니스 로직을 구현하는
POJO(Plain Old Java Object) 방식으로 돌아가자는 의견들이 나오기 시작했고,

이러한 의견들은 Spring Framework의 기원이 되었다.

2. Spring의 특징

앞서 언급한 것처럼 Spring은 Java언어 기반의 Framework이다. EJB의 단점을 보완하기 위해 대두되었고, Java언어의 POJO방식에 충실하는 Framework이다. POJO를 기반으로 "테스트의 용이성", "느슨한 결합"에 중점을 두고 개발되었다.

A. POJO(Plain Old Java Object)

: 순수한 Java Object를 뜻하는 말

POJO의 특징은 아래와 같다.

  1. 특정 규약에 종속되지 않는다.
    : 외부에 의존성을 두지 않고, 순수한 Java로 구성이 가능해야 함.
  2. 특정 환경에 종속되지 않는다.
    : 특정 비즈니스 로직을 처리하는 부분에 외부 종속적인 http request, session 등이 활용되는 경우, POJO를 위배한 것으로 볼 수 있다. @Annotation기반으로 설정하는 부분도 엄연히 POJO라고는 볼 수 없다.
    => Spring에서는 어느정도 타협된 부분인 것 같다.

위와 같은 외부종속성을 최대한 배제하는 POJO의 특징을 고려한다면, 복잡한 시스템과 취약한 이동성이라는 단점을 가진 EJB를 보완할 수 있다.

Spring삼각형

위 사진과 같이 POJO특성을 기반한 Spring의 세 가지 기능이 있다.
이제 세 가지 기능을 하나씩 살펴볼 것이다.

B. IoC/DI

  • IoC(Inversion Of Control) : 제어의 역전, Java 객체를 new로 생성하여 개발자가 관리하는 것이 아닌 Spring Container가 생성하여 관리까지 할 수 있도록 객체관리에 대한 모든 권한을 넘기는 것. Spring Framework의 독자적인 특성
  • DI(Dependency Injection) : 의존성 주입, Java 외부객체 활용이 필요할 때 객체를 주입받아 활용하는 것 => 외부와 의존성이 줄어들어 코드 테스트에 용이하고, 코드를 확장하거나 변경할 때 영향을 최소화할 수 있음.
  • DI의 사례

IEncoder.java

public interface IEncoder {
    String encode(String message);
}

Base64Encoder.java

import java.util.Base64;

public class Base64Encoder implements IEncoder{

    public String encode(String message){
        return Base64.getEncoder().encodeToString(message.getBytes());
    }
}

UrlEncoder.java

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public class UrlEncoder implements IEncoder{

    public String encode(String message){
        try {
            return URLEncoder.encode(message, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }
}

Encoder.java

public class Encoder {

    private IEncoder iEncoder;

    public Encoder(IEncoder iEncoder){
        this.iEncoder = iEncoder;
    }

    public String encode(String message){
        return iEncoder.encode(message);
    }
}

위 예시는 IEncoder라는 인터페이스를 상속받은 Base64Encoder, UrlEncoder 객체를 주입받아 사용하는 Encoder의 사례를 코드로 표현한 예시이다.

경우에 따라서 여러 인코더를 사용할 수가 있는데, 필요할 때마다 그에 맞는 인코더 객체를 new로 생성하여 활용한다면 코드 복잡성이 증가한다.
=> 이를 보완하기 위해 IEncoder라는 인터페이스를 만들고, 해당 인터페이스를 상속받아 각 유형의 Encoder(Base64Encoder, UrlEncoder)를 위 코드와 같이 추상화 시킨다면 정해진 규격의 타입으로 통일시킬 수 있어서 복잡성을 줄일 수가 있다. 또한, DI개념을 도입하여 Encoder라는 객체주입용도의 base class를 추가하고 다양한 유형의 Encoder를 하나의 base class 객체에 주입해서 사용한다면, 코드의 재사용성이 증가하여 테스트를 용이하게 할 수 있고 Encoder라는 base class를 건드리지 않아도되기 때문에 기능 확장성 또한 좋아진다.

  • IoC의 사례

IocApplication.java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@SpringBootApplication
public class IocApplication {

    public static void main(String[] args) {
        SpringApplication.run(IocApplication.class, args);
        ApplicationContext context = ApplicationContextProvider.getContext();

        //Base64Encoder base64Encoder = context.getBean(Base64Encoder.class);
        //UrlEncoder urlEncoder = context.getBean(UrlEncoder.class);

        Encoder encoder = context.getBean("urlEncode", Encoder.class);
        String url = "www.naver.com/books/it?page=10&size=20&name=spring-boot";
        String result = encoder.encode(url);
        System.out.println(result);
    }

}

@Configuration
class AppConfig{

    @Bean("base64Encode")
    public Encoder encoder(Base64Encoder base64Encoder){
        return new Encoder(base64Encoder);
    }

    @Bean("urlEncode")
    public Encoder encoder(UrlEncoder urlEncoder){
        return new Encoder(urlEncoder);
    }
}

Base64Encoder.java

import org.springframework.stereotype.Component;

import java.util.Base64;

@Component("base74Encoder")
public class Base64Encoder implements IEncoder {

    public String encode(String message){
        return Base64.getEncoder().encodeToString(message.getBytes());
    }
}

UrlEncoder.java

import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

@Component
public class UrlEncoder implements IEncoder {

    public String encode(String message){
        try {
            return URLEncoder.encode(message, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }
}

ApplicationContextProvider.java

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class ApplicationContextProvider implements ApplicationContextAware {

    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static ApplicationContext getContext(){
        return context;
    }
}

DI 사례의 코드에서 객체는 여전히 Spring Container가 아닌 개발자에 의해 new로 생성되고 관리가 되고있는 코드이다.
IoC(제어의 역전)개념을 적용하여 객체 관리의 주체를 Spring Container에 넘기기 위해서는 객체가 Spring Container에 생성되고, Container에 의해 객체가 주입되도록 별도의 설정이 필요하다. 이러한 설정은 @Annotation형태의 어노테이션으로 이루어진다.

  • 어노테이션이란? 사전적 의미로는 주석이라는 뜻을 가지고 있고, Java에서의 어노테이션은 코드상에 추가하여 application이 코드를 어떻게 처리해야하는 지를 알려주기 위한 추가 데이터이다.

위 IoC 코드와 DI 코드의 차이를 잘 살펴보면, Encoder 각 클래스에 @Component라는 어노테이션이 추가 기입되어 있고 Spring Container로부터 객체를 받아오기 위해 ApplicationContextProvider.java 코드를 추가하였다. 또한, 메인함수에서 Spring Container 주체적으로 객체주입을 통해 객체를 생성할 수 있도록 Bean을 생성하는 코드를 추가하였다.

  • Bean이란? 위 EJB에서 언급한 것처럼 Container상에서 생성하고 관리하는 Java 객체이다.

@Component라는 어노테이션을 붙임으로서 해당 클래스의 객체가 Spring Container에서 생성되고 관리될 수 있도록 설정되었다. 그리고 Spring Container상에서 생성된 객체를 가져오기 위해 ApplicationContextAware클래스를 상속받은 ApplicationContextProvider클래스를 생성하였고, 해당 클래스의 getContext().getBean()메소드를 활용한다면 생성된 Bean을 가져올 수 있다. 마지막으로 메인클래스에 @SpringBootApplication어노테이션을 추가하여 Spring Boot Framework로 프로젝트가 관리될 수 있도록 하였고, Bean설정을 추가하여 Spring Container가 객체주입을 통해 Bean을 생성할 수 있도록 하였다.

이를 통해 객체의 생성과 관리의 역할은 개발자가 아닌 Spring Container가 맡게 되었다. 이것이 IoC(제어의 역전)이다.

이어서

Spring Framework 삼각형에서 나타나는 대표적인 특징인 AOP와 PSA에 대해 알아볼 것이다.

반응형
728x90
반응형

spring

1. Spring 이란?


Spring은 프로그래밍 언어 Java 기반의 프레임워크이다. 처음 접하는 사람에게는 부족한 설명이다. 그렇다면 프레임워크란 무엇인가?

프레임워크(Framework)는 간단히 말하면, Java 기반으로 애플리케이션을 쉽게 개발할 수 있도록 도와주는 환경(?)이라고 보면 될 것 같다. Spring에서 제공하는 몇 가지 기능을 활용한다면, 개발을 원활하게 진행할 수 있고 보다 효율적인 애플리케이션을 개발하는 데 도움이 된다.

2. Spring Boot


Spring Boot는 초심자가 Spring에 쉽게 접근할 수 있도록 도와주는 Spring의 서브 프로젝트이다.
Spring Boot 환경에서 개발을 한다면 빌드/배포 등과 같이 부수적인 요소에 신경쓰지 않고 비즈니스 로직을 구현하는 데만 집중하여 개발할 수 있다.
아래 링크에서 누구나 쉽게 Spring Boot 프로젝트를 생성할 수 있다.
https://start.spring.io/

하지만... 초심자였던 나는 프로젝트 생성마저도 쉽지 않았다. 차근차근 하나씩 살펴보자.

A. Spring Boot 프로젝트 생성


<사진 1. start.spring.io 초기 화면>

  1. Project : Gradle - Groovy, Gradle - Kotlin, Maven 세 개중 어떤 빌드 툴을 사용할지 정하면 된다.
    빌드란? java 소스코드를 컴퓨터가 실행시킬 수 있는 파일 형태로 변환하는 과정이고, 이를 도와주는 툴이 빌드툴이다.
  2. Language : 말그대로 본인이 활용할 언어를 선택하면 된다.
  3. Spring Boot : Spring Boot의 버전을 활용하면 된다. (SNAPSHOT)이 붙은 버전은 현재 개발이 진행중이라는 의미인 것 같다.
  4. Project Metadata : 프로젝트 이름, 패키징방식, Java 버전을 정하면 된다.
    패키징이란? 빌드 과정중 하나인데, 컴퓨터가 읽을 수 있는 두 가지 파일 형식(Jar, War) 중 하나를 선택하면 된다.
  5. Dependencies : 생성한 프로젝트에서 활용할 라이브러리를 입력하면 된다.

    위 과정을 잘 따라가서 GENERATE 버튼을 누르게 되면 하나의 Spring Boot 프로젝트가 생성되고, 본인이 사용하고 싶은 IDE(Eclipse나 InteliJ)로 불러와 개발을 시작하면 된다.

B. Spring Boot 구성


(출처 : https://wikidocs.net/160947)


위 캡처본은 따로 프로젝트를 생성하진 않아서... 직접 캡처한 파일이 아닌 다른 블로그 글에서 퍼왔다.


처음 프로젝트를 생성하게 되면, 위 사진의 구성과 같이 프로젝트가 생성될 것이다. 하나씩 핵심만 살펴보자.

  1. src/main/java : 직접 작성한 코드가 있는 Java 파일들을 생성할 곳이다. 본인이 구현할 비즈니스 로직을 해당 부분에 Java 코드로 작성하면 된다.
    그리고 프로젝트 실행 시, (프로젝트명)Application.java 파일을 기점으로 프로젝트가 실행된다. (해당 파일 안에 main함수가 있음)
  2. src/main/resource : 프로젝트에 활용되는 파일 중, Java 코드를 제외한 모든 파일들이 저장되는 곳이다. (ex. HTML, CSS, JS, XML 등)
    그 중, application.yml이나 application.properties와 같은 파일은 프로젝트에 활용되는 환경변수 값들이 입력되는 파일로 활용된다.
  3. src/test/java : 프로젝트와 별도로 테스트 용도의 java 코드들이 저장되는 곳이다.
  4. build.gradle (pom.xml) : gradle 빌드툴 활용 시, build.gradle 파일이 생성된다. (maven 빌드툴 활용 시, pom.xml 파일이 생성된다.)
    해당 파일에서 프로젝트에 활용된 외부 라이브러리들을 정의한다. 그리고 빌드 툴은 해당 파일을 읽어서 외부로부터 해당하는 라이브러리들을 가져온다.

3. 이어서

위 과정을 모두 거치게 되면, Spring Boot를 활용하여 개발할 준비가 끝났다고 볼 수 있다.
이제는 Spring을 활용하여 효율적으로 개발하기 위해 알아야하는 몇 가지 개념들(Spring의 원리, IOC/DI/AOP, POJO 등)을 짚어야할 때다.
다음 글에서 다뤄볼 것이다. To Be Continued...

반응형
728x90
반응형

spring

1. Spring 개발에 본격 입문하게된 Woong

22년 12월 어느 날, 팀에서 추진하는 SI 프로젝트에 참여하게 되었다.
주제는 비대면 고객케어 솔루션..!
단말 고장 관련 민원이 들어올 때마다 현장으로의 수리기사 출동을 줄이기 위한 솔루션이라고 한다.
수리기사의 출동이 곧 kt의 지출이니, 지출을 줄이기 위한 일환으로 필요한 솔루션이다.

이를 위해 고객민원을 1선에서 대응하는 매니저분들이 활용할 포털사이트가 필요하다.
그리고 내가 처음 담당한 업무는 해당 포털사이트의 '로그인 연동 개발'이다.

여느 포털사이트에서처럼 인증, OTP, 토큰발행 등과 같은 기능을 개발하기 위해
사내 인증시스템인 LDAP이라는 시스템과 연동되어야 하고, OTP기능이 구현되어 있는 모듈과도 연동되어야 한다.
말이 로그인이지... 사실상 연동개발이다.

그리고 개발에 활용되는 언어는 Java이고, 프레임워크는 Spring Boot이다.
Java활용은 익숙하지만, Spring 프레임워크는 생소했다.
오히려 좋아...! 쉽진 않겠지만, 개발과 공부를 병행하기로 했다.
공부만 하는 것보다 기억에 오래남을 것이고, 실전 활용능력도 기를 수 있어 좋은 기회라고 생각한다.
그리고 후에 리마인드를 위해 블로그 글로 남기려고 한다. 꾸준히 남기자 대웅아..!

2. 앞으로 학습이 필요한 부분

A. Spring 프레임워크의 컨셉과 원리

Spring을 활용한 개발을 진행하기에 앞서, 어떻게 돌아가고 어떤 컨셉을 가지고 개발이 진행되는지를 사전에 파악해야 빠르고 효율적으로 개발할 수 있다.

Spring 프레임워크가 정의와 원리가 뭔지?, POJO의 개념, IOC/DI/AOP 등을 알아볼 것이다.
다양한 패턴(싱글톤, 프록시, 파사드 등)에 대한 학습도 필요하지만, 시간관계상 여유가 생길 때 알아볼 것이다.

B. REST API

구현이 필요한 포털은 VueJS 프레임워크로 구현되고, Axios로 요청을 받을 것이기 때문에 로그인인증 모듈을 REST API로 구현하고자 한다.
이를 위해 REST API의 정의부터 Spring 프레임워크에서는 REST API가 어떻게 구현되는지, 어떤 어노테이션이 활용되는지 등을 알아볼 것이다.

C. Jasypt

Jasypt는 암복호화 모듈이다. application.yml 파일에 입력해놓은 환경변수들을 복호화하여 가져올 때 활용된다.
Spring 프레임워크에서 환경변수를 어떤 원리로 가져오는지? 활용하는 오픈소스에서 복호화는 어떤식으로 이루어지는지 알아볼 것이다.

D. SOAP

다룰내용이 가장 많은 부분이 될 것이다. 실제로 제일 어려웠다 ㅜ OTP인증을 위해 타모듈과의 연동이 필요한데,
연동이 필요한 모듈은 레거시 모듈이기때문에 SOAP로 연동이 이루어진다.
SOAP가 뭔지? WSDL, SOAP연동을 위해 필요한 개발방법 등을 알아볼 것이다.


애기화이팅

반응형

+ Recent posts