Spring为Bean提供了多种实例化方式,通常包括4种方式。(也就是说在Spring中为Bean对象的创建准备了多种方案,目的是:更加灵活)
factory-bean实例化FactoryBean接口实例化
<bean class="com.cjf.bean.SpringBean" id="bean"/>
public class Star {
public Star() {
System.out.println("Star的无参数构造方法执行");
}
}
//明星工厂
public class StarFactory {
public static Star get() {
//这个Star对象实际上是我们负责new的对象
return new Star();
}
}
<bean id="star" class="com.cjf.bean.StarFactory" factory-method="get"/>
具体的Gun
public class Gun extends Mechanical{
public Gun() {
System.out.println("Gun的无参数构造方法执行");
}
}
抽象的 MechanicalFactory ,都是一种产品:机械产品
public abstract class MechanicalFactory {
protected abstract Mechanical get();
}
具体的GunFactory
public class GunFactory extends MechanicalFactory {
@Override
protected Mechanical get() {
return new Gun();
}
}
<bean id="gunFactory" class="com.cjf.bean.GunFactory"/>
<bean id="gun" factory-bean="gunFactory" factory-method="get"/>
以上的第三种方式中,factory-bean是我们自定义的,factory-method也是我们自己定义的。
在Spring中,当你编写的类直接实现FactoryBean接口之后,factory-bean不需要指定了,factory-method也不需要指定了。
factory-bean会自动指向实现FactoryBean接口的类,factory-method会自动指向getObject()方法。
public class PersonFactoryBean implements FactoryBean<Person> {
// PersonFactoryBean 也是一个Bean,只不过通过这个Bean比较特殊,叫做工厂Bean
@Override
public Person getObject() throws Exception {
return new Person();
}
@Override
public Class<?> getObjectType() {
return null;
}
/**
* 接口默认返回ture,表示单例的
* 如果 多例,直接修改为return false 即可
*/
@Override
public boolean isSingleton() {
return FactoryBean.super.isSingleton();
}
}
<bean id="person" class="com.cjf.bean.PersonFactoryBean"/>
Spring IoC容器的顶级对象,BeanFactory被翻译为“Bean工厂”,在Spring的IoC容器中,“Bean工厂”负责创建Bean对象。
BeanFactory是工厂。
@Test
public void testCustomScope(){
//ApplicationContext applicationContext =
// new ClassPathXmlApplicationContext("spring.xml");
BeanFatory applicationContext =
new ClassPathXmlApplicationContext("spring.xml");
}
FactoryBean:它是一个Bean,是一个能够辅助Spring实例化其它Bean对象的一个Bean。
在Spring中,Bean可以分为两类:
BeanBean(记住:工厂Bean也是一种Bean,只不过这种Bean比较特殊,它可以辅助Spring实例化其它Bean对象。)public class Student {
// java.util.Date 在spring当中被当做简单类型。但是简单类型的话,注入的日期字符串格式有要求。
// java.util.Date 在rSpring当中出可以被当做非简单类型。
private Date birth;
public void setBirth(Date birth) {
this.birth = birth;
}
@Override
public String toString() {
return "Student{" +
"birth=" + birth +
'}';
}
}
我们前面说过,java.util.Date在Spring中被当做简单类型,简单类型在注入的时候可以直接使用value属性或value标签来完成。但我们 之前已经测试过了,对于Date类型来说,采用value属性或value标签赋值的时候,对日期字符串的格式要求非常严格,必须是这种格式的:Mon Oct 10 14:30:26 CST 2022。其他格式是不会被识别的。如以下代码:
<bean id="student" class="com.cjf.bean.Student">
<property name="birth" value="Mon Oct 10 14:30:26 CST 2022"/>
bean>
<bean class="java.util.Date" id="nowTime">bean>
<bean id="student" class="com.cjf.bean.Student">
<property name="birth" ref="nowTime">property>
bean>
解决
public class DateFactoryBean implements FactoryBean<Date> {
//DateFactoryBean 这个工厂协助我们Spring创建这个普通的Date
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;
}
}
<bean id="date" class="com.cjf.bean.DateFactoryBean" >
<constructor-arg index="0" value="2002-6-11"/>
bean>
<bean id="student" class="com.cjf.bean.Student">
<property name="birth" ref="date"/>
bean>