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);
}
运行结果:
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);
}
运行结果:
这种方式本质上是:通过工厂方法模式进行实例化
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);
}
运行结果:
以上的第三种方式中,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);
}
运行结果:
FactoryBean 在 Spring 中是一个接口,被称为 “工厂Bean”。“工厂Bean”是一种特殊的 Bean。所有的“工厂Bean”都是用来协助Spring 框架来创建其他 Bean 对象的
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 对象)
前面说过,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);
}
运行结果:
一 叶 知 秋,奥 妙 玄 心