[LG CNS AM Inspire CAMP 1기] Spring (1) - 개발 환경 셋팅 및 기본 개념

니니지·2025년 1월 20일

LG CNS AM Inspire Camp 1기

목록 보기
25/47
post-thumbnail

INTRO

안녕하세요, 오늘은 스프링 학습 첫 날 입니다. 개발 환경 셋팅 및 기본 개념을 이해하기 위한 예제 소스를 작성했습니다.

1. 개발 환경 설정

스프링 프로젝트 생성을 위해 이클립스에서 툴 다운로드 및 pom.xml 설정, mySQL 셋팅을 진행합니다.

- 이클립스

Help -> Marketplace -> spring tools 4 다운로드 -> 완료 시 New Project 에서 Spring Boot 항목이 나타남.

- MySQL & Workbench 설치

https://myanjini.tistory.com/entry/MySQL-8034-MySQL-Workbench-80-%EC%84%A4%EC%B9%98
(패스워드는 p@ssw0rd로 통일)

- spring project 설정

명령 프롬프트에서 작업 디렉터리와 pom.xml 파일을 생성

C:\Users\myanj> mkdir c:\spring & cd c:\spring
c:\spring> notepad pom.xml

메모장에 아래 내용을 입력한 후 저장(Ctrl+S)

<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>spring5</groupId>
    <artifactId>ex01</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>  
            <artifactId>spring-context</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>1.17</source>
                    <target>1.17</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

File > Import... > Maven > Existing Maven Projects > Browser > C:\spring 폴더를 선택 > pom.xml 선택을 확인하고, Finish 버튼을 클릭

2. 예제 코드 실행

Greeter.java : 콘솔에 메시지를 출력하는 자바 클래스
AppContext.java : 스프링 설정 파일
Main.java : 스프링과 Greeter를 실행하는 자바 클래스
소스 디렉터리(폴더)를 생성 >>> New > Folder >>> src/main/java >>> ex01 패키지

[Greeter.java]

package ex01;

public class Greeter {
	private String format;
	
	public String greet(String name) {
		return String.format(format, name);
	}

	public void setFormat(String format) {
		this.format = format;
	}
}

[Main.java]

package ex01;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
	 public static void main(String[] args) {
		 {
			 Greeter greeter = new Greeter();
			 greeter.setFormat("Hello, %s !!!");
			 String message = greeter.greet("Spring");
			 System.out.println(message);
			 
		 }
		 {
			 
			 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppContext.class);
		 
			 Greeter greeter = ctx.getBean("greeter", Greeter.class);
			 greeter.setFormat("안녕, %s !!!");
			 String message = greeter.greet("Spring");
			 System.out.println(message);
		 }
	}
}

[AppContext.java]

package ex01;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppContext {
    @Bean
    public Greeter greeter() {
        Greeter g = new Greeter();
        g.setFormat("%s, 안녕하세요.");
        return g;
    }
}

3. Spring Container

- 빈(bean) 객체

싱글톤(signleton) 범위를 가짐

  • 싱글톤 : 인스턴스가 하나만 생성되는 것을 보장하는 객체
  • 스프링은 기본적으로 한개의 @Bean 어노테이션에 대해 한 개의 빈 객체를 생성
class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null)
            instance = new Signleton();

        return instance;
    }
}

- 의존(dependency)

한 클래스가 다른 클래스의 메서드를 사용(실행)할 때 의존한다라고 표현 ⇒ 변경에 의해 영향을 받는 관계

의존 대상 객체를 직접 생성

⇒ 구현은 용이하나, 유지보수에 문제가 있음

public class MemberRegisterService {
	private MemberDAO dao = new MemberDAO();
		:

DI(Dependency Injection, 의존 주입)

의존하는 객체를 직접 생성하는 대신, 의존 객체를 전달받는 방식
⇒ 의존 객체를 주입해 주는 곳만 수정하면 변경을 반영할 수 있음

[예제 - 어셈블러 활용]

회원 데이터를 관리하는 클래스

Member : 회원 정보(데이터)를 표현하는 객체
WrongIdPasswordException : RuntimeException 상속 받아 익셉션 처리
MemberDAO : DO 정보를 넘겨 DB에 접근하도록 함 (insert, select, update 등)

회원 가입을 처리하는 클래스

DuplicateMemberException : RuntimeException 상속 받아 익셉션 처리
RegisterRequest : 사용자가 입력한 회원 가입에 필요한 정보를 담고 있는 객체
MemberRegisterService : 회원 등록 서비스. DAO 메서드를 호출해서 제공할 서비스를 구현하는 로직.

패스워드 변경을 처리하는 클래스

MemberNotFoundException
ChangePasswordService : 이메일 정보를 받아 비밀번호를 변경하도록 DAO를 호출하는 서비스.

객체를 생성하고 의존 객체를 주입하는 기능을 제공하는 클래스를 정의

assembler.Assembler.java : SVC에 접근하게 함
MainForAssembler.java : main 메서드

[예제 - 스프링 활용]

설정 클래스

AppCtx : @Configuratuion. 스프링 관리 객체(빈) 관리

빈의 개수가 증가하면 영역별로 설정 파일을 나누어서 관리하는 것이 편리⇒ AppCtx를 AppConf1, AppConf2(@Autowired 활용)로 분리.
의존 주입 대상에서 @Autowired 어노테이션을 사용하면 스프링 설정 클래스의 @Bean 메서드에서 의존 주입을 위한 코드를 작성하지 않아도 됨.

// MemberInfoPrinter.java
public class MemberInfoPrinter {
    @Autowired
    private MemberDAO memberDAO;
    @Autowired
    private MemberPrinter printer;
...(생략)...
// AppConf2.java
@Configuration
public class AppConf2 {
        ...(생략)...	
    @Bean
    public MemberInfoPrinter memberInfoPrinter() {
        MemberInfoPrinter infoPrinter = new MemberInfoPrinter();
//        infoPrinter.setMemberDAO(memberDAO);
//        infoPrinter.setMemberPrinter(memberPrinter);
        return infoPrinter;
    }

스프링 컨테이너

MainForSpring : Main 메서드 ⇒ 여러 설정 클래스를 사용하도록 할 수 있다.

private static ApplicationContext ctx = null; 
// ctx = new AnnotationConfigApplicationContext(AppCtx.class);
 ctx = new AnnotationConfigApplicationContext(AppConf1.class, AppConf2.class);

MemberRegisterService regSvc = ctx.getBean("memberRegSvc", MemberRegisterService.class);

기능 추가

MemberPrinter, MemberListPrinter : 회원 목록 출력 기능을 추가 (생성자 활용)
MemberInfoPrinter : 이메일 정보와 일치하는 회원 정보를 출력 (Setter 메서드 활용)
VersionPrinter : 버전 정보를 출력

(추가) 자바 - 클래스 상속 이해

- 코드

package sample;

class Parent {
    public void method1() {
        System.out.println("Parent.method1()");
    }
    public void method2() {
        System.out.println("Parent.method2()");
    }
}

class Child1 extends Parent {
    @Override
    public void method1() {
        System.out.println("Child1.method1()");
    }
}

class Child2 extends Parent {
    @Override
    public void method2() {
        System.out.println("Child2.method2()");
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println("\nParent p = new Parent()");
        Parent p = new Parent();
        p.method1();
        p.method2();
        
        System.out.println("\nChild1 c1 = new Child1()");
        Child1 c1 = new Child1();
        c1.method1();
        c1.method2();

        System.out.println("\nChild2 c2 = new Child2()");
        Child2 c2 = new Child2();
        c2.method1();
        c2.method2();
        
        System.out.println("\nParent p1 = new Child1()");
        Parent p1 = new Child1();
        p1.method1();
        p1.method2();        

        System.out.println("\nParent p2 = new Child2()");
        Parent p2 = new Child2();
        p2.method1();
        p2.method2();
    }
}

- 출력 결과

Parent p = new Parent()
Parent.method1()
Parent.method2()
Child1 c1 = new Child1()
Child1.method1()
Parent.method2()
Child2 c2 = new Child2()
Parent.method1()
Child2.method2()
Parent p1 = new Child1()
Child1.method1()
Parent.method2()
Parent p2 = new Child2()
Parent.method1()
Child2.method2()

OUTRO

오늘은 수업 시간 중에 상담이 있었는데, 현강에 나와서 소통하는 시간을 가지라고 하셨습니다. 네 라고 대답은 했지만 사실 현강에 가야만 하는 시기에만 갈 예정입니다. 교통비+식비+이동 시간을 절약해서 개인 일과 우선 순위대로 학습할 계획입니다.

profile
지니니

0개의 댓글