programing

스프링 컨테이너의 싱글톤 디자인 패턴 vs 싱글톤 원두

minecode 2022. 10. 2. 14:52
반응형

스프링 컨테이너의 싱글톤 디자인 패턴 vs 싱글톤 원두

Spring 컨테이너에는 기본적으로 콩이 싱글톤으로 포함되어 있으며, Spring 프레임워크에 기반한 웹 어플리케이션이 있다면, 이 경우 콩을 봄까지 작성하는 것이 아니라 글로벌 데이터를 보관하기 위해 정말 싱글톤 설계 패턴을 구현해야 합니다.

제가 무엇을 부탁하려고 했는지 설명하지 못해도 조금만 참아주세요.

봄의 싱글톤 빈과 싱글톤 패턴은 상당히 다릅니다.싱글턴 패턴에서는 클래스 로더마다 특정 클래스의 인스턴스가1개만 생성됩니다.

스프링 싱글톤의 범위는 "콩 1개당 컨테이너 수"로 기술됩니다.Spring IoC 컨테이너당 단일 객체인스턴스에 대한 빈 정의 범위입니다.스프링의 기본 스코프는 싱글톤입니다.

를 bean으로 를 변경할 수 .<bean ../>★★★★★★ 。

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

나는 "통당"이 이해하기 어렵다는 것을 안다.'에 한 개씩 통에 한 개씩'이라고 해야겠다.그것을 이해하기 위한 예를 들어보자.콩 클래스 샘플이 있습니다.이 클래스의 두 개의 콩을 콩의 정의로 정의했습니다.

<bean id="id1" class="com.example.Sample" scope="singleton">
        <property name="name" value="James Bond 001"/>    
</bean>    
<bean id="id7" class="com.example.Sample" scope="singleton">
        <property name="name" value="James Bond 007"/>    
</bean>

따라서 ID가 "id1"인 콩을 가져오려고 하면 스프링 컨테이너가 콩을 1개 생성하여 캐시하고 id1로 참조된 동일한 콩을 반환합니다.id7로 가져오려고 하면 샘플 클래스에서 다른 빈이 생성되어 id7로 참조할 때마다 동일한 빈이 캐시되어 반환됩니다.

이것은 싱글톤 패턴에서는 있을 수 없는 일입니다.Singlton 패턴에서는 클래스 로더당 하나의 객체가 항상 생성됩니다.그러나 봄에는 범위를 Singleton으로 설정해도 컨테이너가 해당 클래스에서 많은 인스턴스를 만드는 데 제한이 없습니다.동일한 ID에 대한개체 작성을 다시 제한하고 동일한 ID에 대한 개체가 요청될 때 이전에 만든 개체를 반환합니다.레퍼런스

봄의 싱글톤 스코프는 스프링 컨텍스트에서 단일 인스턴스를 의미합니다.
스프링 컨테이너는 빈을 취득하기 위한 후속 콜에 대해 동일한 인스턴스를 몇 번이고 반환할 뿐입니다.


또한 spring은 bean의 클래스가 singleton으로 코딩되어 있는지 여부에 관계없이 클래스가 singleton으로 코딩되어 있는 경우, spring은 beanUtils.instantiate Class(여기서 javadoc)를 사용하여 컨스트럭터를 액세스 가능하게 설정하고 호출합니다.

또는 다음과 같이 콩 정의에서 공장 방식 속성을 사용할 수 있습니다.

    <bean id="exampleBean" class="example.Singleton"  factory-method="getInstance"/>

가장 간단한 예를 들어보겠습니다.어플리케이션이 있는데 기본 클래스 로더를 사용합니다.어떤 이유로든 응용 프로그램에 여러 인스턴스를 포함해서는 안 된다고 결정하는 클래스가 있습니다.(여러 사람이 애플리케이션의 일부를 작업하는 시나리오를 생각해 보십시오).

Spring 프레임워크를 사용하지 않는 경우 Singleton 패턴은 응용 프로그램에 여러 클래스의 인스턴스가 없도록 보장합니다.이는 생성자가 비공개이기 때문에 'new'를 수행하여 클래스의 인스턴스를 인스턴스화할 수 없기 때문입니다.클래스의 인스턴스를 가져오는 유일한 방법은 항상 동일한 인스턴스를 반환하는 클래스의 정적 메서드(일반적으로 'getInstance'라고 함)를 호출하는 것입니다.

어플리케이션에서 Spring 프레임워크를 사용하고 있다고 하는 것은 클래스의 인스턴스를 취득하는 일반적인 방법(클래스의 인스턴스를 반환하는 새로운 메서드 또는 정적 메서드) 외에 Spring에게 해당 클래스의 인스턴스를 취득하도록 요구할 수 있으며 Spring은 C의 인스턴스를 요구할 때마다 항상 해당 클래스의 인스턴스를 취득하도록 보장할 수 있음을 의미합니다.lass는 Singleton 패턴을 사용하여 클래스를 작성하지 않았더라도 항상 동일한 인스턴스를 반환합니다.즉, 클래스에 퍼블릭컨스트럭터가 있는 경우에도 항상 Spring에게 해당 클래스의 인스턴스를 요청하면 Spring은 응용 프로그램 수명 동안 해당 컨스트럭터에 한 번만 호출합니다.

일반적으로 Spring을 사용하는 경우 Spring을 인스턴스 작성에만 사용해야 하며 클래스에 공용 생성자를 사용할 수 있습니다.그러나 컨스트럭터가 개인적이지 않은 경우 Spring을 우회하여 클래스의 새 인스턴스를 직접 만드는 것을 막을 수 없습니다.

응용 프로그램에서 Spring을 사용하고 Spring의 클래스를 싱글톤으로 정의하더라도 클래스의 단일 인스턴스를 원하는 경우 싱글톤 패턴을 사용하여 클래스를 구현하는 유일한 방법입니다.이렇게 하면 사용자가 스프링을 사용하여 인스턴스를 가져오든 스프링을 건너 뛰든 단일 인스턴스가 생성됩니다.

봄의 싱글톤 스코프는 이 콩이 봄까지 단 한 번만 인스턴스화됨을 의미합니다.시제품 범위(매회 새로운 인스턴스), 요구 범위(요청마다 1회), 세션 범위(HTTP 세션마다 1회)와는 대조적으로.

싱글톤 스코프는 싱글톤 설계 패턴과는 엄밀히 말하면 관계가 없습니다.콩을 싱글톤 스코프에 넣기 위해서 싱글톤으로서 실장할 필요는 없습니다.

그 둘 사이에는 매우 근본적인 차이가 있다.Singleton 설계 패턴의 경우 클래스 인스턴스는 classLoader당1개만 작성되지만 Spring singleton에서는 IOC 컨테이너당 지정된ID 공유빈 인스턴스가1개 작성되지 않습니다.

예를 들어 SpringTest라는 이름의 클래스가 있고 XML 파일이 다음과 같은 경우:-

<bean id="test1" class="com.SpringTest" scope="singleton">
        --some properties here
</bean>    
<bean id="test2" class="com.SpringTest" scope="singleton">
        --some properties here   
</bean>

따라서 이제 메인 클래스에서 위의 두 가지 참조를 체크하면 스프링 문서에 따라 false가 반환됩니다.-

콩이 싱글톤일 경우 콩의 공유 인스턴스는 1개만 관리되며 이 콩 정의에 일치하는 ID를 가진 콩에 대한 모든 요구는 스프링 컨테이너에 의해1개의 특정 콩 인스턴스가 반환됩니다.

따라서 이 경우 클래스는 같지만 제공된 ID가 다르기 때문에 두 개의 다른 인스턴스가 생성됩니다.

봄의 싱글톤 원두와 싱글톤 디자인 패턴의 클래스는 상당히 다릅니다.

싱글톤 패턴을 사용하면 클래스 로더당 특정 클래스의 인스턴스가1개만 생성됩니다.스프링 싱글톤빈의 스코프는 '빈당 컨테이너 수'로 기술됩니다.봄의 싱글톤 스코프는 이 콩이 봄까지 단 한 번만 인스턴스화됨을 의미합니다.스프링 컨테이너는 빈을 취득하기 위한 후속 콜에 대해 동일한 인스턴스를 몇 번이고 반환할 뿐입니다.

봄 싱글톤 빈은 '콩 한 통당'으로 묘사된다.스프링의 싱글톤 스코프는 동일한 메모리 위치에 있는 동일한 개체가 동일한 빈 ID로 반환됨을 의미합니다.같은 클래스의 다른 ID를 가진 여러 개의 콩을 작성하면 컨테이너는 다른 개체를 다른 ID로 반환합니다.이것은 키 값 매핑과 같습니다.키는 bean id, value는 1개의 스프링 컨테이너 내의 bean 객체입니다.여기서 Singleton 패턴은 특정 클래스의 인스턴스가 클래스 로더당1개만 작성되도록 합니다.

지금까지의 모든 답변은 디자인 패턴과 스프링 싱글톤의 차이를 설명하는 데 초점을 맞추고 있으며 실제 질문에 대한 답변은 아닙니다.싱글톤 디자인 패턴을 사용해야 합니까, 아니면 스프링 싱글톤 빈을 사용해야 합니까?무엇이 더 나은가?

대답하기 전에 두 가지 다 할 수 있다는 것을 말씀드리겠습니다.싱글톤 디자인 패턴으로 콩을 구현하고 스프링을 사용하여 Spring 싱글톤 빈으로 클라이언트클래스에 삽입할 수 있습니다.

이 질문에 대한 답은 간단합니다.싱글턴 디자인 패턴을 사용하지 마세요!
Spring의 singleton bean을 퍼블릭 컨스트럭터와의 클래스로 사용합니다.
왜일까요? 싱글톤 디자인 패턴은 안티 패턴으로 간주되기 때문입니다.대부분 테스트가 복잡하기 때문입니다.(그리고 스프링을 사용하여 스프링을 주입하지 않으면 싱글톤을 사용하는 모든 클래스가 스프링에 단단히 결합됩니다.) 교환하거나 확장할 수 없습니다.싱글톤 안티패턴과 같이 "싱글톤 안티패턴"을 검색하여 자세한 정보를 얻을 수 있습니다.

Spring singleton을 사용하는 것은 Spring singleton을 사용하는 방법입니다(Spring singleton을 싱글톤 디자인 패턴으로 구현하지 않고 공공 건설업체와 함께 구현). Spring singleton bean을 사용하는 클래스는 Spring singleton을 필요로 하는 모든 콩에 주입합니다.singleton bean을 사용하는 클라이언트클래스에 영향을 주지 않고 언제든지 다른 구현으로 대체할 수 있습니다.

봄의 "singleton"은 콩 팩토리 get instance를 사용한 후 캐시하는 것입니다.싱글톤 설계 패턴이 엄격하면 인스턴스는 static get 메서드에서만 취득할 수 있으며 오브젝트는 절대 공개 인스턴스화할 수 없습니다.

"콩 1개당"

        <bean id="myBean" class="com.spring4hibernate4.TestBean">
            <constructor-arg name="i" value="1"></constructor-arg>
            <property name="name" value="1-name"></property>
        </bean>

        <bean id="testBean" class="com.spring4hibernate4.TestBean">
            <constructor-arg name="i" value="10"></constructor-arg>
            <property name="name" value="10-name"></property>
        </bean>
    </beans>



    public class Test {

        @SuppressWarnings("resource")
        public static void main(String[] args) {
            ApplicationContext ac = new ClassPathXmlApplicationContext("ws.xml");
            TestBean teatBean = (TestBean) ac.getBean("testBean");
            TestBean myBean1 = (TestBean) ac.getBean("myBean");
            System.out.println("a : " + teatBean.test + " : "   + teatBean.getName());
            teatBean.setName("a TEST BEAN 1");
            System.out.println("uPdate : " + teatBean.test + " : "  + teatBean.getName());
            System.out.println("a1 : " + myBean1.test + " : " + myBean1.getName());
            myBean1.setName(" a1 TEST BEAN 10");
            System.out.println("a1 update : " + teatBean.test + " : " + myBean1.getName());
        }
    }

public class TestBean {
    public int test = 0;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private String name = "default";

    public TestBean(int i) {
        test += i;
    }
}

JAVA 싱글톤:

public class Singleton {
    private static Singleton singleton = new Singleton();
    private int i = 0;

    private Singleton() {
    }

    public static Singleton returnSingleton() {

        return singleton;
    }

    public void increment() {
        i++;
    }

    public int getInt() {
        return i;
    }
}

public static void main(String[] args) {
        System.out.println("Test");

        Singleton sin1 = Singleton.returnSingleton();
        sin1.increment();
        System.out.println(sin1.getInt());
        Singleton sin2 = Singleton.returnSingleton();
        System.out.println("Test");
        sin1.increment();
        System.out.println(sin1.getInt());
    }

언급URL : https://stackoverflow.com/questions/2637864/singleton-design-pattern-vs-singleton-beans-in-spring-container

반응형