SpringFramework核心技术一(IOC:实例化bean)

实例化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.Foo B a r 在名称中使用字符来将嵌套类名与外部类名分开。

二、用构造函数实例化

当您通过构造函数方法创建一个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 。

未完待续~~~

猜你喜欢

转载自blog.csdn.net/wd2014610/article/details/80301435
今日推荐