[SPRING] 싱글 톤과 프로토 타입 빈의 차이점은 무엇입니까?
SPRING싱글 톤과 프로토 타입 빈의 차이점은 무엇입니까?
나는 봄에 새로운데, 나는 이것을 읽었다 :
그러면 "객체 인스턴스"가 무엇입니까?
해결법
-
==============================
1.Prototype scope = 주입 / 조회 할 때마다 새로운 객체가 생성됩니다. 매번 새로운 SomeClass ()를 사용할 것입니다.
Prototype scope = 주입 / 조회 할 때마다 새로운 객체가 생성됩니다. 매번 새로운 SomeClass ()를 사용할 것입니다.
Singleton scope = (기본값) 동일한 객체가 주입 / 조회 될 때마다 반환됩니다. 여기에서는 SomeClass의 인스턴스를 인스턴스화 한 다음 매번 반환합니다.
참조 :
-
==============================
2.코드를 통해 간단히 살펴 보겠습니다.
코드를 통해 간단히 살펴 보겠습니다.
다음은 기본 singleton Scope가있는 TennisCoach Bean입니다.
@Component @Scope("singleton") public class TennisCoach implements Coach { public TennisCoach(){ } @Autowired public void setFortuneService(FortuneService fortuneService) { this.fortuneService = fortuneService; } @Override public String getDailyWorkout() { return "Practice your backhand volley"; } @Override public String getDailyFortune() { return "Tennis Coach says : "+fortuneService.getFortune(); } }
다음은 프로토 타입 범위가있는 TennisCoach Bean입니다.
@Component @Scope("prototype") public class TennisCoach implements Coach { public TennisCoach(){ System.out.println(">> TennisCoach: inside default constructor"); } @Autowired public void setFortuneService(FortuneService fortuneService) { System.out.println(">> Tennis Coach: inside setFortuneService"); this.fortuneService = fortuneService; } @Override public String getDailyWorkout() { return "Practice your backhand volley"; } @Override public String getDailyFortune() { return "Tennis Coach says : "+fortuneService.getFortune(); } }
다음은 Main 클래스입니다.
public class AnnotationDemoApp { public static void main(String[] args) { // read spring config file ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // get the bean from the spring container Coach theCoach = context.getBean("tennisCoach",Coach.class); Coach alphaCoach = context.getBean("tennisCoach",Coach.class); // call a method on the bean System.out.println("Are the two beans same :" + (theCoach==alphaCoach)); System.out.println("theCoach : " + theCoach); System.out.println("alphaCoach: "+ alphaCoach); context.close() } }
싱글 톤 범위의 경우 출력은 다음과 같습니다.
Are the two beans same :true theCoach : com.springdemo.TennisCoach@2a53142 alphaCoach: com.springdemo.TennisCoach@2a53142
프로토 타입 범위의 경우 출력은 다음과 같습니다.
Are the two beans same :false theCoach : com.springdemo.TennisCoach@1b37288 alphaCoach: com.springdemo.TennisCoach@1a57272
희망이 귀하의 질문에 대한 답변. :디
-
==============================
3.위의 .dont에 추가하면 Java 싱글 톤과 혼동을 일으킬 수 있습니다. JAVA spec에 따르면 singleton은 JVM 당 하나의 빈 인스턴스 만 생성된다는 것을 의미합니다. 하지만 봄 싱글 톤은 응용 프로그램 컨텍스트마다 해당 빈에 대한 하나의 인스턴스가 생성된다는 것을 의미합니다. 따라서 애플 리케이션에 하나 이상의 컨텍스트가있는 경우 해당 빈에 대해 둘 이상의 인스턴스를 가질 수 있습니다.
위의 .dont에 추가하면 Java 싱글 톤과 혼동을 일으킬 수 있습니다. JAVA spec에 따르면 singleton은 JVM 당 하나의 빈 인스턴스 만 생성된다는 것을 의미합니다. 하지만 봄 싱글 톤은 응용 프로그램 컨텍스트마다 해당 빈에 대한 하나의 인스턴스가 생성된다는 것을 의미합니다. 따라서 애플 리케이션에 하나 이상의 컨텍스트가있는 경우 해당 빈에 대해 둘 이상의 인스턴스를 가질 수 있습니다.
-
==============================
4.Singleton Scope : Singleton 범위를 사용하면 하나의 bean 인스턴스가 제공된 bean 정의로 생성되고 같은 bean에 대한 후속 요청의 경우 Spring 컨테이너는 동일한 인스턴스를 리턴합니다.
Singleton Scope : Singleton 범위를 사용하면 하나의 bean 인스턴스가 제공된 bean 정의로 생성되고 같은 bean에 대한 후속 요청의 경우 Spring 컨테이너는 동일한 인스턴스를 리턴합니다.
Spring 문서에서 :
예: 다음과 같이 bean accountDao를 정의했다.
<bean id="accountDao" class="" />
그리고 또 다른 두 콩은이 accountDao 빈을 사용합니다.
<bean id="someBean" ref="accountDao" /> <bean id="anotherBean" ref="accountDao" />
Spring은 처음에 accountDaobean을 생성하고 캐시합니다. 그리고 나서 다른 일부 Bean과 다른 Bean에 대해 accountDao의 동일한 인스턴스를 제공합니다.
참고 : Bean 정의에 범위가 지정되지 않은 경우 Singleton이 기본 범위입니다.
프로토 타입 범위 : 프로토 타입 범위의 경우, Bean에 대한 각 요청마다 Bean의 새 인스턴스가 작성되어 리턴됩니다. 이것은 클래스에서 java의 new 연산자를 호출하는 것과 비슷합니다.
예: 다음과 같이 bean accountDao를 정의했다.
<bean id="accountDao" class="" scope="prototype"/>
그리고 또 다른 두 콩은이 accountDao 빈을 사용합니다.
<bean id="someBean" ref="accountDao" /> <bean id="anotherBean" ref="accountDao" />
someBean과 anotherBean의 경우, Spring은 accountDao 객체의 두 개의 분리 된 인스턴스를 반환 할 것이다.
중요한 차이점 중 하나는 프로토 타입 범위에서 Spring이 빈의 전체 라이프 사이클을 관리하지 못하기 때문에 클린업이 클라이언트 코드에 의해 수행되어야한다는 점이다.
Spring 문서에서 :
-
==============================
5.Singleton : scope가 singleton으로 설정되면, Spring IoC 컨테이너는 그 bean 정의에 의해 정의 된 객체의 인스턴스 하나를 정확히 생성한다. 이 단일 인스턴스는 이러한 싱글 톤 bean의 캐시에 저장되며, 그 이후의 모든 요청과 참조 된 bean에 대한 참조는 캐시 된 오브젝트를 리턴합니다.
Singleton : scope가 singleton으로 설정되면, Spring IoC 컨테이너는 그 bean 정의에 의해 정의 된 객체의 인스턴스 하나를 정확히 생성한다. 이 단일 인스턴스는 이러한 싱글 톤 bean의 캐시에 저장되며, 그 이후의 모든 요청과 참조 된 bean에 대한 참조는 캐시 된 오브젝트를 리턴합니다.
Prototype : scope가 prototype으로 설정되면, Spring IoC 컨테이너는 특정 bean에 대한 요청이있을 때마다 객체의 새로운 bean 인스턴스를 생성한다. 원칙적으로 모든 state-full beans에 대한 프로토 타입 범위와 stateless beans에 대한 singleton 범위를 사용하십시오.
-
==============================
6.둘 다 창조적 인 디자인 패턴입니다.
둘 다 창조적 인 디자인 패턴입니다.
Singleton은 첫 번째 호출에서 새 인스턴스를 만들고 이후 호출에서이를 반환합니다.
프로토 타입은 매번 새로운 인스턴스를 반환합니다.
-
==============================
7.나는 위에서 언급 한 문장에서 "객체 인스턴스"의 의미를 찾는 데 도움이되는 몇 가지 추가 정보를 추가하고 싶다. Spring Doc의이 단락은 "object instance"를 정의하려고합니다 :
나는 위에서 언급 한 문장에서 "객체 인스턴스"의 의미를 찾는 데 도움이되는 몇 가지 추가 정보를 추가하고 싶다. Spring Doc의이 단락은 "object instance"를 정의하려고합니다 :
따라서 위의 섹션에서 언급했듯이 각 Bean 정의는 객체 지향적 인 관점에서 Class로 간주 될 수 있습니다. 범위 (...와 같은)에서 정의한 데이터에 따르면이 클래스 (또는 bean 정의)에는 단 하나의 객체 인스턴스 (하나의 공유 인스턴스에 의한 단일 범위) 또는 임의의 수의 객체 인스턴스 (예 : 특정 bean에 대한 요청이있을 때마다 새 bean 인스턴스를 작성하여 프로토 타입 범위).
-
==============================
8.scope가 singleton으로 설정되면, Spring IoC 컨테이너는 그 bean 정의에 의해 정의 된 객체의 인스턴스 하나를 정확히 생성한다. 이 단일 인스턴스는 이러한 싱글 톤 bean의 캐시에 저장되며, 그 이후의 모든 요청과 참조 된 bean에 대한 참조는 캐시 된 오브젝트를 리턴합니다.
scope가 singleton으로 설정되면, Spring IoC 컨테이너는 그 bean 정의에 의해 정의 된 객체의 인스턴스 하나를 정확히 생성한다. 이 단일 인스턴스는 이러한 싱글 톤 bean의 캐시에 저장되며, 그 이후의 모든 요청과 참조 된 bean에 대한 참조는 캐시 된 오브젝트를 리턴합니다.
기본 범위는 항상 싱글 톤이지만, 하나의 빈 인스턴스 만 필요로 할 때는 scope 속성을 singleton으로 설정할 수 있습니다
Singleton과 Prototype의 차이점은 모든 state-full beans에 대한 프로토 타입 범위와 stateless beans에 대한 Singleton scope입니다.
-
==============================
9.싱글 톤은 애플리케이션 전체에서 동일한 인스턴스입니다.
싱글 톤은 애플리케이션 전체에서 동일한 인스턴스입니다.
프로토 타입은 getBean의 모든 새로운 요청에 대한 새로운 인스턴스입니다.
-
==============================
10.프로토 타입 범위 : 삽입 될 때마다 새 객체가 만들어집니다. 싱글 톤 범위 : 동일한 객체가 주입 될 때마다 반환됩니다.
프로토 타입 범위 : 삽입 될 때마다 새 객체가 만들어집니다. 싱글 톤 범위 : 동일한 객체가 주입 될 때마다 반환됩니다.
프로토 타입 범위는 stateful 인 모든 bean에 사용되는 반면 singleton 범위는 stateless bean에 사용되어야합니다. 내 예를 들어 설명해 드리겠습니다. 분명한 이해를 얻으려면 직접 복사하여 실행하십시오. 인터페이스 코치를 고려하십시오.
public interface Coach { public String getDailyWorkout(); public String getDailyFortune(); }
코치를 구현하는 TrackCoach라는 또 다른 클래스가 있습니다.
public class TrackCoach implements Coach { private FortuneService fortuneService; public TrackCoach(FortuneService fortuneService) { this.fortuneService = fortuneService; } @Override public String getDailyWorkout() { return "Run a hard 5k"; } @Override public String getDailyFortune() { return "Just Do it: " + fortuneService.getFortune(); } }
이제 FortuneService 인터페이스가 있습니다.
public interface FortuneService { public String getFortune(); }
우리의 클래스 HappyFortuneService에 의해 구현됩니다.
public class HappyFortuneService implements FortuneService { @Override public String getFortune() { return "Today is your lucky day!"; } }
두 클래스를 연결하고 한 클래스의 객체 빈을 Xml을 사용하여 다른 객체 빈에 삽입합시다. 의존성 주입을 수행합시다. 자바 어노테이션을 사용하여이 작업을 수행 할 수 있습니다.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- Define your beans here --> <!-- define the dependency --> <bean id = "myFortuneService" class = "com.luv2code.springdemo.HappyFortuneService"> </bean> <bean id = "myCoach" class = "com.luv2code.springdemo.TrackCoach" scope = "singleton"> <!-- set up construction injection --> <constructor-arg ref = "myFortuneService" /> </bean> </beans>
scope = singleton임을 주목하십시오.
이제 BeanScopeDemoApp를 정의 해 보겠습니다. 우리의 주요 메소드가 있습니다.
import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanScopeDemoApp { public static void main(String[] args) { // load the spring configuration file ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beanScope-applicationContext.xml"); // retrieve bean from spring container Coach theCoach = context.getBean("myCoach", Coach.class); Coach alphaCoach = context.getBean("myCoach", Coach.class); // check if they are the same boolean result = (theCoach == alphaCoach); // print out the results System.out.println("\nPointing to the same object: " + result); System.out.println("\nMemory location for theCoach: " + theCoach); System.out.println("\nMemory location for alphaCoach: " + alphaCoach +"\n"); // close the context context.close(); } }
위 코드를 실행하면 다음과 같은 결과가 표시됩니다.
Pointing to the same object: true Memory location for theCoach: com.luv2code.springdemo.TrackCoach@16515bb7 Memory location for alphaCoach: com.luv2code.springdemo.TrackCoach@16515bb7
동일한 객체를 가리키고 두 번 호출 한 후 동일한 메모리 위치를 차지합니다. 이제 Xml 파일에서 scope = prototype을 변경하고 저장 한 다음 BeanScopeDemoApp를 다시 실행 해 봅시다. 다음 결과가 표시됩니다.
Pointing to the same object: false Memory location for theCoach: com.luv2code.springdemo.TrackCoach@6d4d203d Memory location for alphaCoach: com.luv2code.springdemo.TrackCoach@627fbcda
다른 객체를 가리키고 두 번 호출 한 후 다른 메모리 위치를 차지합니다. 이것은 제가 방금 말한 것을 보여주는 그래픽입니다.
-
==============================
11.주 : 다른 bean에 의해 참조되고 Application context를 사용하여 호출되면 범위가있는 Bean이 작성됩니다.
주 : 다른 bean에 의해 참조되고 Application context를 사용하여 호출되면 범위가있는 Bean이 작성됩니다.
이것을 확인하는 예제 코드.
public class PrototypeClass { PrototypeClass() { System.out.println("prototype class is created"+this.toString()); } }
생성자가 호출 될 때 관련 텍스트가 인쇄됩니다.
아래의 코드는
for(int i=0;i<10;i++) { PrototypeClass pct= (PrototypeClass) context.getBean("protoClass"); }
콩 정의
<bean id="protoClass" class="Spring.PrototypeClass" scope="prototype</bean>
이제 bean 정의의 범위를 싱글 톤으로 변경했습니다. 생성자는 컨텍스트 초기화 중 한 번만 호출됩니다. 다음으로 scope 속성을 제거하고 싱글 톤과 동일한 동작을 관찰했습니다.
-
==============================
12.Spring은 Java Singleton과는 달리 IoC 컨테이너 당 주어진 id에 대해 정확히 하나의 공유 빈 인스턴스를 보장한다. Singleton은 ClassLoader 당 하나의 특정 클래스 인스턴스 만 생성되도록 객체의 범위를 하드 코드한다.
Spring은 Java Singleton과는 달리 IoC 컨테이너 당 주어진 id에 대해 정확히 하나의 공유 빈 인스턴스를 보장한다. Singleton은 ClassLoader 당 하나의 특정 클래스 인스턴스 만 생성되도록 객체의 범위를 하드 코드한다.
from https://stackoverflow.com/questions/16058365/what-is-difference-between-singleton-and-prototype-bean by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring Boot Rest Controller에서 기본 JSON 오류 응답 수정 (0) | 2019.01.10 |
---|---|
[SPRING] persistence.xml없이 Spring을 설정하는 방법은? (0) | 2019.01.10 |
[SPRING] 프로그래밍 방식으로 Spring에서 속성 자리 표시자를 결정하는 방법 (0) | 2019.01.10 |
[SPRING] JPA @OneToMany -> 부모 - 하위 참조 (외래 키) (0) | 2019.01.10 |
[SPRING] @RunWith 및 @ContextConfiguration 주석이 달린 jUnit 테스트에서 Spring 컨텍스트에 액세스하는 방법? (0) | 2019.01.10 |