spring创建bean过程,spring框架创建bean的方式

  spring创建bean过程,spring框架创建bean的方式

  

目录
前言环境通过豆的班级属性创建实例(带参构造器)工厂方法(静态工厂方法)工厂方法(实例工厂方法)工厂豆总结

  

前言

Spring常见的创建bean实例的方式有:

  1.通过豆的班级属性创建实例

  无参构造器带参构造器2.工厂方法

  静态工厂方法实例工厂方法3.工厂豆

  关于每种方式的春天配置,详见文末总结。

  

环境

Ubuntu 22.04 intellij IDEA 2022。1 .3 JDK 17。0 .3春5。3 .21准备创建专家项目测试0705 .

  修改 pom.xml 文件,添加依赖:

  .-https://mvn repository.com/artifact/JUnit/JUnit-依赖关系groupId JUnit/groupId artifact id JUnit/artifact id版本4 .13 .2/版本scope test/scope/dependence!-https://mvn存储库。com/artifact/org。spring框架/spring-web MVC-依赖groupIdorg.springframework/groupId artifact id版本5 . 3 . 21/版本/依赖性.在资源中心/主要/资源目录下创建应用程序上下文.可扩展标记语言文件:

  ?可扩展标记语言版本=1.0 编码=utf-8 ?豆子xmlns= http://www。spring框架。org/schema/beans xmlns : xsi= http://www。w3。org/2001/XML schema-instance xsi :架构位置= http://www。spring框架。org/schema/beans http://www。spring框架。org/schema/beans/beans/spring-beans。xsd /bean在src/test/java目录下创建测试:

  公共类Test0705 {}通过豆的班级属性创建实例(无参构造器)

  注:这是最常见的创建豆的方式。我其它文档也用过相似代码。如果已熟悉可直接略过。

  创建如下POJO:

  斧头:斧头接口;石斧:斧头实现类;钢斧:斧头实现类;人:人持有斧头;包持久化类公共接口axe { public void chop();}包持久化类公共类石斧实现斧子{公共石斧(){系统。出去。println(石斧构造者);} @覆盖public void chop(){ system。出去。println(石斧!);}}

  s="brush:java;">package pojo;public class SteelAxe implements Axe{ public SteelAxe() { System.out.println("SteelAxe constructor"); } @Override public void chop() { System.out.println("Steel axe!"); }}

package pojo;public class Person { private String name; private Axe axe; public void setAxe(Axe axe) { this.axe = axe; } public void setName(String name) { this.name = name; } public Person() { System.out.println("Person constructor"); } public void useAxe() { System.out.println("I am " + name); axe.chop(); }}
applicationContext.xml 中注册bean:

  

 ...... <bean id="stoneAxe" class="pojo.StoneAxe"/> <bean id="steelAxe" class="pojo.SteelAxe"/> <bean id="person" class="pojo.Person"> <property name="name" value="Tom"/> <property name="axe" ref="stoneAxe"/> </bean> ......
创建测试用例:

  

 @Test public void test1() { var ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); System.out.println("before getBean person"); var person = ctx.getBean("person", Person.class); person.useAxe(); }
运行测试,如下:

  

StoneAxe constructorSteelAxe constructorPerson constructorbefore getBean personI am TomStone axe!

  

通过bean的class属性创建实例(带参构造器)

注:这是较为常见的创建bean的方式。我其它文档也用过相似代码。如果已熟悉可直接略过。

  

创建如下POJO:

  Book :Book接口;PlayBook :Book实现类;StudyBook :Book实现类;Student :Student持有Book;

package pojo;public interface Book { public void show();}
package pojo;public class PlayBook implements Book{ public PlayBook() { System.out.println("PlayBook constructor"); } @Override public void show() { System.out.println("Play book!"); }}
package pojo;public class StudyBook implements Book{ public StudyBook() { System.out.println("StudyBook constructor"); } @Override public void show() { System.out.println("Study book!"); }}
package pojo;public class Student { private String name; private Book book; public Student(String name, Book book) { System.out.println("Student constructor"); this.name = name; this.book = book; } public void readBook() { System.out.println("I am " + name); book.show(); }}
applicationContext.xml 中注册bean:

  

 ...... <bean id="playBook" class="pojo.PlayBook"/> <bean id="studyBook" class="pojo.StudyBook"/> <bean id="student" class="pojo.Student"> <constructor-arg index="0" value="Jerry"/> <constructor-arg index="1" ref="playBook"/> </bean> ......
创建测试用例:

  

 @Test public void test2() { var ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); System.out.println("before getBean student"); var student = ctx.getBean("student", Student.class); student.readBook(); }
运行测试,如下:

  

......PlayBook constructorStudyBook constructorStudent constructorbefore getBean studentI am JerryPlay book!

  

  

工厂方法(静态工厂方法)

配置:

  class 属性指向静态工厂类factory-method 属性指向静态工厂方法注:如果静态工厂方法需要参数,则通过 constructor-arg 来指定。

  例如:

  

 <bean id="dog" class="factory.AnimalFactory" factory-method="getAnimal"> <constructor-arg value="dog"/> <property name="name" value="Snoopy"/> </bean>
当调用 ctx.getBean("dog") 时,Spring会调用 AnimalFactory 类的静态方法 getAnimal() ,并传入参数 "dog",创建一个Animal的实例并返回。

  注:同普通的bean一样,其默认scope是 singleton ,多次调用 ctx.getBean("dog") 返回的是同一个实例(在Spring初始化时生产bean)。

  完整例子如下:

  创建如下POJO:

  Animal :Animal接口;Dog :Animal实现类;Cat :Animal实现类;

package pojo;public interface Animal { public void cry();}
package pojo;public class Dog implements Animal{ private String name; public void setName(String name) { this.name = name; } public Dog() { System.out.println("Dog constructor"); } @Override public void cry() { System.out.println("I am " + name); System.out.println("Wang wang..."); }}
package pojo;public class Cat implements Animal{ private String name; public void setName(String name) { this.name = name; } public Cat() { System.out.println("Cat constructor"); } @Override public void cry() { System.out.println("I am " + name); System.out.println("Miao Miao..."); }}
创建工厂类 AnimalFactory

  

package factory;import pojo.Animal;import pojo.Cat;import pojo.Dog;public class AnimalFactory { public static Animal getAnimal(String type) { System.out.println("creating new Animal object"); if (type.equalsIgnoreCase("dog")) { return new Dog(); } else if (type.equalsIgnoreCase("cat")) { return new Cat(); } else { return null; } }}
applicationContext.xml 中注册bean:

  

 <bean id="dog" class="factory.AnimalFactory" factory-method="getAnimal"> <constructor-arg value="dog"/> <property name="name" value="Snoopy"/> </bean> <bean id="cat" class="factory.AnimalFactory" factory-method="getAnimal"> <constructor-arg value="cat"/> <property name="name" value="Kitty"/> </bean>
创建测试用例:

  

 @Test public void test3() { var ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); System.out.println("before getBean dog cat"); var animal1 = ctx.getBean("dog", Animal.class); animal1.cry(); var animal2 = ctx.getBean("cat", Animal.class); animal2.cry(); }
运行测试,如下:

  

creating new Animal objectDog constructorcreating new Animal objectCat constructorbefore getBean dog catI am SnoopyWang wang...I am KittyMiao Miao...

  

  

工厂方法(实例工厂方法)

实例工厂方法跟静态工厂方法很相像,主要区别是:

  静态工厂方法:不用实例化工厂,只需直接调用工厂类的静态工厂方法;实例工厂方法:工厂方法不是静态的,因此需要通过 factory-bean 来指定工厂类的实例。比如:

  

 <bean id="fruitFactory" class="factory.FruitFactory"/> <bean id="apple" factory-bean="fruitFactory" factory-method="getFruit"> <constructor-arg value="apple"/> <property name="name" value="Fuji"/> </bean>
其它都一样。

  完整例子如下:

  创建如下POJO:

  Fruit :Fruit接口;Apple :Fruit实现类;Banana :Fruit实现类;

package pojo;public interface Fruit { public void describe();}
package pojo;public class Apple implements Fruit { private String name; public void setName(String name) { this.name = name; } public Apple() { System.out.println("Apple constructor"); } @Override public void describe() { System.out.println("I am " + name); System.out.println("Juicy!"); }}
package pojo;public class Banana implements Fruit { private String name; public void setName(String name) { this.name = name; } public Banana() { System.out.println("Banana constructor"); } @Override public void describe() { System.out.println("I am " + name); System.out.println("Sweet!"); }}
创建工厂类 FruitFactory

  

package factory;import pojo.Apple;import pojo.Banana;import pojo.Fruit;public class FruitFactory { public Fruit getFruit(String type) { System.out.println("creating new Fruit object"); if (type.equalsIgnoreCase("apple")) { return new Apple(); } else if (type.equalsIgnoreCase("banana")) { return new Banana(); } else { return null; } }}
applicationContext.xml 中注册bean:

  

 ...... <bean id="fruitFactory" class="factory.FruitFactory"/> <bean id="apple" factory-bean="fruitFactory" factory-method="getFruit"> <constructor-arg value="apple"/> <property name="name" value="Fuji"/> </bean> <bean id="banana" factory-bean="fruitFactory" factory-method="getFruit"> <constructor-arg value="banana"/> <property name="name" value="Pisang"/> </bean> ......
创建测试用例:

  

 @Test public void test4() { var ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); System.out.println("before getBean apple banana"); var fruit1 = ctx.getBean("apple", Fruit.class); fruit1.describe(); var fruit2 = ctx.getBean("banana", Fruit.class); fruit2.describe(); }
运行测试,如下:

  

creating new Fruit objectApple constructorcreating new Fruit objectBanana constructorbefore getBean apple bananaI am FujiJuicy!I am PisangSweet!

  

  

工厂bean

工厂bean是指实现了 FactoryBean 接口的类。

  FactoryBean 接口有3个方法:

  T getObject() throws :创建产品实例;Class<?> getObjectType() :获取产品的类;default boolean isSingleton() {return true;} :是否单例,默认值为true;实现 FactoryBean 接口,则无需再配置 factory-method ,Spring知道如何创建产品(通过 getObject() 方法)。

  比如:

  

 <bean id="benz" class="factory.CarFactoryBean"> <property name="type" value="benz"/> </bean>
注意:该配置看起来很像普通的bean,实际上因为 CarFactoryBean 实现了 FactoryBean 接口,当调用 ctx.getBean("benz") 方法时,返回的并不是 CarFactoryBean 的实例,而是其 getObject() 方法的返回值。

  注:默认scope是 singleton ,多次调用 ctx.getBean("dog") 返回的是同一个实例。如果在 CarFactoryBean 中override isSingleton() 方法并返回false,则每次调用ctx.getBean("benz") 返回的是不同对象。

  注:工厂bean跟其它bean有一点不同,即使是singleton,它也不是在Spring初始化时生产bean,而是在第一次调用 ctx.getBean() 时才生产bean。

  完整例子如下:

  创建如下POJO:

  Car :Car接口;Benz :Car实现类;Audi :Car实现类;

package pojo;public interface Car { public void run();}
package pojo;public class Benz implements Car{ public Benz() { System.out.println("Benz constructor"); } @Override public void run() { System.out.println("Go go go!"); }}
package pojo;public class Audi implements Car{ public Audi() { System.out.println("Audi constructor"); } @Override public void run() { System.out.println("OOOO"); }}
创建工厂类 FactoryBean

  

package factory;import org.springframework.beans.factory.FactoryBean;import pojo.Audi;import pojo.Benz;import pojo.Car;public class CarFactoryBean implements FactoryBean { private String type; public void setType(String type) { this.type = type; } @Override public Object getObject() throws Exception { System.out.println("creating new Car object"); if (type.equalsIgnoreCase("benz")) { return new Benz(); } else if (type.equalsIgnoreCase("audi")) { return new Audi(); } else return null; } @Override public Class<?> getObjectType() { return Car.class; }}
applicationContext.xml 中注册bean:

  

 ...... <bean id="benz" class="factory.CarFactoryBean"> <property name="type" value="benz"/> </bean> <bean id="audi" class="factory.CarFactoryBean"> <property name="type" value="audi"/> </bean> ......
创建测试用例:

  

 @Test public void test5() { var ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); System.out.println("before getBean benz audi"); var car1 = ctx.getBean("benz", Car.class); car1.run(); var car2 = ctx.getBean("audi", Car.class); car2.run(); }
运行测试,如下:

  

before getBean benz audicreating new Car objectBenz constructorGo go go!creating new Car objectAudi constructorOOOO

  

  

总结

 ...... <!-- 通过bean的class属性创建bean实例(无参构造器) --> <bean id="stoneAxe" class="pojo.StoneAxe"/> <bean id="steelAxe" class="pojo.SteelAxe"/> <bean id="person" class="pojo.Person"> <property name="name" value="Tom"/> <property name="axe" ref="stoneAxe"/> </bean> <!-- 通过bean的class属性创建bean实例(带参构造器) --> <bean id="playBook" class="pojo.PlayBook"/> <bean id="studyBook" class="pojo.StudyBook"/> <bean id="student" class="pojo.Student"> <constructor-arg index="0" value="Jerry"/> <constructor-arg index="1" ref="playBook"/> </bean> <!-- 通过静态工厂方法创建bean实例 --> <bean id="dog" class="factory.AnimalFactory" factory-method="getAnimal"> <constructor-arg value="dog"/> <property name="name" value="Snoopy"/> </bean> <bean id="cat" class="factory.AnimalFactory" factory-method="getAnimal"> <constructor-arg value="cat"/> <property name="name" value="Kitty"/> </bean> <!-- 通过实例工厂方法创建bean实例 --> <bean id="fruitFactory" class="factory.FruitFactory"/> <bean id="apple" factory-bean="fruitFactory" factory-method="getFruit"> <constructor-arg value="apple"/> <property name="name" value="Fuji"/> </bean> <bean id="banana" factory-bean="fruitFactory" factory-method="getFruit"> <constructor-arg value="banana"/> <property name="name" value="Pisang"/> </bean> <!-- 通过工厂bean创建bean实例 --> <bean id="benz" class="factory.CarFactoryBean"> <property name="type" value="benz"/> </bean> <bean id="audi" class="factory.CarFactoryBean"> <property name="type" value="audi"/> </bean> ......
此外,有几点说明:

  使用工厂bean来管理的bean,即使scope是 singleton ,也并不是在Spring初始化时生产对象的,而是在第一次调用 ctx.getBean() 方法时生产的。

  Spring整合MyBatis,使用了 SqlSessionFactoryBeanMapperFactoryBean ,这两个就是工厂bean,它们实现了 FactoryBean 接口。前者生产 SqlSessionFactory ,后者生产 Mapper 。比如:

  

 <!-- sqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- <property name="configLocation" value="classpath:mybatis-config.xml"/>--> <property name="mapperLocations" value="classpath:dao/*.xml"/> <property name="transactionFactory"> <bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" /> </property> </bean> <bean id="myMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="dao.MyMapper" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean>
到此这篇关于Spring创建bean实例的几种方式分享的文章就介绍到这了,更多相关Spring创建bean 内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • spring编程式事务处理,spring编程事务
  • spring编程式事务处理,spring编程事务,详解Spring学习之编程式事务管理
  • spring的核心功能模块有几个,列举一些重要的spring模块
  • spring的核心功能模块有几个,列举一些重要的spring模块,七个Spring核心模块详解
  • spring注解和springmvc的注解,SpringMVC常用注解
  • spring注解和springmvc的注解,SpringMVC常用注解,详解springmvc常用5种注解
  • spring实现ioc的四种方法,spring的ioc的三种实现方式
  • spring实现ioc的四种方法,spring的ioc的三种实现方式,简单实现Spring的IOC原理详解
  • spring事务失效问题分析及解决方案怎么做,spring 事务失效情况
  • spring事务失效问题分析及解决方案怎么做,spring 事务失效情况,Spring事务失效问题分析及解决方案
  • spring5.0新特性,spring4新特性
  • spring5.0新特性,spring4新特性,spring5新特性全面介绍
  • spring ioc以及aop原理,springmvc aop原理
  • spring ioc以及aop原理,springmvc aop原理,深入浅析Spring 的aop实现原理
  • Spring cloud网关,spring cloud zuul作用
  • 留言与评论(共有 条评论)
       
    验证码: