Câu hỏi Mẫu thiết kế Singleton so với hạt Singleton trong thùng chứa Spring


Như chúng ta đã biết, chúng ta có bean như singleton theo mặc định trong Spring container và nếu chúng ta có một ứng dụng web dựa trên Spring framework thì trong trường hợp đó chúng ta thực sự cần phải thực hiện mẫu thiết kế Singleton để giữ dữ liệu toàn cục thay vì chỉ tạo một bean thông qua spring .

Hãy chịu với tôi nếu tôi không thể giải thích những gì tôi thực sự muốn hỏi.


76
2018-04-14 13:47


gốc




Các câu trả lời:


Một chiếc đậu đơn trong mùa xuân và mẫu đơn là khá khác nhau. Mẫu Singleton nói rằng một và chỉ một thể hiện của một lớp học cụ thể sẽ được tạo ra cho mỗi lớp học.

Phạm vi của một singleton mùa xuân được mô tả là "mỗi container cho mỗi bean". Đó là phạm vi của định nghĩa bean đối với một cá thể đối tượng duy nhất trên mỗi thùng chứa Spring IoC. Phạm vi mặc định trong Spring là Singleton.

Mặc dù phạm vi mặc định là singleton, bạn có thể thay đổi phạm vi của bean bằng cách chỉ định thuộc tính scope của <bean ../> thành phần.

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

49
2018-04-14 20:25



@ user184794: mỗi vùng chứa cho mỗi bean, có nghĩa là chỉ có một trình nạp lớp trong thùng chứa mùa xuân.if có hai hoặc nhiều trình nạp lớp trong thùng chứa mùa xuân, sau đó mỗi trình nạp lớp sẽ có cá thể riêng. Có nghĩa là "mỗi vùng chứa cho mỗi trình nạp lớp cho mỗi bean". Vui lòng làm rõ!! - Dead Programmer
tôi nghĩ rằng nó có nghĩa là một thùng chứa Spring sẽ sử dụng một trình nạp lớp duy nhất mà nó sở hữu. những gì bạn làm bên ngoài cơ chế của Spring không liên quan, tức là bạn có thể tạo các trình nạp lớp của riêng bạn và tạo ra nhiều thể hiện của một lớp như bạn muốn, nhưng nếu bạn đi qua vùng chứa Spring, nó sẽ không tạo nhiều hơn một cá thể - inor
Sau đó, họ không "hoàn toàn khác" khi bạn nói. Sự khác biệt duy nhất là phạm vi - Trình chứa lớp câu lệnh Spring container - Zack Macomber


Phạm vi Singleton vào mùa xuân có nghĩa là cá thể đơn lẻ trong bối cảnh mùa xuân ..
Spring container chỉ trả về cùng một cá thể một lần nữa và một lần nữa cho các cuộc gọi tiếp theo để lấy bean.
 
 
Và mùa xuân không bận tâm nếu lớp của bean được mã hóa là singleton hay không, trên thực tế, nếu class được mã hóa như singleton có constructor là private, Spring sử dụng BeanUtils.instantiateClass (javadoc đây) để đặt hàm tạo để truy cập và gọi nó.

Ngoài ra, chúng ta có thể sử dụng một thuộc tính factory-method trong định nghĩa bean như thế này

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

25
2018-06-20 15:27



bạn có chắc là bạn cần thuộc tính factory-method không? Tôi khá chắc chắn Spring biết làm thế nào để có được một thể hiện ngay cả khi các nhà xây dựng là tư nhân (có thể cố gắng gọi getInstance) - inor
Một cuộc thảo luận liên quan về cách Spring gọi hàm tạo riêng đây - Xiawei Zhang


Hãy lấy ví dụ đơn giản nhất: bạn có một ứng dụng và bạn chỉ sử dụng trình nạp lớp mặc định. Bạn có một lớp học, vì lý do gì đó, bạn quyết định rằng nó không nên có nhiều hơn một cá thể trong ứng dụng. (Hãy suy nghĩ về một kịch bản mà một số người làm việc trên các phần của ứng dụng).

Nếu bạn không sử dụng khung công tác Spring, mẫu Singleton đảm bảo rằng sẽ không có nhiều hơn một cá thể của một lớp trong ứng dụng của bạn. Đó là bởi vì bạn không thể khởi tạo các cá thể của lớp bằng cách làm 'mới' vì hàm tạo là riêng tư. Cách duy nhất để có được một thể hiện của lớp là gọi một số phương thức tĩnh của lớp (thường được gọi là 'getInstance') luôn trả về cùng một cá thể.

Nói rằng bạn đang sử dụng khung công tác Spring trong ứng dụng của bạn, chỉ có nghĩa là ngoài các cách thường xuyên để lấy một cá thể của lớp (các phương thức mới hoặc tĩnh trả về một cá thể của lớp), bạn cũng có thể yêu cầu Spring giúp bạn một thể hiện của lớp đó và Spring sẽ đảm bảo rằng bất cứ khi nào bạn yêu cầu nó cho một cá thể của lớp đó, nó sẽ luôn trả về cùng một cá thể, ngay cả khi bạn không viết lớp bằng cách sử dụng mẫu Singleton. Nói cách khác, ngay cả khi lớp có một hàm tạo công khai, nếu bạn luôn yêu cầu Spring cho một cá thể của lớp đó, Spring sẽ chỉ gọi hàm tạo đó một lần trong suốt thời gian tồn tại của ứng dụng của bạn.

Thông thường nếu bạn đang sử dụng Spring, bạn chỉ nên sử dụng Spring để tạo các cá thể và bạn có thể có một hàm tạo công khai cho lớp đó. Nhưng nếu constructor của bạn không phải là private, bạn không thực sự ngăn cản bất kỳ ai tạo ra các cá thể mới của lớp một cách trực tiếp, bằng cách bỏ qua Spring.

Nếu bạn thực sự muốn một cá thể của lớp, ngay cả khi bạn sử dụng Spring trong ứng dụng của bạn và định nghĩa lớp trong Spring là singleton, cách duy nhất để đảm bảo rằng nó cũng triển khai lớp bằng cách sử dụng mẫu Singleton. Điều đó đảm bảo rằng sẽ có một cá thể duy nhất, cho dù mọi người sử dụng Spring để có được một cá thể hay bỏ qua Spring.


18
2018-05-08 09:58





Singleton phạm vi trong mùa xuân có nghĩa là đậu này sẽ được instantiated chỉ một lần bởi mùa xuân. Ngược lại với phạm vi nguyên mẫu (ví dụ mới mỗi lần), phạm vi yêu cầu (một lần cho mỗi yêu cầu), phạm vi phiên (một lần cho mỗi phiên HTTP).

Phạm vi Singleton về mặt kỹ thuật cần phải làm với mẫu thiết kế singleton. Bạn không cần phải thực hiện đậu của bạn như là đơn cho họ được đặt trong phạm vi singleton.


9
2018-04-14 17:00



Đúng tôi nếu tôi sai vì vậy theo bạn nếu tôi cần phải thực hiện bất kỳ đối tượng như singleton vì vậy không cần phải thực hiện mô hình singleton. Tạo bean bằng Spring sẽ hoạt động. Bây giờ tôi hơi bối rối với sự hiểu biết của tôi liên quan đến mẫu thiết kế Singleton và phạm vi Singleton trong khung công tác Spring. - Peeyush
Mùa xuân không buộc bạn phải sử dụng mẫu Singleton. - lexicore


Singleton đậu trong mùa xuân và các lớp học dựa trên mẫu thiết kế Singleton là khá khác nhau.

Mẫu Singleton đảm bảo rằng một và chỉ một thể hiện của một lớp cụ thể sẽ được tạo ra cho mỗi trình nạp lớp khi phạm vi của một bean đơn Spring được mô tả là 'mỗi vùng chứa cho mỗi bean'. Singleton phạm vi trong mùa xuân có nghĩa là đậu này sẽ được instantiated chỉ một lần bởi mùa xuân. Spring container chỉ trả về cùng một cá thể một lần nữa và một lần nữa cho các cuộc gọi tiếp theo để lấy bean.


2
2017-11-27 18:29



Bạn là 'maverick java', phải không? Điều đó sẽ làm cho tuyên bố của bạn, "Tìm thấy một lời giải thích tốt và ví dụ tại ..." một nỗ lực không trung thực để che giấu rằng bạn đang liên kết đến trang web của riêng bạn. Tuy nhiên, liên kết của bạn dường như không quan trọng đối với câu trả lời. Tôi đang xóa nó, để tránh câu trả lời bị xóa là spam. Vui lòng đọc Câu hỏi thường gặp về Tự quảng cáo trước khi đăng bất kỳ liên kết nào khác lên trang web của bạn. cũng lưu ý rằng nó là khá tốt cho bạn để đặt liên kết trang web của bạn trong hồ sơ của bạn. - Andrew Barber


Tôi tìm thấy "mỗi container mỗi đậu" khó nắm bắt. Tôi sẽ nói "một bean cho mỗi id đậu" .Lets có một ví dụ để hiểu nó. Chúng ta có một mẫu bean bean. Tôi đã định nghĩa hai bean từ lớp này trong định nghĩa bean, như:

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

Vì vậy, khi bao giờ tôi cố gắng để có được đậu với id "id1", các thùng chứa mùa xuân sẽ tạo ra một đậu, bộ nhớ cache nó và trả lại cùng một đậu nơi bao giờ được tham chiếu với id1. Nếu tôi cố gắng để có được nó với id7, một bean khác sẽ được tạo ra từ lớp Sample, cùng sẽ được lưu trữ và trả về mỗi khi bạn gọi nó với id7.

Điều này là không chắc với mẫu Singleton. Trong mẫu Singlton, một đối tượng trên mỗi trình nạp lớp được tạo luôn. Nhưng vào mùa xuân nhiều vật thể đang được tạo ra cho cùng một lớp. Tuy nhiên trong mùa xuân làm cho phạm vi như Singleton trở về cùng một đối tượng cho cùng một id. Tài liệu tham khảo


2
2018-01-01 20:11





"singleton" vào mùa xuân đang sử dụng bean factory get instance, sau đó cache nó; mà mẫu thiết kế singleton là đúng, ví dụ chỉ có thể được lấy ra từ phương thức tĩnh nhận, và đối tượng không bao giờ có thể được khởi tạo công khai.


1
2017-10-01 06:20





Ví dụ: "mỗi vùng chứa cho mỗi hạt".

        <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 SINGLETON:

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

1
2017-09-16 10:15



<bean class = "com.spring4hibernate4.TestBean"> <constructor-arg name = "i" value = "1"> </ constructor-arg> <property name = "name" value = "1-name"> </ property> </ bean> <bean class = "com.spring4hibernate4.TestBean"> <constructor-arg name = "i" value = "10"> </ constructor-arg> <property name = "name" value = "10 - tên "> </ property> </ bean> </ beans> - Hariprasad


Spring singleton bean được mô tả là 'per container per bean'. Phạm vi Singleton trong Mùa xuân có nghĩa là cùng một đối tượng ở cùng một vị trí bộ nhớ sẽ được trả về cùng một id bean. Nếu một tạo ra nhiều bean của các id khác nhau của cùng một lớp thì container sẽ trả về các đối tượng khác nhau cho các id khác nhau. Điều này giống như ánh xạ khóa giá trị trong đó khóa là id bean và giá trị là đối tượng bean trong một thùng chứa mùa xuân. Khi mẫu Singleton đảm bảo rằng một và chỉ một thể hiện của một lớp cụ thể sẽ được tạo ra cho mỗi trình nạp lớp.


1
2017-11-24 09:00