[000-01-010].第08节:Bean的实例化方式

我的后端学习大纲

我Spring学习大纲


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

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

1.通过构造方法实例化

我们之前一直使用的就是这种方式。默认情况下,会调用Bean的无参数构造方法

1.1.编码实现:

  • 1.定义实体类:
package com.powernode.spring6.bean;
public class User {
    public User() {
        System.out.println("User类的无参数构造方法执行。");
    }
}
  • 2.定义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">

    <bean id="userBean" class="com.powernode.spring6.bean.User"/>

</beans>
  • 3.测试程序:
    在这里插入图片描述
package com.powernode.spring6.test;

import com.powernode.spring6.bean.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringInstantiationTest {
    @Test
    public void testConstructor(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        User user = applicationContext.getBean("userBean", User.class);
        System.out.println(user);
    }
}

  • 4.执行结果:
    在这里插入图片描述

2.通过简单工厂模式实例化

2.1.编码实现:

  • 1.定义一个bean
package com.powernode.spring6.bean;

public class Vip {

}
  • 2.第二步:编写简单工厂模式当中的工厂类角色:
package com.powernode.spring6.bean;
public class VipFactory {
    // 定义工厂类中的静态方法
    public static Vip get(){
       // 这个vip对象最终实际实际上创建的时候,还是自己new出来的
        return new Vip();
    }
}

  • 3.在Spring配置文件中指定创建该Bean的方法(使用factory-method属性指定)
<bean id="vipBean" class="com.powernode.spring6.bean.VipFactory" factory-method="get"/>
  • 4.测试:
@Test
public void testSimpleFactory(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    Vip vip = applicationContext.getBean("vipBean", Vip.class);
    System.out.println(vip);
}
  • 5.结果:
    在这里插入图片描述

3.通过factory-bean(工厂方法模式)实例化

这种方式本质上是:通过工厂方法模式进行实例化

3.1.编码实现:

  • 1.定义一个Bean,工厂方法模式中的具体产品角色
package com.powernode.spring6.bean;
public class Order {

}
  • 2.定义具体工厂类,工厂类中定义实例方法,相当于工厂方法模式中的具体工厂角色
package com.powernode.spring6.bean;

public class OrderFactory {
    public Order get(){
        return new Order();
    }
}
  • 3.在Spring配置文件中指定factory-bean以及factory-method属性,告诉Spring调用哪个对象的哪个方法来获取Bean
<bean id="orderFactory" class="com.powernode.spring6.bean.OrderFactory"/>
<bean id="orderBean" factory-bean="orderFactory" factory-method="get"/>
  • 4.编写测试程序
@Test
public void testSelfFactoryBean(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    Order orderBean = applicationContext.getBean("orderBean", Order.class);
    System.out.println(orderBean);
}
  • 5.执行结果:
    在这里插入图片描述

4.通过FactoryBean接口实例化:

  • 以上的第三种方式中,factory-bean是我们自定义的,factory-method也是我们自己定义的。
  • 在Spring中,当你编写的类直接实现FactoryBean接口之后,factory-bean不需要指定了,factory-method也不需要指定了
  • factory-bean会自动指向实现FactoryBean接口的类,factory-method会自动指向getObject()方法。

4.1.编码实现:

  • 1.定义一个Bean:
package com.powernode.spring6.bean;

public class Person {
}

  • 2.写一个类实现FactoryBean接口:
package com.powernode.spring6.bean;

import org.springframework.beans.factory.FactoryBean;

public class PersonFactoryBean implements FactoryBean<Person> {

    @Override
    public Person getObject() throws Exception {
        return new Person();
    }

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

    @Override
    public boolean isSingleton() {
        // true表示单例
        // false表示原型
        return true;
    }
}

  • 3.在Spring配置文件中配置FactoryBean
<bean id="personBean" class="com.powernode.spring6.bean.PersonFactoryBean"/>
  • 4.测试程序:
@Test
public void testFactoryBean(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    Person personBean = applicationContext.getBean("personBean", Person.class);
    System.out.println(personBean);

    Person personBean2 = applicationContext.getBean("personBean", Person.class);
    System.out.println(personBean2);
}
  • 5.执行结果:
    在这里插入图片描述

FactoryBean在Spring中是一个接口。被称为“工厂Bean”。“工厂Bean”是一种特殊的Bean。所有的“工厂Bean”都是用来协助Spring框架来创建其他Bean对象的。


5 BeanFactory和FactoryBean的区别

5.1.BeanFactory

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

5.2.FactoryBean

  • 1.FactoryBean:它是一个Bean,是一个能够辅助Spring实例化其它Bean对象的一个Bean。
  • 2.在Spring中,Bean可以分为两类:
    • 第一类:普通Bean
    • 第二类:工厂Bean(记住:工厂Bean也是一种Bean,只不过这种Bean比较特殊,它可以辅助Spring实例化其它Bean对象)

5.3.FactoryBean的使用场景:

a.注入自定义的Date:

a1.概述:
  • 1.我们前面说过,java.util.Date在Spring中被当做简单类型,简单类型在注入的时候可以直接使用value属性或value标签来完成。但我们之前已经测试过了,对于Date类型来说,采用value属性或value标签赋值的时候,对日期字符串的格式要求非常严格,必须是这种格式的:Mon Oct 10 14:30:26 CST 2022。其他格式是不会被识别的。
a2.编码实现:
  • 1.定义实体类:
    在这里插入图片描述

  • 2.定义xml:

    <bean id="studentBean" class="com.powernode.spring6.bean.Student">
      <property name="birth" value="Mon Oct 10 14:30:26 CST 2002"/>
    </bean>
    
  • 3.测试程序:

    @Test
    public void testDate(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Student studentBean = applicationContext.getBean("studentBean", Student.class);
        System.out.println(studentBean);
    }
    
  • 4.执行结果:
    在这里插入图片描述

  • 5.把日期修改下:

    <bean id="studentBean" class="com.powernode.spring6.bean.Student">
      <property name="birth" value="2002-10-10"/>
    </bean>
    
  • 6.执行结果报错:
    在这里插入图片描述

  • 7.这种情况下,我们就可以使用FactoryBean来完成这个骚操作。编写DateFactoryBean实现FactoryBean接口:

    package com.powernode.spring6.bean;
    
    import org.springframework.beans.factory.FactoryBean;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    
    public class DateFactoryBean implements FactoryBean<Date> {
    
        // 定义属性接收日期字符串
        private String date;
    
        // 通过构造方法给日期字符串属性赋值
        public DateFactoryBean(String date) {
            this.date = date;
        }
    
        @Override
        public Date getObject() throws Exception {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            return sdf.parse(this.date);
        }
    
        @Override
        public Class<?> getObjectType() {
            return null;
        }
    }
    
  • 8.定义xml:

    <!-- 这个是工厂Bean,通过工厂bean来返回普通Bean-->
    <bean id="dateBean" class="com.powernode.spring6.bean.DateFactoryBean">
      <constructor-arg name="date" value="1999-10-11"/>
    </bean>
    
    <bean id="studentBean" class="com.powernode.spring6.bean.Student">
      <property name="birth" ref="dateBean"/>
    </bean>
    
  • 9.执行结果:
    在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值