본문 바로가기
SpringBoot/예제

[ Spring Boot ] 실습 예제 01

by Hwanii_ 2023. 9. 13.
728x90

1. 

웹 애플리케이션을 사용 하지 않고, 간단하게 console 예제 라는 것을 참고 하자.

 

2.

따라서,

TEST01Application.java 파일의,

@SpringBootApplication 어노테이션과

SpringApplication.run(Test01Application.class, args) 은 주석 처리 하여 예제를 진행 한다.

 

3.

프로젝트를 잘 생성 하면, 기본 구조는 아래와 같다.

 

 

4.

강제성을 부여할 인터페이스를 생성하고 미완성 메서드를 작성 하기.

 

Phone.java

 

package test;

public interface Phone {
	
	void call(String name);
	//	인터페이스에 달리는 기본 키워드는 아래와 같다.
	//	하지만 당연하게 달려있어야 하기 때문에 생략이 가능 하다.
	//	public : 인터페이스를 구현할 클래스들보다 무조건적으로 접근제어자의 범위가 넓어야 해서 public 이다.
	//	abstract : 메서드 바디를 가질 수 없는 미완성 메서드가 된다. (== 추상 메서드)

}	//	Phone interface

 

Phone 인터페이스와, call 추상 메서드를 작성 했다.

 

5.

Phone 인터페이스를 구현한 PhoneA 클래스와 PhoneB 클래스를 생성 하기.

 

PhoneA.java

 

package test;

public class PhoneA implements Phone {

	@Override
	public void call(String name) {	//	오버라이딩
		
		System.out.println("PhoneA : " + name + "이 (가) 전화 거는중..");
		
	}
	
}	//	PhoneA

 

PhoneB.java

 

package test;

public class PhoneB implements Phone {

	@Override
	public void call(String name) {	//	오버라이딩
		
		System.out.println("PhoneB : " + name + "이 (가) 전화 거는중..");
		
	}
	
}	//	PhoneB

 

Phone 인터페이스를 구현한 각각의 클래스들은 추상메서드를 반드시 오버라이딩 해야 한다.

 

6.

스마트폰을 사용 하는 것을 표현하기 위한 설계도를 작성 한다.

 

설계도 == 클래스 

 

Member 클래스 작성 하기.

 

DI를 setter 방식과 생성자 방식으로 둘다 실습 하기 위해서,

Member 클래스에,

생성자, setter & getter, toString() 오버라이딩, .. 등등을 작성 한다.

 

Member. java

 

package test;

public class Member {
	
	private String name;
	private Phone phone;
	
	public Member() {
		
		System.out.println("Member 기본 생성자 호출.");
	}
	
	//	생성자 오버로딩
	public Member(String name, Phone phone) {	
		
		this.name = name;
		this.phone = phone;
		
		System.out.println("Member 생성자 호출.");
		
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Phone getPhone() {
		return phone;
	}

	public void setPhone(Phone phone) {
		this.phone = phone;
	}

	@Override
	public String toString() {
		return "Member [name=" + name + ", phone=" + phone + "]";
	}
	
	public void print() {
		this.phone.call(name);	//	this 키워드는 생략 가능 하다.
	}

}	//	Member

 

7.

스프링부트는 외부의 설정파일이 아닌,

.xml 파일 설정 대신에 @ 어노테이션 위주로 설정 하는게 특징 이라고 했었다.

 

따라서 자바에서 Configuration 클래스를 생성 한다.

 

package test;

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

//	설정 클래스
//	Configuration : 프로그램의 설정을 저장해두고 환경을 구성하는 데에 사용 하는 파일.

@Configuration	//	설정과 관련된 파일이라는것을 명시하는 어노테이션.
public class Config {
	
	@Bean	//	스프링이 IoC 컨테이너로 관리하는 객체라는것을 명시하는 어노테이션.
	public PhoneA phoneA() {
		return new PhoneA();
	}
	
	@Bean
	public PhoneB phoneB() {
		return new PhoneB();
	}
	
	@Bean
	public Member Member1() {	//	생성자 주입
			return new Member("Hwanii", new PhoneA());
	}
	
	@Bean(name = "apple")
	public Member Member2() {	//	setter 주입
		Member Member = new Member();
		Member.setName("Yoonjeong");
		Member.setPhone(new PhoneA());
		return Member;
	}
    //	같은 타입의 객체를 생성 할 때는, 이름 설정을 해주자. (별도로 하지 않으면 메서드명 (Member2) 이 등록 된다)

}	//	Config

 

위의 Configuration 클래스는 줄여서 Config 라고 작성 했고,

프로그램의 설정을 저장해두고 환경을 구성하는 데 사용 한다.

 

@Configuration 어노테이션으로 설정과 관련된 파일이라는것을 명시 한다.

 

@Bean 어노테이션을 사용 해서, 스프링 컨테이너가 IoC로 관리하는 객체라는것을 명시 한다.

 

@Bean 어노테이션을 사용 할 때, 별도로 name 설정을 해주지 않으면,

메서드명이 객체의 이름으로 자동 설정 된다.

 

즉,

@Bean 어노테이션을 통해 PhoneA와 PhoneB 객체는 스프링 컨테이너가 관리하는 객체가 되며,

PhoneA 를 사용하는 주체인 Member 에게,

생성자 주입과 setter 주입 방식으로 의존 주입을 하도록 작성 했다.

 

8.

스프링 컨테이너를 구동시키기 위해서,

TEST01Application.java 클래스 에서 실행할 코드를 작성 하기.

 

package com.hwan.app;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import test.Config;
import test.Member;

//@SpringBootApplication	//	웹 어플리케이션을 사용 할 때 명시하는 어노테이션 이다.
public class Test01Application {

	public static void main(String[] args) {
//		SpringApplication.run(Test01Application.class, args);
		
		//	1. 스프링 IoC 컨테이너 구동 하기.
		//	1-2. 컨테이너를 구동시킬때에 설정 파일이 필요 하다.
		//	(스프링에서는 .xml / 부트에서는 .java)
		
		ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
		
		//	컨테이너가 팩토리 패턴을 기반으로 동작 하고 있다.
		
		Member Member1 = (Member) ac.getBean("Member1");	//	다운 캐스팅 (형변환)
		Member1.print();
		
		Member Member2 = ac.getBean("apple", Member.class);
		Member2.print();
		
		//	2. 싱글톤 유지되는지 확인 하기 !
		
		if(Member1 == Member2) {
			System.out.println("둘은 동일한 객체 입니다.");
		}
		else {
			System.out.println("둘은 다른 객체 입니다.");
		}
		
		//	부트 방식을 전부 활용 하지 않음.
		//	개발자가 직접 new를 작성한 상황.
		//	개발자가 Member 객체를 2개 등록 -> (둘은 같은 타입의 객체이므로, 싱글톤 유지가 되지 않는다)
		
	}	//	main()

}	//	Test01Application

 

[ console ]

 

Member 생성자 호출.
Member 기본 생성자 호출.
PhoneA : Hwanii이 (가) 전화 거는중..
PhoneA : Yoonjeong이 (가) 전화 거는중..
둘은 다른 객체 입니다.

 

반응형