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