多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[原文](https://docs.spring.io/spring/docs/5.0.6.RELEASE/spring-framework-reference/core.html#beans-beanname) [toc] bean的定义本质上就是创建对象的清单。当询问容器指定name的bean时,容器查询清单,使用bean定义封装的配置元数据来创建或获取实际对象。 如果使用xml的配置元数据,则元素`<bean/>`的属性class指定类型的对象实例.这个class属性,其实是`BeanDefinition`类的内部属性,通常是必需的(例外情况参考[工厂方法实例对象](https://docs.spring.io/spring/docs/5.0.6.RELEASE/spring-framework-reference/core.html#beans-factory-class-instance-factory-method) 和[子类实例](https://docs.spring.io/spring/docs/5.0.6.RELEASE/spring-framework-reference/core.html#beans-child-bean-definitions)).使用class的两种方式: * 典型的,容器通过反射直接调用构造方法创建对象,和直接使用java操作符`new`效果类似. * 指定包含静态工厂方法来创建对象的实际类,比较少用的场景,容器调用类的静态工厂方法创建bean,这个bean可以是类本身实例,也可以是其他类实例 > *内部类命名* > 对于静态内部类的定义,需要使用二元名称.例如在包`com.example`下有个类`Foo`,并且包含静态内部类`Bar`,定义bean的class属性的值就是:`com.example.Foo$Bar`. >注意使用$字符来分割内部类和外部类 > ## Instantiation with a constructor 当你通过构造函数来创建bean时,所有普通类都能被spring使用和兼容.即,开发的类不需要实现特定接口或用特定方式编码,只要指定bean的class就足够了.然而,根据特定bean使用的ioc容器类型,你可能需要默认的无参构造方法. spring 容器可以管理任何你想要它管理的类,不局限于纯javaBeans.大多数spring使用者更喜欢无参构造函数的bean和恰当的get,set模式设置属性.你的容器中也可以有非bean风格的类.例如,你需要使用一个传统的绝对不符合javaBean规范的连接池,spring也可以很好的管理它. 基于xml格式的配置元数据,可以如下指定bean的class ~~~xml <bean id="exampleBean" class="examples.ExampleBean"/> <bean name="anotherExample" class="examples.ExampleBeanTwo"/> ~~~ 需要给构造方法提供参数,或者在对象实例化后设置属性,参考[依赖注入](https://docs.spring.io/spring/docs/5.0.6.RELEASE/spring-framework-reference/core.html#beans-factory-collaborators) ## Instantiation with a static factory method 当定义的bean由静态工厂方法创建时,使用`class`指定包含静态工厂方法的类(不是工厂方法返回对象的类),属性`factory-method`指定工厂方法.你可以调用这个方法返回一个活动的对象,随后把它当做是通过构造方法创建的.这种bean定义方式的用途是调用历史代码的静态工厂方法. 下面的bean定义,指定bean是由工厂方法创建的.仅指定了含有工厂方法的类,并没有指定返回对象的类型.在这个例子中,`createInstance()`必须是静态方法. ~~~xml <bean id="clientService" class="examples.ClientService" factory-method="createInstance"/> ~~~ ~~~java public class ClientService { private static ClientService clientService = new ClientService(); private ClientService() {} public static ClientService createInstance() { return clientService; } } ~~~ ## Instantiation using an instance factory method 类似静态工厂方法实例化,实例工厂方法实例化就是调用容器中已存在的bean的非静态方法来创建bean.使用这种机制,`class`属性为空,使用`factory-bean`属性指定容器中bean的name,这个bean包含创建对象的实例方法,`factory-method`指定工厂方法. ~~~xml <!-- 工厂类, 包含方法 createClientServiceInstance() --> <bean id="serviceLocator" class="examples.DefaultServiceLocator"> </bean> <!-- 工厂类创建的bean --> <bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/> ~~~ ~~~java public class DefaultServiceLocator { private static ClientService clientService = new ClientServiceImpl(); public ClientService createClientServiceInstance() { return clientService; } } ~~~ 一个工厂类可以包含多个工厂方法: ~~~xml <bean id="serviceLocator" class="examples.DefaultServiceLocator"> </bean> <bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/> <bean id="accountService" factory-bean="serviceLocator" factory-method="createAccountServiceInstance"/> ~~~ ~~~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; } } ~~~