복붙노트

[SPRING] 싱글 톤과 프로토 타입 빈의 차이점은 무엇입니까?

SPRING

싱글 톤과 프로토 타입 빈의 차이점은 무엇입니까?

나는 봄에 새로운데, 나는 이것을 읽었다 :

그러면 "객체 인스턴스"가 무엇입니까?

해결법

  1. ==============================

    1.Prototype scope = 주입 / 조회 할 때마다 새로운 객체가 생성됩니다. 매번 새로운 SomeClass ()를 사용할 것입니다.

    Prototype scope = 주입 / 조회 할 때마다 새로운 객체가 생성됩니다. 매번 새로운 SomeClass ()를 사용할 것입니다.

    Singleton scope = (기본값) 동일한 객체가 주입 / 조회 될 때마다 반환됩니다. 여기에서는 SomeClass의 인스턴스를 인스턴스화 한 다음 매번 반환합니다.

    참조 :

  2. ==============================

    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. ==============================

    3.위의 .dont에 추가하면 Java 싱글 톤과 혼동을 일으킬 수 있습니다. JAVA spec에 따르면 singleton은 JVM 당 하나의 빈 인스턴스 만 생성된다는 것을 의미합니다. 하지만 봄 싱글 톤은 응용 프로그램 컨텍스트마다 해당 빈에 대한 하나의 인스턴스가 생성된다는 것을 의미합니다. 따라서 애플 리케이션에 하나 이상의 컨텍스트가있는 경우 해당 빈에 대해 둘 이상의 인스턴스를 가질 수 있습니다.

    위의 .dont에 추가하면 Java 싱글 톤과 혼동을 일으킬 수 있습니다. JAVA spec에 따르면 singleton은 JVM 당 하나의 빈 인스턴스 만 생성된다는 것을 의미합니다. 하지만 봄 싱글 톤은 응용 프로그램 컨텍스트마다 해당 빈에 대한 하나의 인스턴스가 생성된다는 것을 의미합니다. 따라서 애플 리케이션에 하나 이상의 컨텍스트가있는 경우 해당 빈에 대해 둘 이상의 인스턴스를 가질 수 있습니다.

  4. ==============================

    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. ==============================

    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. ==============================

    6.둘 다 창조적 인 디자인 패턴입니다.

    둘 다 창조적 인 디자인 패턴입니다.

    Singleton은 첫 번째 호출에서 새 인스턴스를 만들고 이후 호출에서이를 반환합니다.

    프로토 타입은 매번 새로운 인스턴스를 반환합니다.

  7. ==============================

    7.나는 위에서 언급 한 문장에서 "객체 인스턴스"의 의미를 찾는 데 도움이되는 몇 가지 추가 정보를 추가하고 싶다. Spring Doc의이 단락은 "object instance"를 정의하려고합니다 :

    나는 위에서 언급 한 문장에서 "객체 인스턴스"의 의미를 찾는 데 도움이되는 몇 가지 추가 정보를 추가하고 싶다. Spring Doc의이 단락은 "object instance"를 정의하려고합니다 :

    따라서 위의 섹션에서 언급했듯이 각 Bean 정의는 객체 지향적 인 관점에서 Class로 간주 될 수 있습니다. 범위 (...와 같은)에서 정의한 데이터에 따르면이 클래스 (또는 bean 정의)에는 단 하나의 객체 인스턴스 (하나의 공유 인스턴스에 의한 단일 범위) 또는 임의의 수의 객체 인스턴스 (예 : 특정 bean에 대한 요청이있을 때마다 새 bean 인스턴스를 작성하여 프로토 타입 범위).

  8. ==============================

    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. ==============================

    9.싱글 톤은 애플리케이션 전체에서 동일한 인스턴스입니다.

    싱글 톤은 애플리케이션 전체에서 동일한 인스턴스입니다.

    프로토 타입은 getBean의 모든 새로운 요청에 대한 새로운 인스턴스입니다.

  10. ==============================

    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. ==============================

    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. ==============================

    12.Spring은 Java Singleton과는 달리 IoC 컨테이너 당 주어진 id에 대해 정확히 하나의 공유 빈 인스턴스를 보장한다. Singleton은 ClassLoader 당 하나의 특정 클래스 인스턴스 만 생성되도록 객체의 범위를 하드 코드한다.

    Spring은 Java Singleton과는 달리 IoC 컨테이너 당 주어진 id에 대해 정확히 하나의 공유 빈 인스턴스를 보장한다. Singleton은 ClassLoader 당 하나의 특정 클래스 인스턴스 만 생성되도록 객체의 범위를 하드 코드한다.

  13. from https://stackoverflow.com/questions/16058365/what-is-difference-between-singleton-and-prototype-bean by cc-by-sa and MIT license