programing

싱글톤과 원형 콩의 차이점은 무엇입니까?

easyjava 2023. 10. 1. 23:06
반응형

싱글톤과 원형 콩의 차이점은 무엇입니까?

저는 봄이 처음인데 이 글을 읽었습니다.

기본적으로 콩은 응용 프로그램에서 존재를 정의하는 스코프를 가지고 있습니다.

싱글톤(Singleton): Spring IOC 컨테이너당 단일 객체 인스턴스에 대한 단일 빈 정의를 의미합니다.

프로토타입(Prototype): 개체 인스턴스의 개수에 대한 단일 빈 정의를 의미합니다.

그렇다면 "객체 인스턴스"란 무엇입니까?

프로토타입 스코프 = 주입/looked업 할 때마다 새로운 오브젝트가 생성됩니다.쓰임새가.new SomeClass()매번.

싱글톤 스코프 = (기본값)주입/검색할 때마다 동일한 개체가 반환됩니다.여기서 그것은 하나의 예를 인스턴스화할 것입니다.SomeClass그때마다 돌려주는 거죠

참고 항목:

그냥 코드를 통해서 이것을 찾아봅시다.

다음은 기본 스코프가 있는 테니스 코치 빈입니다.

@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();
    }

}

다음은 원형 범위의 테니스 코치 빈입니다.

@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

위의 내용을 추가하면..자바 싱글톤과 혼동하지 마세요.JAVA 사양에 따르면 singleton은 해당 bean의 인스턴스가 JVM당 하나씩만 생성됨을 의미하지만 봄에 singleton은 해당 bean의 인스턴스가 애플리케이션 컨텍스트당 하나씩 생성됨을 의미합니다.따라서 앱에 둘 이상의 컨텍스트가 있는 경우 해당 빈에 대한 둘 이상의 인스턴스를 여전히 가질 수 있습니다.

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

싱글턴은 첫 번째 통화에서 새 인스턴스를 만들고 이후 통화에서 이 인스턴스를 반환합니다.

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

싱글턴 범위:싱글톤 스코프를 사용하면 제공된 빈 정의를 사용하여 하나의 빈 인스턴스만 생성되고 동일한 빈에 대한 후속 요청을 위해 Spring 컨테이너에서 동일한 인스턴스를 반환합니다.

Spring 설명서에서:

.. 빈 정의를 정의하고 단일 톤으로 범위를 지정하면 Spring IoC 컨테이너가 해당 빈 정의에 의해 정의된 개체의 인스턴스 하나를 정확히 생성합니다.이 단일 인스턴스는 싱글톤 빈의 캐시에 저장되며, 이름이 지정된 빈에 대한 모든 후속 요청 및 참조는 캐시된 개체를 반환합니다...

를 들어, 를 정의했습니다: , 합니다.accountDao아래와 같이

<bean id="accountDao" class="" />

또 두 의 콩은 합니다를 합니다.accountDao

<bean id="someBean" ref="accountDao" /> 
<bean id="anotherBean" ref="accountDao" />

에는 됩니다를 낼 것입니다.accountDao콩을 넣고 캐싱합니다.에도.r.someBean만 아니라.anotherBean를 동일하게 합니다.accountDao.

참고: 빈 정의로 지정된 범위가 없는 경우 싱글턴이 기본 범위입니다.

프로토타입 범위:프로토타입 범위의 경우, 콩에 대한 각 요청에 대해 새로운 콩 인스턴스가 생성되어 반환됩니다.이것은 java에서 클래스의 새 연산자를 호출하는 것과 유사합니다.

를 들어, 를 정의했습니다: , 합니다.accountDao아래와 같이

<bean id="accountDao" class="" scope="prototype"/>

또 두 의 콩은 합니다를 합니다.accountDao

<bean id="someBean" ref="accountDao" /> 
<bean id="anotherBean" ref="accountDao" />

일부 Bean 및 다른 Bean의 경우 Spring은 계정 Dao 개체의 두 개의 개별 인스턴스를 반환합니다.

한 가지 중요한 차이점은 프로토타입 범위의 경우 Spring이 콩의 전체 라이프사이클을 관리하지 않는다는 점이며, Cleanup은 클라이언트 코드에 의해 수행되어야 합니다.

Spring 설명서에서:

Spring은 프로토타입 빈의 전체 라이프사이클을 관리하지 않습니다. 컨테이너는 프로토타입 개체를 인스턴스화, 구성 및 조립한 후 해당 프로토타입 인스턴스에 대한 추가 기록 없이 클라이언트에게 전달합니다.따라서 범위에 관계없이 모든 개체에서 초기화 라이프사이클 콜백 방법이 호출되지만 프로토타입의 경우 구성된 파괴 라이프사이클 콜백이 호출되지 않습니다.클라이언트 코드는 프로토타입 범위 개체를 정리하고 프로토타입 빈이 보유하고 있는 값비싼 리소스를 해제해야 합니다.

  1. 싱글톤 스코프가 기본값입니다.
  2. 싱글톤 콩은 앱 컨텍스트 초기화 중에 생성되며 항상 같은 콩이 반환됩니다.
  3. 원형 콩은 언제 불려질 때마다 만들어집니다.그것이 불려질 때마다 우리는 새로운 물체를 얻습니다.

참고: 다른 콩이 참조하고 Application 컨텍스트를 사용하여 호출하면 범위가 모두 지정된 콩이 생성됩니다.

이를 확인하기 위한 예시 코드.

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");
}

프로토타입 클래스가 생성됩니다. 봄.프로토타입 클래스@29774679 프로토타입 클래스가 생성되었습니다.프로토타입 클래스@3fffc5af1 프로토타입 클래스가 생성되었습니다.프로토타입 클래스@5e5792a0 프로토타입 클래스가 생성되었습니다.PrototypeClass@2665322PrototypeClass가 생성되었습니다.PrototypeClass@3532ec19 프로토타입 클래스가 생성되었습니다.프로토타입 클래스@68c4039c 프로토타입 클래스가 생성되었습니다.PrototypeClass@ae45eb6 프로토타입 클래스가 생성되었습니다.프로토타입 클래스@59f99ea 프로토타입 클래스가 생성되었습니다.PrototypeClass@27efef64 프로토타입 클래스가 생성되었습니다.PrototypeClass@6f7fd0e6 프로토타입 클래스가 생성되었습니다.프로토타입 클래스@47c62251

콩의 정의는

<bean id="protoClass" class="Spring.PrototypeClass" scope="prototype</bean>

이제 빈 정의의 범위를 싱글톤으로 변경했습니다. 컨스트럭터는 컨텍스트 초기화 중에 한 번만 호출됩니다.다음으로 스코프 속성을 제거하고 싱글톤과 동일한 동작을 관찰했습니다.

언급된 문장에서 '객체 인스턴스'의 의미를 알아보는 데 도움이 될 수 있는 몇 가지 추가 정보를 추가하고자 합니다.Spring Doc의 이 단락은 "object instance"를 정의하려고 합니다.

빈 정의를 만들 때 해당 빈 정의로 정의된 클래스의 실제 인스턴스를 만드는 방법을 만듭니다.콩 정의가 레시피라는 개념은 중요합니다. 클래스와 마찬가지로 하나의 레시피에서 많은 개체 인스턴스를 만들 수 있다는 것을 의미하기 때문입니다.

따라서 위 절에서 언급한 바와 같이, 각각의 빈 정의는 클래스(Object Oriented)로 간주되거나 클래스로 간주될 수 있습니다.정의한 데이터(예: 스코프, ...)에 따라 이 클래스(또는 bean 정의)는 하나의 개체 인스턴스(공유 인스턴스 하나에 의한 단일 톤 범위) 또는 임의 수의 개체 인스턴스(예: 해당 bean에 대한 요청이 있을 때마다 새로운 bean 인스턴스를 생성하여 프로토타입 범위)를 가질 수 있습니다.

프로토타입 범위:주입할 때마다 새 개체가 생성됩니다.
싱글톤 스코프:주입할 때마다 동일한 개체가 반환됩니다.

상태가 있는 모든 콩에는 프로토타입 스코프가 사용되지만 상태가 없는 콩에는 싱글톤 스코프가 사용되어야 합니다.예를 들어 설명하겠습니다.직접 복사하여 실행하여 명확한 이해를 구하시기 바랍니다.Coach 인터페이스를 고려합니다.

public interface Coach {

    public String getDailyWorkout();

    public String getDailyFortune();

}

우리는 코치를 구현하는 트랙코치라는 다른 수업이 있습니다.

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();
    }    
}

이제 Fortune Service 인터페이스가 있습니다.

public interface FortuneService {

    public String getFortune();

}

우리반 해피포춘 서비스에서 시행하고 있습니다.

public class HappyFortuneService implements FortuneService {

    @Override
    public String getFortune() {
        return "Today is your lucky day!";
    }

}

두 클래스를 연결하고 Xml을 사용하여 한 클래스의 개체 빈을 다른 클래스에 주입해 보겠습니다.의존성 주입을 해보겠습니다.java 주석을 사용하여 이 작업을 수행할 수 있습니다.

<?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

같은 대상을 가리키며 두 번 호출한 후 같은 메모리 위치를 차지합니다.요?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

이것은 다른 물체를 가리키며 두 번 호출한 후 다른 메모리 위치를 차지합니다.이것은 제가 방금 말한 것을 그래픽으로 보여주는 것입니다.

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

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

언급URL : https://stackoverflow.com/questions/16058365/what-is-difference-between-singleton-and-prototype-bean

반응형