Spring创建Bean的三种方式

1.使用构造器创建Bean的实例

默认情况下使用无参数的构造方法来实例化Bean
<bean id="bean1" class="cn.itcast.spring3.demo2.Bean1"></bean>

条件:必须要有无参数构造函数,如果自己定义了有参数的构造函数如果忘了定义无参的构造函数,Spring就会报错,因为Spring底层用到的是反射技术,而反射用到的就是无参数构造函数



2.使用静态工厂方法实例化Bean

使用静态工厂方法实例化Bean时,class属性并不是指定Bean实例的实现类,而是静态工厂类。

通俗的说就是通过工厂来产生类的对象,然后我们调用工厂的方法来获取对象,比无参数构造函数多了一个BeanFactory

下面是类的UML图
Bean是接口,Cat和Dog是实现类,BeanFactory类中通过方法获取Cat和Dog对象

下面是applicationContext.xml配置文件中的内容:

<bean id="dog" class="demo1.BeanFactory" factory-method="getBean">
    <!-- 配置静态工厂方法的参数 -->
    <constructor-arg value ="dog"/>
    <!-- 驱动Spring以我是dog为参数执行dog的setMsg方法 -->
    <property name="msg" value="我是dog"/>
</bean>

<bean id="cat" class="demo1.BeanFactory" factory-method="getBean">
    <constructor-arg value="cat"/>
    <property name="msg" value="我是猫"/>
</bean>

工厂类BeanFactory的代码如下:

public class BeanFactory {
    //args参数决定哪个是Bean的实力
    public static Bean getBean(String args){
        if(args.equalsIgnoreCase("dog")){
            return new Dog();
        }else{
            return new Cat();
        }
    }
}

下面是测试类的代码和测试结果

    @Test
    public void test(){
        ApplicationContext ctx = 
                new ClassPathXmlApplicationContext("applicationContext2.xml");  
        Bean b1 = ctx.getBean("dog",Bean.class);
        b1.testBean();  

        Bean b2 = ctx.getBean("cat",Bean.class);
        b2.testBean();  
    }

测试结果:

Dog的方法 == 我是dog
Cat调用方法==我是猫

总结:

静态工厂方法实例化Bean的方式是:

Spring解析配置文件中的信息,根据配置文件的信息,通过反射调用静态工厂类的静态方法,将静态工厂方法的返回值作为Bean的实例。

而详细的步骤是:

1.Spring加载了XML的配置文件信息

2.通过配置文件中的factory-method="getBean"来指定静态工厂方法创建Bean

3.通过配置文件信息,Spring调用BeanFactory的getBean(String args)方法,并通过配置文件中的`<constructor-arg value ="dog"/>`为方法传入参数,这样就通过静态工厂来创建了一个Bean

4.在测试类中,通过getBean方法获得Bean的子类的实例对象

3.调用实例工厂方法实例化Bean

其实实例化工厂实例化Bean的方法和静态工厂实例化Bean 的区别不大。

    静态工厂实例化Bean只需要静态工厂类即可(因为静态工厂类的getBean方法是静态的)
    实例化工厂则需要工厂实例。

所以两个方法的配置文件是会不同的。

在上面的基础上,实例工厂的代码是如下:基本没改变只是不再是静态方法了

public class BeanFactory {
    //args参数决定哪个是Bean的实力
    public Bean getBean(String args){
        if(args.equalsIgnoreCase("dog")){
            return new Dog();
        }else{
            return new Cat();
        }
    }
}

而ApplicationContext.xml的变动就比较大

<bean id="animalFactory" class="demo1.BeanFactory1"/>
<bean id="dog" factory-bean="animalFactory" factory-method="getBean">
    <!-- 配置静态工厂方法的参数 -->
    <constructor-arg value ="dog"/>
    <!-- 驱动Spring以我是dog为参数执行dog的setMsg方法 -->
    <property name="msg" value="我是dog"/>
</bean>
<bean id="cat" factory-bean="animalFactory" factory-method="getBean">
    <constructor-arg value="cat"/>
    <property name="msg" value="我是猫"/>
</bean>

此时的配置文件中改动如下:

<bean../>元素无需class属性,因为Spring容器不再直接实例化Bean,Spring容器仅仅调用实例工厂的工厂方法

所以第二个变动就是为BeanFactory配置了Bean,负责生产其他的Bean。

还有就是普通的<bean../>中增加了factory-bean=”animalFactory”这一项

总结:

调用实例方法和静态方法的区别:
1.配置实例工厂方法创建Bean,必须要为实例工厂配置Bean实例,而静态工厂方法则无需配置Bean实例

2.配置静态工厂方法创建Bean,必须以Bean-factory属性确定工厂Bean,而配置静态工厂方法创建Bean,则使用class确定静态工厂类。

相同之处如下:
1.都需要使用factory-method指定产生Bean实例的工厂方法

2.工厂方法如果需要参数则使用<construct-args.../>元素指定参数值

3.普通的设值注入都是用<property../>元素确定参数值

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值