A La definición de bean es esencialmente un conjunto de reglas para crear uno o más objetos. En respuesta a una solicitud, el contenedor busca el conjunto de reglas del bean nombrado y utiliza los metadatos de configuración contenidos en la definición de ese bean para crear (o recuperar) el objeto real.

Si utiliza metadatos de configuración basados en XML , especifica el tipo (o clase) del objeto del que se va a crear una instancia, en el atributo class del elemento <bean/>. Este atributo class (que es internamente la propiedad Class de la instancia BeanDefinition) normalmente es necesario. La propiedad Class se puede utilizar de dos maneras:

  • Normalmente, para especificar la clase del bean que debe construirse si el contenedor mismo se construye directamente. crea el bean llamando reflexivamente a su constructor, que es algo equivalente al código Java con el operador new.

  • Para especificar la clase real que contiene el static es un método de fábrica que se llama para crear un objeto, en el caso menos común en el que el contenedor llama a un método de fábrica static en la clase para crear el bean. El tipo de objeto devuelto por una llamada a un método de fábrica static puede ser la misma clase o una clase completamente diferente.

Nombres de clases anidadas

Si desea personalizar una definición de bean para una clase anidada, puede usar ya sea un nombre binario o el nombre original de la clase anidada.

Por ejemplo, si tiene una clase SomeThing en el paquete com.example, y esta clase SomeThing tiene una clase anidada static llamada OtherThing, se pueden separar por un signo de dólar($) o un punto (.). Por lo tanto, el valor del atributo class en la definición del bean sería com.example.SomeThing$OtherThing o com.example.SomeThing.OtherThing .

Crear una instancia usando un constructor

Si se crea una instancia del bean usando un constructor, se pueden usar todas las clases estándar y lo harán. ser compatible con Spring. Es decir, la clase que se está desarrollando no tiene que implementar ninguna interfaz específica ni estar escrita de una manera específica. Simplemente configurar la clase de frijol debería ser suficiente. Sin embargo, dependiendo del tipo de IoC que se use para ese bean en particular, es posible que se necesite un constructor predeterminado (vacío).

El contenedor IoC de Spring puede administrar casi cualquier clase que necesite administrar. No se limita a gestionar verdaderos JavaBeans. La mayoría de los usuarios de Spring prefieren JavaBeans reales que utilizan un constructor predeterminado (sin argumentos) y definidores y captadores apropiados modelados a partir de las propiedades del contenedor. Su contenedor también puede contener clases más exóticas que no sean de estilo Bean. Si, por ejemplo, desea utilizar un grupo de conexiones heredado que es completamente inconsistente con la especificación JavaBean, Spring también puede administrarlo.

Utilizando metadatos de configuración basados en XML, puede definir su clase de bean de esta manera:


<bean id="exampleBean" class=" examples.ExampleBean"/>
<bean name="anotherExample" class="examples.ExampleBeanTwo"/>

Más detalles sobre el mecanismo para proporcionar argumentos al constructor (si requerido) y configurar la instancia del objeto de propiedades después de construir el objeto, consulte Inyección de dependencia.

Crear una instancia usando un método de fábrica estático

Al definir un bean del que crea una instancia usando un método de fábrica estático, use el atributo class para especificar la clase que contiene el static método de fábrica y el atributo factory-method para establecer el nombre del método de fábrica en sí. Debería poder llamar a este método (con argumentos opcionales, como se describe a continuación) y devolver un objeto ejecutable, que luego será tratado como si hubiera sido creado usando el constructor. Un caso de uso para dicha definición de bean es llamar a fábricas static en código heredado.

La siguiente definición de bean especifica que el bean se creará llamando a un método de fábrica. La definición no especifica el tipo (clase) del objeto devuelto, sino solo la clase que contiene el método de fábrica. En este ejemplo, el método createInstance() debe ser static. El siguiente ejemplo muestra cómo configurar un método de fábrica:


<bean id="clientService"
    class="examples.ClientService"
    factory-method="createInstance"/>

En lo siguiente El ejemplo muestra una clase que funcionará con la definición de bean anterior:

Java

public class ClientService {
    private static ClientService clientService = new ClientService();
    private ClientService() {}
    public static ClientService createInstance() {
        return clientService;
    }
}
Kotlin
c
class ClientService private constructor() {
     companion object {
         private val clientService = ClientService()
         @JvmStatic
         fun createInstance() = clientService
     }
}

Obtenga más información sobre el mecanismo para proporcionar argumentos (opcionales) a un método de fábrica y establecer las propiedades de un instancia de objeto después de que el objeto es devuelto de fábrica.

Crear una instancia usando un método de fábrica de instancias

Similar a crear una instancia a través de un método de fábrica estático, crear una instancia usando una instancia El método de fábrica llama a un método no estático de un bean existente en el contenedor para crear un nuevo bean. Para utilizar este mecanismo, deje el atributo class vacío y en el atributo factory-bean especifique el nombre del bean en el contenedor actual (o padre o predecesor) que contiene el método de instancia que se llamará para crear el objeto. Establezca el nombre del método de fábrica utilizando el atributo factory-method. El siguiente ejemplo muestra cómo configurar dicho bean:


<!-- a factory bean containing the createInstance() method -->
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
     <!-- inject any dependencies required by this locator bean -->
</bean>
<!-- bean that will be created using the factory bean -->
<bean id="clientService"
     factory-bean="serviceLocator"
     factory-method="createClientServiceInstance"/>

El siguiente ejemplo muestra el correspondiente clase:

Java

public class DefaultServiceLocator {
    private static ClientService clientService = new ClientServiceImpl();
    public ClientService createClientServiceInstance() {
         return clientService;
    }
}
Kotlin

class DefaultServiceLocator {
    companion object {
        private val clientService = ClientServiceImpl()
    }
    fun createClientServiceInstance(): ClientService {
        return clientService
    }
}

Una clase de fábrica puede contener más de un método de fábrica, como se muestra en el siguiente ejemplo:


<bean id="serviceLocator" class="examples. DefaultServiceLocator">
    <!-- inject any dependencies required by this locator bean -->
</bean>
<bean id="clientService"
      factory-bean="serviceLocator"
      factory-method="createClientServiceInstance"/>
<bean id="accountService"
      factory-bean="serviceLocator"
      factory-method="createAccountServiceInstance"/>

El siguiente ejemplo muestra el correspondiente clase:

Java

public class DefaultServiceLocator {
    private static ClientService clientService = new ClientServiceImpl();
    private static AccountService accountService = new AccountServiceImpl();
    public ClientService createClientServiceInstance() {
        return clientService;
    }
    public AccountService createAccountServiceInstance() {
        return accountService;
    }
}
Kotlin

class DefaultServiceLocator {
    companion object {
        private val clientService = ClientServiceImpl()
        private val accountService = AccountServiceImpl()
    }
    fun createClientServiceInstance(): ClientService {
        return clientService
    }
    fun createAccountServiceInstance(): AccountService {
        return accountService
    }
}

Este enfoque demuestra que una fábrica El bean se puede gestionar y configurar mediante inyección de dependencia (DI). Consulte "Dependencias y detalles de configuración".

En la documentación de Spring, un "bean de fábrica" significa un bean que está configurado en un contenedor Spring y crea objetos usando una instancia o un método de fábrica estático. Por el contrario, FactoryBean (tenga en cuenta las mayúsculas) se refiere a la clase de implementación específica de Spring FactoryBean FactoryBean..

Determinar el tipo de un bean en tiempo de ejecución

Determinar el tipo de un bean particular en tiempo de ejecución no es una tarea trivial. La clase especificada en la definición de metadatos de un bean es simplemente la referencia original a una clase, potencialmente combinada con un método de fábrica declarado o siendo una clase FactoryBean, lo que podría dar como resultado un tipo de bean diferente en tiempo de ejecución, o no. especificado en absoluto en el método de fábrica a nivel de instancia del caso (que se resuelve mediante el nombre de pila factory-bean). Además, el proxy AOP puede colocar una instancia de bean en un proxy basado en interfaz con un descubrimiento limitado del tipo real del bean de destino (solo sus interfaces implementadas).

La forma recomendada de averiguar el tipo de tiempo de ejecución real de un bean en particular es llamar a BeanFactory.getType para el nombre del bean dado. Esto tiene en cuenta todos los casos anteriores y devuelve el tipo de objeto que se devolvería llamando a BeanFactory.getBean para el mismo nombre de frijol.