一个Bean的定义本质上是能创建一个或者更多Bean的设计图(如何创建Bean的设计说明书)。当容器收到请求时查看指定Bean的说明书,然后通过此说明书创建或者获取真实的对象。
如果使用基于XML的配置元数据,在`<bean/>`元素的`class`属性中指定对象的类型用于实例化。`class`属性对应与`BeanDefinition`对象中`beanClass`成员变量,这通常是必须的(一些例外的情况请参见:下文的通过工厂方法实例化Bean和[1.7.继承Bean定义](1.7.继承Bean定义.md))。
`class`属性被用于下面的两种情况之一。
* 一般地,容器可以直接通过class反射调用构造器来创建对象,相当于在Java代码中使用`new`操作符。
* 指定的class中包含创建对象的工厂方法,这种方式是不常见的。工厂方法返回的对象可能可class的类型一致,也可能完全不一致。
> ##### 内部类类名
> 如果你想配置一个静态内部类的Bean定义,你必须使用二进制的类名。
>
> 比如:在`com.example`包内有一个名为`Foo`的类,在这个类中包含一个名为`Bar`的静态内部类,在`class`属性中你可以这么来指定:`com.example.Foo$Bar`
>
> 注意:'$'符号用于分隔外部和内部类。
* * * * *
### **通过构造器实例化**
当通过构造器来创建对象时,简单普通的类在Spring中都是可用的,兼容性良好的。换而言之,Spring实例化的对象不需要实现任何接口或者编写特定的代码,只需要提供类名即可。无论如何,根据指定Bean使用的IOC类型,你可能需要一个无参构造器。
Spring可以管理任何类型的Bean,不仅仅是JavaBean。大多数开发者更喜欢带有无参构造和Getter、Setter方法的JavaBean。容器也可以管理非Bean风格的类,比如和JavaBean规范无关的连接池。
在基于XML的配置元数据中,你可以通过下面的样例来指定Bean的配置。
~~~
<bean id="exampleBean" class="examples.ExampleBean"/>
<bean name="anotherExample" class="examples.ExampleBeanTwo"/>
~~~
关于提供参数给构造器以及在创建对象后为其设置属性的详细信息请参见:[1.4.1.依赖注入](1.4.1.依赖注入.md)。
* * * * *
### **通过静态工厂方法实例化**
如果你想通过静态工厂方法来创建对象,可以在`class`属性中指定包含静态工厂方法的类并在`factory-method`属性中指定此类的工厂方法。这种创建对象的方式主要用于遗留的代码中。
在下面的Bean定义中,对象会被指定的工厂方法来创建。只需一个包含工厂方法的类即可,无需指定返回对象的类型。在这个例子中,`createInstance()`必须是静态方法。
~~~
<bean id="clientService" class="examples.ClientService" factory-method="createInstance"/>
~~~
~~~
public class ClientService {
private static ClientService clientService = new ClientService();
private ClientService() {}
public static ClientService createInstance() {
return clientService;
}
}
~~~
关于提供参数给工厂方法以及在工厂方法创建对象后设置属性的详细信息请参见:[1.4.2.依赖配置详情](1.4.2.依赖配置详情.md)。
* * * * *
### **通过实例工厂方法实例化**
和静态工厂方法实例化对象类似,对象可以通过容器中已存在的Bean(工厂Bean)来创建,该Bean包含一个非静态的工厂方法。要使用这种方式来创建对象,首先在`factory-bean`属性中指定上述提到的工厂Bean,然后在`factory-method`属性中指定工厂方法。
~~~
<!-- 包含创建对象的工厂Bean-->
<bean id="serviceLocator" class="examples.DefaultServiceLocator"/>
<!-- 此Bean的创建通过指定的工厂Bean -->
<bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/>
~~~
~~~
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
}
~~~
一个工厂类可以包含多个工厂方法,如下所示:
~~~
<bean id="serviceLocator" class="examples.DefaultServiceLocator"/>
<bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/>
<bean id="accountService" factory-bean="serviceLocator" factory-method="createAccountServiceInstance"/>
~~~
~~~
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;
}
}
~~~
从上例可以看出:通过依赖注入可以配置和管理工厂Bean,详情参见:[1.4.2.依赖和配置详情](1.4.2.依赖和配置详情.md)。
> 在Spring 文档中,工厂Bean是通过上述方法来创建对象的Bean。而`FactoryBean`是构成Spring相关的Bean。
- ---- 阅读说明
- 一、核心技术
- 1.IOC容器
- 1.1.IOC 容器和 Bean 简介
- 1.2.容器概览
- 1.2.1.配置元数据
- 1.2.2.实例化容器
- 1.2.3.使用容器
- 1.3.Bean概览
- 1.3.1.Bean的命名
- 1.3.2.实例化Bean
- 1.4.依赖
- 1.4.1.依赖注入
- 1.4.2.依赖配置详情
- 1.4.5.注入合作者
- 1.4.4.Bean的懒加载
- 1.5.Bean的范围
- 1.6.自定义Bean的特性
- 1.6.1.生命周期回调函数
- 1.7.继承Bean定义
- 1.9.基于注解的容器配置
- 1.9.1.@Required
- 1.12.基于Java的容器配置
- 1.12.3.使用@Bean注解
- 1.15.ApplicationContext的附加功能
- 1.15.4.Web 应用中便捷的 ApplicationContext 实例
- 1.16.BeanFactory
- 2.资源
- 2.7.应用上下文和资源路径
- 3.验证、数据绑定以及类型转换
- 3.5.Spring类型转换
- 3.5.4.ConversionService API
- 5.基于 Spring 的面向切面编程
- 5.8.在 Spring 中使用 AspectJ
- 5.8.1.在 Spring 中使用 AspectJ 注入领域对象
- 二、测试
- 三、数据访问
- 四、Web应用
- 五、Web响应式编程
- 六、集成
- 4.1.介绍
- 七、编程语言