Spring中Bean实例化方式和Bean生命周期

Spring


Bean的实例化方式

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

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

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

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

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

通过构造方法实例化

默认情况下,会调用Bean的无参数构造方法

通过简单工厂模式实例化

新建spring-Bean模块用来写本节代码

第一步:定义一个Bean

Vip.java

java 复制代码
package com.w.spring6.bean;

public class Vip {
}

第二步:编写简单工厂模式当中的工厂类

VipFactory.java

java 复制代码
package com.w.spring6.bean;

public class VipFactory {
    public static Vip get(){
        return new Vip();
    }
}

第三步:在Spring配置文件中指定创建该Bean的方法(使用factory-method属性指定)

spring.xml

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="vipBean" class="com.w.spring6.bean.VipFactory" factory-method="get"/>
    
</beans>

第四步:编写测试程序

java 复制代码
package com.w.spring.test;

import com.w.spring6.bean.Vip;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringBeanTest {
    @Test
    public void testSimpleFactory(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Vip vip = applicationContext.getBean("vipBean", Vip.class);
        System.out.println(vip);
    }
}

运行结果:

通过工厂方法模式实例化

第一步:定义一个Bean

Order.java

java 复制代码
package com.w.spring6.bean1;

public class Order {
}

第二步:定义具体工厂类,工厂类中定义实例方法

OrderFactory.java

java 复制代码
package com.w.spring6.bean1;

public class OrderFactory {
    public Order get(){
        return new Order();
    }
}

第三步:在Spring配置文件中指定factory-bean以及factory-method

xml 复制代码
    <bean id="orderFactory" class="com.w.spring6.bean1.OrderFactory"/>
    <bean id="orderBean" factory-bean="orderFactory" factory-method="get"/>

第四步:编写测试程序

java 复制代码
@Test
public void testSelfFactoryBean(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    Order orderBean = applicationContext.getBean("orderBean", Order.class);
    System.out.println(orderBean);
}

运行结果:

通过FactoryBean接口实例化

FactoryBean在Spring中是一个接口,用来协助Spring框架来创建其他Bean对象的。

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

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

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

第一步:定义一个Bean

Person.java

java 复制代码
package com.w.spring6.bean2;

public class Person {
}

第二步:编写一个类实现FactoryBean接口

PersonFactoryBean.java

java 复制代码
package com.w.spring6.bean2;

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

第三步:在Spring配置文件中配置FactoryBean

spring.xml

xml 复制代码
    <bean id="personBean" class="com.w.spring6.bean2.PersonFactoryBean"/>

第四步:编写测试程序

java 复制代码
@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);
}

运行结果:

注入自定义Date

简单类型在注入的时候可以直接使用value属性或value标签来完成,但对于Date类型来说,采用value属性或value标签赋值的时候,对日期字符串的格式要求非常严格,必须是这种格式的:Mon Oct 10 14:30:26 CST 2022。其他格式是不会被识别的。

这种情况下,我们就可以使用FactoryBean来完成其他格式。

编写DateFactoryBean实现FactoryBean接口:

DateFactoryBean.java

java 复制代码
package com.w.spring6.test;


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

编写spring配置文件:

spring.xml

xml 复制代码
    <bean id="userBean" class="com.w.spring6.test.User">
        <property name="birth" ref="dateBean"/>
    </bean>

    <bean id="dateBean" class="com.w.spring6.test.DateFactoryBean">
        <constructor-arg name="date" value="2023-11-11"/>
    </bean>

测试程序:

java 复制代码
    @Test
    public void testDate(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        User userBean = applicationContext.getBean("userBean", User.class);
        System.out.println(userBean);
    }

运行结果:

Bean的生命周期

Bean生命周期可以粗略的划分为五大步:

  • 第一步:实例化Bean
  • 第二步:Bean属性赋值
  • 第三步:初始化Bean
  • 第四步:使用Bean
  • 第五步:销毁Bean

Bean的循环依赖问题

循环依赖:A对象中有B属性。B对象中有A属性。我依赖你,你也依赖我。

例:

Husband.java

java 复制代码
package com.w.spring6.BeanCircularDependency;

public class Husband {
    private String name;
    private Wife wife;
}

Wife.java

java 复制代码
package com.w.spring6.BeanCircularDependency;

public class Wife {
    private String name;
    private Husband husband;
}
相关推荐
白子寰2 分钟前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
王俊山IT15 分钟前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
为将者,自当识天晓地。17 分钟前
c++多线程
java·开发语言
小政爱学习!19 分钟前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
daqinzl25 分钟前
java获取机器ip、mac
java·mac·ip
k093334 分钟前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
激流丶40 分钟前
【Kafka 实战】如何解决Kafka Topic数量过多带来的性能问题?
java·大数据·kafka·topic
神奇夜光杯42 分钟前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
Themberfue44 分钟前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
plmm烟酒僧1 小时前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv