实例化bean
bean定义本质上是创建一个或多个对象的配方。容器在被询问时查看命名bean的配方,并使用由该bean定义封装的配置元数据来创建(或获取)实际对象。
一、实例化Bean的说明
如果使用基于XML的配置元数据,则可以指定要在元素的class属性中实例化的对象的类型(或类)<bean/>
。这个 class属性在内部是Class一个BeanDefinition 实例的属性,通常是强制性的。可以通过以下Class两种方式之一使用该属性:
- 通常,在容器本身通过反射调用其构造函数直接创建bean的情况下,指定要构建的bean类,这与使用new操作符的Java代码有些相同。
要指定包含static将被调用来创建对象的工厂方法的实际类,那么容器在类上调用static 工厂方法以创建该Bean的情况较少 。从调用static工厂方法返回的对象类型可以是完全相同的类或另一个类。
内部类名称
如果要为static嵌套类配置一个bean定义,则必须使用嵌套类的二进制名称。
例如,如果您Foo在com.example包中调用了一个类,并且此类 Foo具有一个static名为嵌套的类Bar,那么’class’ bean定义上的属性值将是…
com.example.FooBar。注意Bar。注意在名称中使用字符来将嵌套类名与外部类名分开。
二、用构造函数实例化
当您通过构造函数方法创建一个bean时,所有普通类都可以被Spring使用并兼容。也就是说,正在开发的类不需要实现任何特定的接口或以特定的方式编码。只需指定bean类就足够了。但是,根据您用于特定bean的IoC类型,您可能需要一个默认(空)构造函数。
Spring IoC容器几乎可以管理任何您想要管理的类; 它不限于管理真正的JavaBeans。大多数Spring用户更喜欢实际的JavaBeans,它只有一个默认的(无参数)构造函数,以及在容器中的属性之后建模的合适的setter和getter。您的容器中还可以有更多具有异国情调的非Bean风格的类。例如,如果您需要使用绝对不符合JavaBean规范的传统连接池,Spring也可以管理它。
2.1 使用基于XML的配置元数据,您可以按如下方式指定您的bean类:
<bean id="exampleBean" class="examples.ExampleBean"/>
<bean name="anotherExample" class="examples.ExampleBeanTwo"/>
三、使用静态工厂方法实例化
在定义一个使用静态工厂方法创建的bean时,可以使用该class 属性来指定包含static工厂方法的类和factory-method指定工厂方法本身的名称的属性。您应该能够调用此方法(使用后面介绍的可选参数)并返回一个活动对象,随后将其视为通过构造函数创建的对象。这种bean定义的一个用途是static在旧代码中调用工厂。
以下bean定义指定将通过调用工厂方法来创建该bean。该定义没有指定返回对象的类型(类),而只指定了包含工厂方法的类。在这个例子中,该createInstance() 方法必须是一个静态方法。
以下bean定义指定将通过调用工厂方法来创建该bean。该定义没有指定返回对象的类型(类),而只指定了包含工厂方法的类。在这个例子中,该createInstance() 方法必须是一个静态方法。
<bean id="clientService"
class="examples.ClientService"
factory-method="createInstance"/>
下面写一个例子:
package org.springframework.test;
/**
* @author:wangdong
* @description:静态工厂方法实例化
*/
public class ClientService {
//首先来new一个ClientService
private static ClientService clientService = new ClientService();
//无参构造
private ClientService(){}
//定义一个静态工厂方法
//ClientService必须为静态
public static ClientService createInstance(){
return clientService;
}
//如果在其他类中调用这个静态工厂方法实例化就像这样子写。
ClientService instantiationService = ClientService.createInstance();
}
四、使用实例工厂方法实例化Bean
与通过静态工厂方法实例化类似,使用实例工厂方法的实例化从容器调用现有bean的非静态方法来创建新的bean。要使用此机制,请将该class属性留空,并在factory-bean属性中指定当前(或父/祖代)容器中的bean的名称,该容器包含要调用以创建对象的实例方法。使用factory-method属性设置工厂方法本身的名称。
- 4.1 beanInstantiation.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- the factory bean, which contains a method called createInstance() -->
<!-- id是自己定义的给定一个Id=serviceLocator,对应类中的DefaultServiceLocator类名-->
<bean id="serviceLocator" class="org.springframework.test.DefaultServiceLocator">
<!-- inject any dependencies required by this locator bean -->
</bean>
<!-- 第一个工厂方法-->
<!-- the bean to be created via the factory bean -->
<!-- id是自己给定的,factory-bean对应于上面的id(当前(或父/祖代)容器中的bean的名称),factory-method对应于examples.DefaultServiceLocator实例中的工厂方法-->
<bean id="clientService"
factory-bean="serviceLocator"
factory-method="createClientServiceInstance"/>
<!-- 一个工厂类可以拥有多个工厂方法-->
<!-- 第二个工厂方法-->
<bean id="accountService"
factory-bean="serviceLocator"
factory-method="createAccountServiceInstance"/>
</beans>
- 4.2 实例工厂Bean
package org.springframework.test;
/**
* @author:wangdong
* @description:使用实例工厂方法实例化Bean
*/
public class DefaultServiceLocator {
//new一个ClientService实例
private static ClientService clientService = new ClientServiceImpl();
//new一个AccountService实例
private static AccountService accountService = new AccountServiceImpl();
//创建一个实例工厂方法createClientInstance
public ClientService createClientServiceInstance(){
return clientService;
}
//创建一个实例工厂方法createAccountServiceInstance
public AccountService createAccountServiceInstance(){
return accountService;
}
}
- 4.3 这个类DefaultServiceLocator需要依赖一些其他的类
- AccountService
package org.springframework.test;
/**
* @author:wangdong
* @description:创建AccountService
*/
public class AccountService {
}
- AccountServiceImpl
package org.springframework.test;
/**
* @author:wangdong
* @description:创建AccountServiceImpl去继承AccountService
*/
public class AccountServiceImpl extends AccountService{
}
- ClientService
package org.springframework.test;
/**
* @author:wangdong
* @description:静态工厂方法实例化
*/
public class ClientService {
//首先来new一个ClientService
private static ClientService clientService = new ClientService();
//无参构造
public ClientService(){}
//定义一个静态工厂方法
//ClientService必须为静态
public static ClientService createInstance(){
return clientService;
}
//如果在其他类中调用这个静态工厂方法实例化就像这样子写。
ClientService instantiationService = ClientService.createInstance();
}
- ClientServiceImpl
package org.springframework.test;
/**
* @author:wangdong
* @description:ClientServiceImpl需要继承ClientService
*/
public class ClientServiceImpl extends ClientService {
//需要有一个无参的构造
public ClientServiceImpl() {
super();
}
}
注意:
这种方法表明,工厂bean本身可以通过依赖注入(DI)进行管理和配置。
在Spring文档中,工厂bean指的是在Spring容器中配置的bean,它将通过实例或 静态工厂方法创建对象 。相反, FactoryBean(注意大写字母)是指特定于Spring的 FactoryBean 。
未完待续~~~