Механізм визначення області видимості бінів є розширюваним. Ти можеш визначити власні області видимості або навіть
перевизначити існуючі, хоча останнє вважається порочною практикою, а також ти не можеш перевизначити вбудовані
області видимості singleton
і prototype
.
Створення спеціальної області видимості
Щоб інтегрувати спеціальні області видимості до контейнера Spring, необхідно реалізувати інтерфейс org.springframework.beans.factory.config.Scope
,
описаний у цьому розділі. Щоб отримати уявлення про те, як реалізувати спеціальні області видимості, ознайомся з
реалізаціями Scope
, що поставляються із самим Spring Framework, а також з javadoc Scope
, в якому докладніше описано методи, які потрібно реалізувати.
Інтерфейс Scope
має чотири методи для отримання об'єктів з області видимості, видалення їх з області
видимості та дозволу на їх знищення.
Наприклад, реалізація області видимості session повертає скопійований бін, що входить до області видимості session (якщо такого не існує, метод повертає новий екземпляр біна, прив'язавши його до сесії для подальшого використання). Наступний метод повертає об'єкт із базової області видимості:
Object get(String name, ObjectFactory<?> objectFactory)
fun get(name: String, objectFactory: ObjectFactory<*>): Any
Наприклад, реалізація області видимості на рівні сесії видаляє бін, що входить до області видимості на рівні сесії, з
базової сесії. Об'єкт потрібно повернути, але може повернутися null
, якщо об'єкт із зазначеним ім'ям не
буде знайдено. Наступний метод видаляє об'єкт із базової області видимості:
Object remove(String name)
fun remove(name: String): Any
Наступний метод реєструє зворотний виклик, який область видимості повинна ініціювати під час свого знищення або знищення вказаного об'єкта в області видимості:
void registerDestructionCallback(String name, Runnable destructionCallback)
fun registerDestructionCallback(name: String, destructionCallback: Runnable)
Детальнішу інформацію про зворотні виклики знищення див. у javadoc або в області видимості в Spring.
Наступний метод отримує діалоговий ідентифікатор для базової області видимості:
String getConversationId()
fun getConversationId(): String
Цей ідентифікатор відрізняється для кожної області видимості. Для реалізації на рівні області видимості session цей ідентифікатор може бути ідентифікатором сесії.
Використання спеціальної області видимості
Після написання та тестування однієї або кількох спеціальних реалізацій Scope
, потрібно зробити так, щоб
контейнер Spring дізнався про твої нові області видимості. Наступний метод є головним методом реєстрації нового
Scope
у контейнері Spring:
void registerScope(String scopeName, Scope scope);
fun registerScope(scopeName: String, scope: Scope)
Цей метод оголошується в інтерфейсі ConfigurableBeanFactory
, який доступний через властивість BeanFactory
у більшості конкретних реалізацій ApplicationContext
, що поставляються у складі Spring.
Першим аргументом методу registerScope(..)
є унікальне ім'я, пов'язане з областю видимості. Прикладами
таких імен у контейнері Spring є singleton
і prototype
. Другим аргументом методу registerScope(..)
є реальний екземпляр спеціальної реалізації Scope
, який ти хочеш зареєструвати та використовувати.
Припустимо, що ти написав свою власну реалізацію Scope
, а потім зареєстрував її, як показано в
наступному прикладі.
SimpleThreadScope
, який входить до
складу Spring, але не реєструється за замовчуванням. Інструкції будуть такими ж для твоїх спеціальних реалізацій
Scope
.
Scope threadScope = new SimpleThreadScope();
beanFactory.registerScope("thread", threadScope);
val threadScope = SimpleThreadScope()
beanFactory.registerScope("thread", threadScope)
Потім ти зможеш створити визначення бінів, які будуть відповідати правилам визначення області видимості твоєї
реалізації Scope
, як показано нижче:
<bean id="..." class="..." scope="thread">
Під час використання власної реалізації Scope
ти не обмежений програмною реєстрацією області видимості.
Також можеш зробити реєстрацію Scope
декларативно, із використанням класу
CustomScopeConfigurer
, як показано в наведеному нижче прикладі:
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="thread">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>
<bean id="thing2" class="x.y.Thing2" scope="thread">
<property name="name" value="Rick"/>
<aop:scoped-proxy/>
</bean>
<bean id="thing1" class="x.y.Thing1">
<property name="thing2" ref="thing2"/>
</bean>
</beans>
<aop:scoped-proxy/>
в оголошення <bean>
для реалізації FactoryBean
, до області видимості входить сам фабричний бін, а не об'єкт, що
повертається з getObject()
.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ