코드를 작성해야 하는 위치
src/main/java : java 파일을 작성하는 곳
src/main/resources > static : 정적 리소스를 작성하는 폴더
- 정적 리소스란 ?
- html, css, javascript, file 등
src
- 동적 리소스를 작성하는 곳
- 동적 리소스 : jsp
application.properties
- 기존 스프링에서는 .xml에서 설정을 했지만 스프링 부트에서는 .properties로 끝나는 확장자명이 설정함
build.grandle
- 기존 스프링에서 의존성 주입을 하던 곳은 pom.xml이지만 스프링 부트에서는 build.grandle에서 의존성 주입 및 버전을 자동으로 관리해준다
실습
> 먼저 서버 포트 번호를 8088로 변경한 후 저장한다
application.properties
server.port = 8088
> 스프링 부트에서는 Boot Dashboard를 통해 디버깅 하기 때문에 TEST01을 선택한 후 Start 버튼을 누른다
> 그렇게 실행하게 되면 404 에러가 발생하게 된다 (경로를 찾을 수 없기 때문)
오늘은 웹 애플리케이션을 활용하지 않고, console을 활용하기만 할 것이므로 웹을 먼저 Test01Application.java 파일의 @SpringBootApplication과 SpringApplication.run(Test01Application.class, args); 를 주석 처리한다
> console로 실습을 진행할 패키지를 만든 후 강제성을 부여할 인터페이스를 생성하고 강제성을 부여할 메소드를 선언한다
Phone.java
public interface Phone {
void call(String name);
}
> 강제성을 부여받을 클래스를 만들어 메소드를 작성한다
PhoneA.java
public class PhoneA implements Phone {
@Override
public void call(String name) { // 메소드를 강제한다 : 오버라이딩
System.out.println("PhoneA : " + name + "이(가) 전화 거는중 ...");
}
}
PhoneB.java
public class PhoneB implements Phone {
@Override
public void call(String name) {
System.out.println("PhoneB : " + name + "이(가) 전화 거는중 ...");
}
}
> 의존성을 부여하기 위해 Phone 을 사용할 Member 클래스를 생성하고 생성자와 getter & setter, 클래스가 호출 되었을 때 출력될 메세지가 담긴 메소드, 로그를 확인하기 위한 toString()을 작성한다
Member.java
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() {
phone.call(name);
}
}
> 프로그램의 설정을 저장해두고 환경을 구성하는 데 사용하는 파일인 Configuration 클래스를 생성한다
Config.java
@Configuration // 컨테이너야 이거 설정파일이다 !! 라고 어노테이션을 통해 알려줌
public class Config {
@Bean // Bean 어노테이션을 달게 되면 스프링이 IoC 컨테이너로 관리하는 객체가 됨
public PhoneA phoneA() {
return new PhoneA();
}
@Bean
public PhoneB phoneB() {
return new PhoneB();
}
// 멤버를 2가지 방식으로 만들 것임 (생성자 주입, setter 주입)
public Member member1() {
// 생성자 주입 방식
return new Member("큰 사람", new PhoneA());
}
@Bean(name="apple") // 이름 설정을 별도로 하지 않으면 member2 << 메소드명이 등록됨
public Member member2() {
// setter 주입 방식
Member member = new Member();
member.setName("작은 사람");
member.setPhone(new PhoneA());
return member;
}
}
@Bean 을 통해 PhoneA와 PhoneB 객체는 스프링이 관리하는 객체가 되고, 두가지 의존 주입 방법(생성자 주입, setter 주입) 으로
Phone을 사용하는 주체인 Member에게 의존 주입을 하도록 작성한다
또한, 이름 설정을 하기 위해 @Bean 뒤에 name을 apple로 선언하므로써 가독성을 높일 수 있다
> 서버를 실행 시키기 위해 Test01Application.java 클래스에서 실행할 코드를 작성한다
Test01Application.java
public class Test01Application {
public static void main(String[] args) {
// SpringApplication.run(Test01Application.class, args);
// 위의 어노테이션과 SpringApplicaiton은 웹 어플리케이션을 사용하는 것이기 때문에 지금 실습에선 사용하지 않으므로 주석 처리함
// 1. 스프링 IoC 컨테이너 구동시키기
// 1-2. 컨테이너를 구동시킬 때 설정 파일이 필요하다
// 스프링에서는 applicationContext.xml 사용했지만 부트은 방금 우리가 만든 클래스 파일을 넣어서 사용 (Config.class)
// (즉, 스프링에서는 .xml / 부트에서는 .java)
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
// 스프링 IoC 컨테이너는 팩토리 패턴을 기반으로 동작하고 있다
Member member1 = (Member)ac.getBean("member1"); // output이 Object 이므로 다운캐스팅 필요함
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개 등록 --> 개발자가 유도한대로 싱글톤 유지가 안됨 [ 싱글톤이 깨짐 ]
}
}
'Spring Boot' 카테고리의 다른 글
[Spring Boot] 데이터 유효성 검사 (2) | 2023.09.15 |
---|---|
[Spring Boot] 참조 변수 (1) | 2023.09.14 |
[Spring Boot] 스프링 부트 매번 해야하는 설정 및 정적 리소스 실습 (2) | 2023.09.14 |
[Spring Boot] Lombok (0) | 2023.09.14 |
[Spring Boot] 스프링 부트 개념 및 STS4(Mac) 설치 방법 (0) | 2023.09.13 |