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的作用域默许是单例(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());
}
履行成果:
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);
}
履行成果:
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);
}
履行成果
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);
}
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目标。)