Spring
- Bean的实例化方式
- 通过构造方法实例化
- 通过简单工厂模式实例化
- 通过工厂方法模式实例化
- 通过FactoryBean接口实例化
- 注入自定义Date
- Bean的生命周期
- Bean的循环依赖问题
Bean的实例化方式
Spring为Bean提供了多种实例化方式,通常包括4种方式。(也就是说在Spring中为Bean对象的创建准备了多种方案,目的是:更加灵活)
第一种:通过构造方法实例化
第二种:通过简单工厂模式实例化
第三种:通过factory-bean实例化
第四种:通过FactoryBean接口实例化
通过构造方法实例化
默认情况下,会调用Bean的无参数构造方法
通过简单工厂模式实例化
新建spring-Bean模块用来写本节代码
第一步:定义一个Bean
Vip.java
package com.w.spring6.bean;
public class Vip {
}
第二步:编写简单工厂模式当中的工厂类
VipFactory.java
package com.w.spring6.bean;
public class VipFactory {
public static Vip get(){
return new Vip();
}
}
第三步:在Spring配置文件中指定创建该Bean的方法(使用factory-method属性指定)
spring.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>
第四步:编写测试程序
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
package com.w.spring6.bean1;
public class Order {
}
第二步:定义具体工厂类,工厂类中定义实例方法
OrderFactory.java
package com.w.spring6.bean1;
public class OrderFactory {
public Order get(){
return new Order();
}
}
第三步:在Spring配置文件中指定factory-bean以及factory-method
<bean id="orderFactory" class="com.w.spring6.bean1.OrderFactory"/>
<bean id="orderBean" factory-bean="orderFactory" factory-method="get"/>
第四步:编写测试程序
@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
package com.w.spring6.bean2;
public class Person {
}
第二步:编写一个类实现FactoryBean接口
PersonFactoryBean.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
<bean id="personBean" class="com.w.spring6.bean2.PersonFactoryBean"/>
第四步:编写测试程序
@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
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
<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>
测试程序:
@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
package com.w.spring6.BeanCircularDependency;
public class Husband {
private String name;
private Wife wife;
}
Wife.java
package com.w.spring6.BeanCircularDependency;
public class Wife {
private String name;
private Husband husband;
}