6、Bean的获取方式

SpringBean提供了多种实例化方式,通常包括4种方式。(也就是说在Spring中为Bean对象的创建准备了多种方案,目的是:更加灵活)

  • 第一种:通过构造方法实例化
  • 第二种:通过简单工厂模式实例化
  • 第三种:通过factory-bean实例化
  • 第四种:通过FactoryBean接口实例化

1 通过构造方法获取

<!--Spring提供的实例化方式,第一种,在Spring配置文件中直接配置类全路径,Spring会自动调用该类的无参数构造方法来实例化Bean-->
<bean class="com.cjf.bean.SpringBean" id="bean"/>

2 通过简单工厂模式获取

public class Star {
    public Star() {
        System.out.println("Star的无参数构造方法执行");
    }
}
//明星工厂
public class StarFactory {
    public static Star get() {
        //这个Star对象实际上是我们负责new的对象
        return new Star();
    }
}
    <!---Spring提供的实例化方式,第二种:通过简单工厂桃式。你需要在Spring配置文件中告诉Spring框架,调用哪个类的哪个方法软取Bean-->
    <!--factory-method 属性指定的是工厂类当中的静态方法,也就是告诉Spring框架,调用这个方法可以获取Bean-->
    <bean id="star" class="com.cjf.bean.StarFactory" factory-method="get"/>

3 通过factory-bean获取

具体的Gun

public class Gun extends Mechanical{
	public Gun() {
        System.out.println("Gun的无参数构造方法执行");
    }
}

抽象的 MechanicalFactory ,都是一种产品:机械产品

public abstract class MechanicalFactory {
    protected abstract Mechanical get();
}

具体的GunFactory

public class GunFactory extends MechanicalFactory {
    @Override
    protected Mechanical get() {
        return new Gun();
    }
}
    <!--Spring提供的实例化方式,第三种:通过工厂方法模式。通过factory-bean 属性 + factory-method 属性共同来完成-->
    <!--告诉Spring框架,调用哪个对象 的哪个方法来获取Bean-->
    <bean id="gunFactory" class="com.cjf.bean.GunFactory"/><!--GunFactory实际上就是一个FactoryBean-->
    <bean id="gun" factory-bean="gunFactory" factory-method="get"/>

4 通过FactoryBean接口获取

以上的第三种方式中,factory-bean是我们自定义的,factory-method也是我们自己定义的。

Spring中,当你编写的类直接实现FactoryBean接口之后,factory-bean不需要指定了,factory-method也不需要指定了。

factory-bean会自动指向实现FactoryBean接口的类,factory-method会自动指向getObject()方法。

public class PersonFactoryBean implements FactoryBean<Person> {
    // PersonFactoryBean 也是一个Bean,只不过通过这个Bean比较特殊,叫做工厂Bean
    @Override
    public Person getObject() throws Exception {
        return new Person();
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }

    /**
     * 接口默认返回ture,表示单例的
     * 如果 多例,直接修改为return false 即可
     */

    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}
<!--Spring提供的实例化方式,第四种:通过FactoryBean接口来实现-->
<!--由于你编写的类实现了FactoryBean接口,所以这个类是一个特殊的类-->
<!--通过一个特殊的Bean: 工厂 Bean,来返回一个普通部Bean Person对象。-->
<bean id="person" class="com.cjf.bean.PersonFactoryBean"/>

5 BeanFactory和FactoryBean的区别

5.1 BeanFactory

Spring IoC容器的顶级对象,BeanFactory被翻译为“Bean工厂”,在SpringIoC容器中,“Bean工厂”负责创建Bean对象。

BeanFactory是工厂。

 @Test
    public void testCustomScope(){
        //ApplicationContext applicationContext = 
        //    new ClassPathXmlApplicationContext("spring.xml");

        BeanFatory applicationContext = 
            new ClassPathXmlApplicationContext("spring.xml");
    }

5.2 FactoryBean

FactoryBean:它是一个Bean,是一个能够辅助Spring实例化其它Bean对象的一个Bean

Spring中,Bean可以分为两类:

  • 第一类:普通Bean
  • 第二类:工厂Bean(记住:工厂Bean也是一种Bean,只不过这种Bean比较特殊,它可以辅助Spring实例化其它Bean对象。)

6 注入自定义Date

public class Student {

    // java.util.Date 在spring当中被当做简单类型。但是简单类型的话,注入的日期字符串格式有要求。
    // java.util.Date 在rSpring当中出可以被当做非简单类型。
    private Date birth;

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    @Override
    public String toString() {
        return "Student{" +
                "birth=" + birth +
                '}';
    }
}

我们前面说过,java.util.DateSpring中被当做简单类型,简单类型在注入的时候可以直接使用value属性或value标签来完成。但我们 之前已经测试过了,对于Date类型来说,采用value属性或value标签赋值的时候,对日期字符串的格式要求非常严格,必须是这种格式的:Mon Oct 10 14:30:26 CST 2022。其他格式是不会被识别的。如以下代码:

    <bean id="student" class="com.cjf.bean.Student">
        <property name="birth" value="Mon Oct 10 14:30:26 CST 2022"/>
    </bean>

    <!--这种方式只能获取系统当前时间,不能作为当前生日-->
    <bean class="java.util.Date" id="nowTime"></bean>
    <bean id="student" class="com.cjf.bean.Student">
        <property name="birth" ref="nowTime"></property>
    </bean>

解决

public class DateFactoryBean implements FactoryBean<Date> {
    //DateFactoryBean 这个工厂协助我们Spring创建这个普通的Date
    private String strDate;

    public DateFactoryBean(String strDate) {
        this.strDate = strDate;
    }

    @Override
    public Date getObject() throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = sdf.parse(strDate);
        return date;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }
}
<!--创建工厂Bean:DateFactoryBean,返回普通Bean:java.util.Date-->
<bean id="date" class="com.cjf.bean.DateFactoryBean" >
    <constructor-arg index="0" value="2002-6-11"/>
</bean>
<bean id="student" class="com.cjf.bean.Student">
    <property name="birth" ref="date"/>
</bean>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值