El mecanismo para determinar el alcance de los beans es extensible. Puede definir sus propios alcances o incluso
anular los existentes, aunque esto último se considera una mala práctica y no puede anular los alcances integrados
singleton
y prototype
.
Crear un alcance especial
Para integrar ámbitos personalizados en un contenedor Spring, debe implementar la interfaz org.springframework.beans.factory.config.Scope
,
que se describe en esta sección. Para tener una idea de cómo implementar alcances personalizados, consulte las
implementaciones de Scope
que vienen con Spring Framework, así como el javadoc Scope
, que proporciona más detalles y se describen los métodos que deben
implementarse.
La interfaz Scope
tiene cuatro métodos para sacar objetos del alcance, eliminarlos del alcance y
permitir su destrucción.
Por ejemplo, la implementación del alcance de la sesión devuelve el bean copiado que está incluido en el alcance de la sesión (si no existe, el método devuelve una nueva instancia del bean, vinculándolo a la sesión para su uso posterior). El siguiente método devuelve un objeto del ámbito subyacente:
Object get(String name, ObjectFactory<?> objectFactory
fun get(name: String, objectFactory: ObjectFactory<*>): Any
Por ejemplo, la implementación del alcance a nivel de sesión elimina un bean que está incluido en el alcance a nivel
de sesión de la sesión subyacente. Se debe devolver un objeto, pero se puede devolver null
si no se
encuentra un objeto con el nombre especificado. El siguiente método elimina un objeto del ámbito subyacente:
Eliminar objeto (nombre de cadena)
eliminación divertida(nombre: Cadena): Cualquiera
El siguiente método registra una devolución de llamada que el alcance debe activar cuando se destruye o cuando se destruye el objeto especificado en el alcance:
void registroDestructionCallback(Nombre de cadena, Destrucción ejecutableCallback)
registro divertidoDestructionCallback(nombre: cadena, destrucciónCallback: ejecutable)
Para obtener más información sobre las devoluciones de llamada de destrucción, consulte javadoc o en la implementación del alcance de Spring.
El siguiente método obtiene el identificador de diálogo para el ámbito subyacente:
String getConversationId()
fun getConversationId(): String
Este identificador es diferente para cada ámbito. Para una implementación con ámbito de sesión, este identificador podría ser el identificador de sesión.
Usando un alcance especial
Después de escribir y probar una o más implementaciones personalizadas de Scope
, debe hacer que el
contenedor Spring conozca sus nuevos alcances. El siguiente método es el método principal para registrar un nuevo
Scope
en el contenedor Spring:
void RegisterScope(String ScopeName, Scope Scope);
fun RegisterScope(scopeName: String, range: Scope)
Este método se declara en la interfaz ConfigurableBeanFactory
, a la que se puede acceder a través de la
propiedad BeanFactory
en la mayoría de las implementaciones concretas de
ApplicationContext
enviadas con Spring.
El primer argumento del método registerScope(..)
es un nombre único asociado con el alcance. Ejemplos de
tales nombres en el propio contenedor Spring son singleton
y prototype
. El segundo
argumento del método registerScope(..)
es la instancia real de la implementación personalizada de
Scope
que desea registrar y utilizar.
Supongamos que escribió su propia implementación de Scope
y luego la registró como se muestra en el
siguiente ejemplo.
SimpleThreadScope
, que se incluye
con Spring pero no está registrado de forma predeterminada. Las instrucciones serán las mismas para sus propias
implementaciones personalizadas de Scope
.
Alcance threadScope = new SimpleThreadScope();
beanFactory.registerScope("hilo", threadScope);
val threadScope = SimpleThreadScope()
beanFactory.registerScope("hilo", threadScope)
Luego puede crear definiciones de beans que sigan las reglas de alcance de su implementación personalizada de Scope
,
como se muestra a continuación:
<bean id="..." class="..." scope="thread">
Cuando utiliza una implementación personalizada de Scope
, no está limitado a registrar el alcance
mediante programación. También puede registrar Scope
de forma declarativa utilizando la clase CustomScopeConfigurer
,
como se muestra en el siguiente ejemplo:
<?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/>
en una declaración <bean>
para la implementación de FactoryBean
, el alcance es el propio bean de fábrica, no el objeto devuelto
por getObject()
.