【Spring】Bean 的实例化方式

Spring 为 Bean 提供了多种实例化方式,通常包括4种方式

也就是说在 Spring 中为 Bean 对象的创建准备了多种方案,目的是:更加灵活

  • 第一种:通过构造方法实例化

  • 第二种:通过简单工厂模式实例化

  • 第三种:通过 factory-bean 实例化

  • 第四种:通过 FactoryBean 接口实例化

 

一、通过构造方法实例化 

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

@Test
public void testInstantiationOne(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    SpringBean springBean = applicationContext.getBean("springBean", SpringBean.class);
    System.out.println(springBean);
}

运行结果: 

【Spring】Bean 的实例化方式_第1张图片

 

二、通过简单工厂模式实例化 

public class Star {
    public Star(){
        System.out.println("Star 的无参数构造方法执行......");
    }
}
public class StarFactory {
    public static Star get(){
        // 这个 Star 实际上创建的时候还是我们自己 new 的对象
        return new Star();
    }
}

@Test
public void testtestInstantiationTwo(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    Star star = applicationContext.getBean("starBean", Star.class);
    System.out.println(star);
}

运行结果:

【Spring】Bean 的实例化方式_第2张图片

 

三、通过 factory-bean 实例化

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

public class Gun{
    public Gun() {
        System.out.println("Gun 的无参数构造方法执行......");
    }
}
public class GunFactory{
    public Gun get(){
        return new Gun();
    }
}


@Test
public void testtestInstantiationThree(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    Gun gun = applicationContext.getBean("gun", Gun.class);
    System.out.println(gun);
}

运行结果:

【Spring】Bean 的实例化方式_第3张图片

 

四、通过 FactoryBean 接口实例化 

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

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

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

package org.qiu.spring.bean;

/**
 * @author 秋玄
 * @version 1.0
 * @email [email protected]
 * @project Spring
 * @package org.qiu.spring.bean
 * @date 2022-11-10-22:15
 * @since 1.0
 */
public class Person {
    public Person() {
        System.out.println("Person 的无参数构造方法执行......");
    }
}
package org.qiu.spring.bean;

import org.springframework.beans.factory.FactoryBean;

/**
 * @author 秋玄
 * @version 1.0
 * @email [email protected]
 * @project Spring
 * @package org.qiu.spring.bean
 * @date 2022-11-10-22:16
 * @since 1.0
 */
public class PersonFactoryBean implements FactoryBean {
    @Override
    public Person getObject() throws Exception {
        // 最终这个 Bean 的创建还是程序员自己 new 的
        return new Person();
    }

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

    /**
     * 这个方法 FactoryBean 接口有默认实现
     *      default boolean isSingleton() {
     *          return true;
     *      }
     * 即获取的 Bean 默认情况下是单例的
     * 若需要修改为多例,修改为 return false 即可
     */
    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}

@Test
public void testInstantiationFour(){
    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);
}

运行结果:

【Spring】Bean 的实例化方式_第4张图片

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

 

五、BeanFactory 和 FactoryBean 的区别 

BeanFactory:

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

BeanFactory 是工厂


FactoryBean:

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

在 Spring 中,Bean可以分为两类:

  • 第一类:普通 Bean

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

 

六、注入自定义 Date 

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

package org.qiu.spring.bean;

import java.util.Date;

/**
 * @author 秋玄
 * @version 1.0
 * @email [email protected]
 * @project Spring
 * @package org.qiu.spring.bean
 * @date 2022-11-10-22:34
 * @since 1.0
 */
public class Student {
    private Date birth;

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

    @Override
    public String toString() {
        return "Student{" +
                "birth=" + birth +
                '}';
    }
}
package org.qiu.spring.bean;

import org.springframework.beans.factory.FactoryBean;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author 秋玄
 * @version 1.0
 * @email [email protected]
 * @project Spring
 * @package org.qiu.spring.bean
 * @date 2022-11-10-22:41
 * @since 1.0
 */
public class DateFactoryBean implements FactoryBean {

    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;
    }
}


    



    
@Test
public void testDate(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    Student student = applicationContext.getBean("student", Student.class);
    System.out.println(student);
}

运行结果: 

【Spring】Bean 的实例化方式_第5张图片

 

一  叶  知  秋,奥  妙  玄  心

你可能感兴趣的:(Spring,spring,java,后端)