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:

Java
Object get(String name, ObjectFactory<?> objectFactory
Kotlin
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:

Java
Eliminar objeto (nombre de cadena)
Kotlin
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:

Java
void registroDestructionCallback(Nombre de cadena, Destrucción ejecutableCallback)
Kotlin
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:

Java
String getConversationId()
Kotlin
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:

Java
void RegisterScope(String ScopeName, Scope Scope);
Kotlin
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.

El siguiente ejemplo utiliza 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.
Java
Alcance threadScope = new SimpleThreadScope();
beanFactory.registerScope("hilo", threadScope);
Kotlin
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>
Cuando pones <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().