Bean的实例化办法

Spring为Bean供给了多种实例化办法,一般包含4种办法。(也便是说在Spring中为Bean目标的创立准备了多种方案,意图是:愈加灵敏)

  • 第一种:经过结构办法实例化
  • 第二种:经过简略工厂形式实例化
  • 第三种:经过工程办法形式实例化
  • 第四种:经过FactoryBean接口实例化

1. 经过结构办法实例化

咱们之前一直运用的便是这种办法。默许情况下,会调用Bean的无参数结构办法。在spring装备文件中直接装备类全途径,spring会主动调用该类的无参结构办法来实例化Bean。

public class SpringBean {
    private int a;
    public SpringBean() {
        System.out.println("无参结构:"+this);
    }
    public int getA() {
        return a;
    }
    public void setA(int a) {
        this.a = a;
    }
}
<?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="springBean" class="com.qiuye.beanInstance.entity.SpringBean">
    <property name="a" value="1"></property>
 </bean>
</beans>
public void test() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spirng-instance.xml");
    SpringBean springBean = applicationContext.getBean("springBean",SpringBean.class);
    System.out.println(springBean);
    System.out.println(springBean.getA());
}

履行成果:

Spring之Bean实例化的四种方式

留意: spring的Bean的作用域默许是单例(singleton,是bean标签里边scope特点的值之一,不装备是scope特点则其默许为singleton),此时结构函数是在解析xml的时分就进行调用了,所以Bean的创立也是在这个时分进行的,并非是在调用getBean办法时创立。能够在测验类只保留ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spirng-instance.xml");进行验证。

2. 经过简略工厂形式实例化

简略工厂形式是工厂办法的一种特别完成,简略工厂形式由三个人物组成:工厂类人物、笼统产品人物、详细产品人物。
①编写简略工厂形式傍边的工厂类,这儿边需求留意的是获取Bean的办法必须是静态的

public class SpringBeanSimpleFactory {
    public static SpringBean getSpringbean(){ //必须是静态办法
        return new SpringBean();
    }
}

②在Spring装备文件中指定创立该Bean的办法(运用factory-method特点指定),其实便是告知Spring结构,调用该办法能够获取到Bean。

<bean id="getSpirngBean1" class="com.qiuye.beanInstance.factory.SpringBeanSimpleFactory" factory-method="getSpringbean"/>

③编写测验程序

public void test() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spirng-instance.xml");
    SpringBean springBean = applicationContext.getBean("getSpirngBean1",SpringBean.class);
    System.out.println(springBean);
    System.out.println(springBean.getA());
}

履行成果:

Spring之Bean实例化的四种方式

3. 经过工厂办法形式实例化

工厂办法形式有笼统/详细工厂、笼统/详细产品四个人物,这儿主要运用详细工厂和详细产品人物。

①界说详细工厂类,工厂类中界说实例办法

public class SpringBeanFactory {
    public SpringBean getSpringBean(){
        return new SpringBean();
    }
}

②在Spring装备文件中指定factory-bean(指定工厂类)以及factory-method(指定工厂类的办法),其实便是告知spring从哪个工厂Bean的那个办法获取到需求的Bean。

<bean id="springBeanFactory" class="com.qiuye.beanInstance.factory.SpringBeanFactory"></bean>
<bean id="getSpirngBean2" factory-bean="springBeanFactory" factory-method="getSpringBean"/>

③编写测验程序

public void test3() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-instance.xml");
    SpringBean springBean = applicationContext.getBean("getSpirngBean2",SpringBean.class);
    System.out.println(springBean);
}

履行成果:

Spring之Bean实例化的四种方式

4. 经过FactoryBean接口实例化

经过工厂办法形式进行实例化时,factory-bean是咱们自界说的,factory-method也是咱们自己界说的。 在Spring中,供给了FactoryBean接口,完成该接口之后factory-bean不需求指定了,factory-method也不需求指定了。factory-bean会主动指向完成FactoryBean接口的类,factory-method会主动指向getObject()办法。以下是FactoryBean的源码

public interface FactoryBean<T> {
   String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
   @Nullable
   T getObject() throws Exception;
   @Nullable
   Class<?> getObjectType();
   default boolean isSingleton() { //默许办法,判断是否是单例,默许回来true
      return true;
   }

①编写一个类完成FactoryBean接口

public class SpringBeanFactoryImpl implements FactoryBean<SpringBean> {
    @Override
    public SpringBean getObject() throws Exception {
        return new SpringBean();
    }
    @Override
    public Class<?> getObjectType() {
        return null;
    }
    @Override
    public boolean isSingleton() { //该办法在需求转换作用域时重写。默许调用接口的默许办法
        return FactoryBean.super.isSingleton(); 
    }
}

②在Spring装备文件中装备FactoryBean

<bean id="getSpirngBean3" class="com.qiuye.beanInstance.factory.SpringBeanFactoryImpl"/>

测验程序:

public void test3() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-instance.xml");
    SpringBean springBean = applicationContext.getBean("getSpirngBean3",SpringBean.class);
    System.out.println(springBean);
}

履行成果

Spring之Bean实例化的四种方式

FactoryBean在Spring中是一个接口。被称为“工厂Bean”。“工厂Bean”是一种特别的Bean。一切的“工厂Bean”都是用来帮忙Spring结构来创立其他Bean目标的。
工厂的责任是生产和加工,咱们能够用一个例子来体验一下工厂的加工责任。java.util.Date在Spring中被作为简略类型,简略类型在注入的时分能够直接运用value特点或value标签来完成。但咱们之前已经测验过了,对于Date类型来说,采用value特点或value标签赋值的时分,对日期字符串的格局要求非常严格,必须是这种格局的:Mon Oct 10 14:30:26 CST 2022。其他格局是不会被识别的。咱们习惯的字符串类型是“yyyy-MM-dd”这样的,或许其他的形式。代码如下:
①编写一个Student类

public class Student { //界说Student类,有Date类型的特点
    private String name;
    private Date birth;
    public String getName() {return name}
    public void setName(String name) {this.name = name;}
    public Date getBirth() {return birth;}
    public void setBirth(Date birth) {this.birth = birth;}
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + ''' +
                ", birth=" + birth +
                '}';
    }
}

②创立Date类型的工厂Bean

public class DateFactory implements FactoryBean<Date> { //界说Date的工厂Bean
    private String dataStr;
    public void setDataStr(String dataStr) {
        this.dataStr = dataStr;
    }
    @Override
    public Date getObject() throws Exception { //在这儿对Date类型进行处理
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = simpleDateFormat.parse(dataStr);
        return date;
    }
    @Override
    public Class<?> getObjectType() {
        return null;
    }
}

③编写XML装备 这儿便是运用Date的工厂Bean对Date类型进行处理,然后再注入到Student类型里

<bean id="date" class="com.qiuye.beanInstance.factory.DateFactory">
    <property name="dataStr" value="1998-01-01"/>
</bean>
<bean id="Student" class="com.qiuye.beanInstance.entity.Student">
    <property name="birth" ref="date"/>
    <property name="name" value="qy"/>
</bean>

④测验

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

Spring之Bean实例化的四种方式

5.BeanFactory和FactoryBean的差异

5.1 BeanFactory

Spring IoC容器的尖端目标,BeanFactory被翻译为“Bean工厂”,在Spring的IoC容器中,“Bean工厂”担任创立Bean目标。BeanFactory是工厂。

5.2 FactoryBean

FactoryBean:它是一个Bean,是一个能够辅佐Spring实例化其它Bean目标的一个Bean。

在Spring中,Bean能够分为两类:

  • 第一类:普通Bean
  • 第二类:工厂Bean(留意:工厂Bean也是一种Bean,只不过这种Bean比较特别,它能够辅佐Spring实例化其它Bean目标。)