这篇“Spring Bean实例化方式怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Spring Bean实例化方式怎么实现”文章吧。
Spring为Bean提供了多种实例化方式,通常包括4种方式。(也就是说在Spring中为Bean对象的创建准备了多种方案,目的是:更加灵活)
第一种:通过构造方法实例化
第二种:通过简单工厂模式实例化
第三种:通过factory-bean实例化(工厂方法模式)
第四种:通过FactoryBean接口实例化
1.通过构造方法实例化
我们之前一直使用的就是这种方式!默认情况下,会调用Bean的无参数构造方法,这里在复习一遍!
SpringBean类
package com.bjpowernode.spring.bean;public class SpringBean { public SpringBean() { System.out.println("SpringBean的无参数构造方法执行了"); }}
spring.xml配置
第一种:在spring配置文件中直接配置类全路径,Spring会自动调用该类的无参数构造方法来实例化Bean!
<?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"> <!--Spring提供的实例化方式,第一种--> <bean id="sb" class="com.bjpowernode.spring.bean.SpringBean"/></beans>
BeanInstantiationTest测试类
package com.bjpowernode.spring.test;import com.bjpowernode.spring.bean.SpringBean;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanInstantiationTest { @Test public void tesInstantiation1(){ ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml"); SpringBean sb = applicationContext.getBean("sb", SpringBean.class); System.out.println(sb); }}
执行结果:成功调用无参数构造方法实例化对象
2.通过简单工厂模式实例化
简单工厂模式又叫做静态工厂方法模式,因为工厂类中有一个静态方法!
定义一个Bean
package com.bjpowernode.spring.bean;public class Vip { public Vip() { System.out.println("我是一个Vip"); }}
编写简单工厂模式当中的工厂类
package com.bjpowernode.spring.bean;public class VipFactory { // 里面有一个静态方法 public static Vip get(){ // 实际上对象的创建还是我们程序员自己完成的 return new Vip(); }}
在Spring配置文件中指定创建该Bean的方法
第二种:通过简单工厂模式。
需要在Spring配置文件中告诉Spring框架,调用哪个类的哪个方法获取Bean?
①class属性指定的是工厂类的全限定类名!
②factory-method属性指定的是工厂类当中的静态方法,也就是告诉Spring框架,调用这个方法可以获取Bean!
<?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"> <!--Spring提供的实例化方式,第二种--> <bean id="vipBean" class="com.bjpowernode.spring.bean.VipFactory" factory-method="get"/></beans>
编写测试程序
package com.bjpowernode.spring.test;import com.bjpowernode.spring.bean.SpringBean;import com.bjpowernode.spring.bean.Vip;import com.bjpowernode.spring.bean.VipFactory;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanInstantiationTest { @Test public void tesInstantiation2(){ ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml"); Object vipBean = applicationContext.getBean("vipBean", Vip.class); System.out.println(vipBean); }}
执行结果:通过简单工厂模式也能实例化对象
3.通过factory-bean实例化
本质上是:通过工厂方法模式进行实例化对象!
注:简单工厂模式和工厂方法模式的区别
①简单工厂模式是所有的产品对应一个工厂类,使用的是静态方法!
②工厂方法模式是一个产品对应一个工厂类,使用的是实例方法!
定义一个Bean
package com.bjpowernode.spring.bean;// 工厂方法模式当中的:具体产品角色public class Gun { public Gun() { System.out.println("Gun的无参数构造方法执行"); }}
定义具体工厂类,工厂类中定义实例方法
package com.bjpowernode.spring.bean;// 工厂方法模式当中:的具体工厂角色public class GunFactory { // 实例方法 public Gun get(){ // 还是我们自己new的对象 return new Gun(); }}
在Spring配置文件中指定factory-bean以及factory-method
第三种:通过工厂方法模式。
通过 factory-bean属性 + factory-method属性来共同完成。告诉Spring框架,调用哪个对象(因为是实例方法需要创建对象)的哪个方法来获取Bean。
①factory-bean属性用来告诉Spring调用那个对象!
②factory-method属性用来告诉Spring调用该对象的那个方法!
<?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"> <!--Spring提供的实例化方式,第三种--> <bean id="gunBean" class="com.bjpowernode.spring.bean.GunFactory"/> <bean id="gun" factory-bean="gunBean" factory-method="get"/> </beans>
编写测试程序
package com.bjpowernode.spring.test;import com.bjpowernode.spring.bean.Gun;import com.bjpowernode.spring.bean.SpringBean;import com.bjpowernode.spring.bean.Vip;import com.bjpowernode.spring.bean.VipFactory;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanInstantiationTest { @Test public void tesInstantiation3(){ ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml"); Gun gun = applicationContext.getBean("gun", Gun.class); System.out.println(gun); }}
执行结果:通过工厂方法模式也能实例化对象
4.通过FactoryBean接口实例化
①在第三种方式中,factory-bean和factory-method都是我们自己定义的。
②在Spring中,当编写的类直接实现FactoryBean接口之后,factory-bean和factory-method就不需要指定了!factory-bean会自动指向实现FactoryBean接口的类,factory-method会自动指向getObject()方法!
定义一个Bean
package com.bjpowernode.spring.bean;public class Person { public Person() { System.out.println("Person的无参数构造方法执行了"); }}
编写一个类实现FactoryBean接口,重写里面的方法
PersonFactory也是一个Bean,只不过这个Bean比较特殊,叫做工厂Bean。通过工厂Bean这个特殊的Bean可以获取一个普通的Bean!
package com.bjpowernode.spring.bean;import org.springframework.beans.factory.FactoryBean;public class PersonFactory implements FactoryBean<Person> { @Override public Person getObject() throws Exception { // 对象的创建也是自己new的 return new Person(); } @Override public Class<?> getObjectType() { return null; } @Override public boolean isSingleton() { // 这个方法是默认存在的,true表示单例,false表示原型 return true; }}
在Spring配置文件中配置FactoryBean
第四种:通过FactoryBean接口来实现,这种方式实际上就是第三种方式的简化!
①由于你编写的类实现了FactoryBean接口,所以这个类是一个特殊的类,不需要你再手动指定:factory-bean、factory-method。 ②通过一个特殊的Bean:工厂Bean,来返回一个普通的Bean Person对象。即通过FactoryBean这个工厂Bean主要是想对普通Bean进行加工处理!
<?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"> <!--Spring提供的实例化方式,第四种--> <bean id="person" class="com.bjpowernode.spring.bean.PersonFactory" /></beans>
编写测试程序
package com.bjpowernode.spring.test;import com.bjpowernode.spring.bean.*;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanInstantiationTest { @Test public void tesInstantiation4(){ ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml"); Person person = applicationContext.getBean("person", Person.class); System.out.println(person); }}
执行结果:通过FactoryBean接口实例化
注:FactoryBean在Spring中是一个接口,被称为“工厂Bean”。“工厂Bean”是一种特殊的Bean,所有的“工厂Bean”都是用来协助Spring框架来创建其他Bean对象的!
5.BeanFactory和FactoryBean的区别-面试题
(1)BeanFactory(是一个工厂)
BeanFactory是Spring IoC容器的顶级对象,BeanFactory被翻译为“Bean工厂”,在Spring的IoC容器中,“Bean工厂”负责创建Bean对象!
(2)FactoryBean(是一个Bean)
FactoryBean是一个Bean,是一个能够辅助Spring实例化其它Bean对象的一个Bean!
在Spring中,Bean可以分为两类:
第一类:普通Bean
第二类:工厂Bean(工厂Bean也是一种Bean,只不过这种Bean比较特殊,它可以辅助Spring实例化其它Bean对象)
6.使用FactoryBean注入自定义Date
①前面我们说过,java.util.Date在Spring中被当做简单类型,简单类型在注入的时候可以直接使用value属性或value标签来完成。
②但是之前我们已经测试过了,对于Date类型来说,采用value属性或value标签赋值的时候,对日期字符串的格式要求非常严格,必须是这种格式的:Mon Oct 10 14:30:26 CST 2022,其他格式是不会被识别的!
③当然我们也可以当成非简单类型处理,使用ref属性来处理,但是却有一个弊端,获取的都是当前的时间,并不能自己指定时间!
注:下面我们就使用FactoryBean来完成这个骚操作!
Student类
package com.bjpowernode.spring.bean;import java.util.Date;public class Student { // 每个学生都有出生日期 private Date birth; @Override public String toString() { return "Student{" + "birth=" + birth + '}'; } public void setBirth(Date birth) { this.birth = birth; }}
编写DateFactory实现FactoryBean接口
package com.bjpowernode.spring.bean;import org.springframework.beans.factory.FactoryBean;import java.text.SimpleDateFormat;import java.util.Date;public class DateFactory implements FactoryBean<Date> { // 定义一个日期属性,用来处理传过来的日期字符串 private String date; // 通过构造方法给日期字符串属性赋值 public DateFactory(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配置文件
<?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"> <!--通过这个类的构造方法,把字符串转换成Date--> <bean id="date" class="com.bjpowernode.spring.bean.DateFactory"> <constructor-arg name="date" value="1999-01-14"/> </bean> <!--把上面的Date通过上面的类,使用ref属性引进来--> <bean id="studentBean" class="com.bjpowernode.spring.bean.Student"> <property name="birth" ref="date"/> </bean></beans>
编写测试程序
package com.bjpowernode.spring.test;import com.bjpowernode.spring.bean.*;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanInstantiationTest { @Test public void testDate(){ ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml"); Student studentBean = applicationContext.getBean("studentBean", Student.class); System.out.println(studentBean); }}
执行结果
以上就是关于“Spring Bean实例化方式怎么实现”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。