[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
권오남 / Onam Kwon

0개의 댓글