[Java] Spring Boot / Singleton (싱글톤) / Prototype (프로토타입)

Onam Kwon·2022년 11월 1일
0

Java

목록 보기
6/7

Singleton (싱글톤타입)

  • singleton(싱글톤) 타입이란, 컨테이너에 빈 객체 등록을 한 뒤, 객체들을 컨테이너에서 꺼내 쓸 때, 똑같은 빈 여러개를 다른이름으로 가져올 때, 객체를 매번 새롭게 찍어내는게 아닌, 하나의 객체로 쓰는것을 말한다.
    • 컨테이너에서 빈을 꺼내 쓸 때 보통 싱글톤 타입으로 생성됨.

Prototype (프로토타입)

  • 반대로 매번 새롭게 찍어내는것은 prototype(프로토타입) 이라고 함.
    • new 연산자를 이용해 객체를 생성하면 보통 프로토 타입으로 생성됨.

🔽 User.java 🔽

package practice.beans;

import lombok.Data;
import org.springframework.stereotype.Component;

@Data
@Component
public class User {
    private String name;
    private Integer age;
}

🔽 Main.java 🔽

package practice.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import practice.beans.User;

import static org.springframework.web.bind.annotation.RequestMethod.GET;

@Controller
public class Main {
    @Autowired
    private User u1;
    @Autowired
    private User u2;
    @RequestMapping(value={"/single"}, method=GET)
    public String pracSingleton() {
        System.out.println("u1 name: " + u1.getName());
        System.out.println("u1 age: " + u1.getAge());
        u1.setName("First");
        u1.setAge(1);
        System.out.println("u1 name: " + u1.getName());
        System.out.println("u1 age: " + u1.getAge());
        System.out.println("u2 name: " + u2.getName());
        System.out.println("u2 age: " + u2.getAge());
        return "Single";
    }
}
  • 위 코드를 실행하면 아래와 같은 결과를 얻는다
2022-11-01 22:49:15.312  INFO 58459 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
u1 name: null
u1 age: null
u1 name: First
u1 age: 1
u2 name: First
u2 age: 1
  • 처음 u1을 출력하면 당연히 null로 결과가 나오며 u1의 이름과 나이를 설정해 준 후, u1 u2 둘다 출력하자 같은 값이 나왔다.
    -u2는 값을 설정하지도 않았지만 u1과 같은 값이 나왔으므로 싱글톤 타입임을 확인할 수 있다.
  • 빈으로 등록된 클래스는 기본적으로 싱글톤 타입.
  • 만약 프로토타입으로 변경하고 싶은 클래스가 있다면 @Scope 어노테이션을 사용하면 된다.
  • @Scope("prototype") 이런식으로 어노테이션 내부에 prototype을 속성값으로 줘야함.
    • prototype으로 변경했을시, 해당 객체만 변경된다!

🔽 User.java 🔽

package practice.beans;

import lombok.Data;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Data
@Component
@Scope("prototype")
public class User {
    private String name;
    private Integer age;
}

🔽 Main.java 🔽

package practice.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import practice.beans.Hotel;
import practice.beans.User;

import static org.springframework.web.bind.annotation.RequestMethod.GET;

@Controller
public class Main {
    @Autowired
    private User u1;
    @Autowired
    private User u2;
    @RequestMapping(value={"/single"}, method=GET)
    public String pracSingleton() {
        System.out.println("u1 name: " + u1.getName());
        System.out.println("u1 age: " + u1.getAge());
        u1.setName("First");
        u1.setAge(1);
        System.out.println("u1 name: " + u1.getName());
        System.out.println("u1 age: " + u1.getAge());
        System.out.println("u2 name: " + u2.getName());
        System.out.println("u2 age: " + u2.getAge());
        return "Single";
    }
}
  • 위와 같이 클래스에 프로토타입 설정을 해준 뒤, 다시 실행시키면 아래와 같은 결과가 나온다.
2022-11-01 22:54:27.289  INFO 58511 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
u1 name: null
u1 age: null
u1 name: First
u1 age: 1
u2 name: null
u2 age: null
  • 마지막 부분을 보면 아까는 싱글톤 타입 이었기 때문에 u1만 값을 줬음에도 불구하고 u2의 값도 변했지만 이번엔 User 클래스를 프로토타입으로 설정해줬기 때문에 u1객체와 u2객체는 서로 다른 객체로 취급된다(프로토타입).
profile
뜨거운 백엔드 개발자

0개의 댓글