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ábricastatic
en la clase para crear el bean. El tipo de objeto devuelto por una llamada a un método de fábricastatic
puede ser la misma clase o una clase completamente diferente.
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:
public class ClientService {
private static ClientService clientService = new ClientService();
private ClientService() {}
public static ClientService createInstance() {
return clientService;
}
}
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:
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
}
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:
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;
}
}
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".
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.
GO TO FULL VERSION