在Spring的世界中, 我们通常会利用bean config file 或者 annotation注解方式来配置bean.

在第一种利用bean config file(spring xml)方式中, 还包括如下三小类

  1. 反射模式

  2. 工厂方法模式(本文重点)

  3. Factory Bean模式

其中反射模式最常见, 我们需要在bean 配置中指明我们需要的bean object的全类名。

例如:

<bean id="car1" class="com.home.factoryMethod.Car"> <property name="id" value="1"></property> <property name="name" value="Honda"></property> <property name="price" value="300000"></property> </bean>

上面bean 里面的class属性就是全类名, Spring利用java反射机制创建这个bean。

Factory方法模式

本文介绍的是另1种模式, 在工厂方法模式中, Spring不会直接利用反射机制创建bean对象, 而是会利用反射机制先找到Factory类,然后利用Factory再去生成bean对象。

而Factory Mothod方式也分两种, 分别是静态工厂方法 和 实例工厂方法。

静态工厂方法方式

所谓镜头静态工厂方式就是指Factory类不本身不需要实例化, 这个Factory类中提供了1个静态方法来生成bean对象

下面是例子

bean类Car

首先我们定义1个bean类Car

package com.home.factoryMethod;public class Car { private int id; private String name; private int price; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @Override public String toString() { return "Car [id=" + id + ", name=" + name + ", price=" + price + "]"; } public Car(){ } public Car(int id, String name, int price) { super(); this.id = id; this.name = name; this.price = price; } }

然后我们再定义1个工厂类CarStaticFactory

package com.home.factoryMethod;import java.util.HashMap;
import java.util.Map;public class CarStaticFactory { private static Map<Integer, Car> map = new HashMap<Integer,Car>(); static{ map.put(1, new Car(1,"Honda",300000)); map.put(2, new Car(2,"Audi",440000)); map.put(3, new Car(3,"BMW",540000)); } public static Car getCar(int id){ return map.get(id); } }

里面定义了1个静态的bean 容器map. 然后提供1个静态方法根据Car 的id 来获取容器里的car对象。

xml配置

  <!-- Static Factory method:class: the class of Factoryfactory-method: method of get Bean Objectconstructor-arg: parameters of factory-method--><bean id="bmwCar" class="com.home.factoryMethod.CarStaticFactory" factory-method="getCar"> <constructor-arg value="3"></constructor-arg> </bean> <bean id="audiCar" class="com.home.factoryMethod.CarStaticFactory" factory-method="getCar"> <constructor-arg value="2"></constructor-arg> </bean>

可以见到, 利用静态工厂方法定义的bean item种, class属性不在是bean的全类名, 而是静态工厂的全类名, 而且还需要指定工厂里的 
getBean 静态方法名字和参数

客户端代码

public static void h(){ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-factoryMethod.xml"); Car car1 = (Car) ctx.getBean("bmwCar"); System.out.println(car1); car1 = (Car) ctx.getBean("audiCar"); System.out.println(car1); }

输出

May 30, 2016 11:17:45 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@43765ab3: startup date [Mon May 30 23:17:45 CST 2016]; root of context hierarchy May 30, 2016 11:17:46 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [bean-factoryMethod.xml] Car [id=3, name=BMW, price=540000] Car [id=2, name=Audi, price=440000]

小结

由上面的例子, 静态工厂方法方式是非常适用于作为1个bean容器(集合的), 只不过吧bean集合定义在工厂类里面而不是bean config file里面。 
缺点也比较明显, 把数据写在class里面而不是配置文件中违反了我们程序猿的常识和spring的初衷。当然优点就是令到令人恶心的bean config file更加简洁啦。

实例工厂方法方式

所谓实例工厂方式也很容易看懂, 就是里面的getBean 方法不是静态的, 也就是代表要先实例1个工厂对象, 才能依靠这个工厂对象去获得bean 对象。

用回上面的例子。

而这次我们写1个实例工厂类

CarInstanceFactroy

package com.home.factoryMethod;import java.util.HashMap;
import java.util.Map;public class CarInstanceFactory { private Map<Integer, Car> map = new HashMap<Integer,Car>(); public void setMap(Map<Integer, Car> map) { this.map = map; } public CarInstanceFactory(){ } public Car getCar(int id){ return map.get(id); } }

bean xml写法

<!-- Instance Factory Method:1.must create a bean for the Instance Factroy First--><bean id="carFactory" class="com.home.factoryMethod.CarInstanceFactory"> <property name="map"> <map> <entry key="4"> <bean class="com.home.factoryMethod.Car"> <property name="id" value="4"></property> <property name="name" value="Honda"></property> <property name="price" value="300000"></property> </bean> </entry> <entry key="6"> <bean class="com.home.factoryMethod.Car"> <property name="id" value="6"></property> <property name="name" value="ford"></property> <property name="price" value="500000"></property> </bean> </entry> </map> </property> </bean> <!-- 2.use Factory bean to get bean objectr factory-bean : the bean define above factory-method: method of get Bean Object constructor-arg: parameters of factory-method --> <bean id="car4" factory-bean="carFactory" factory-method="getCar"> <constructor-arg value="4"></constructor-arg> </bean> <bean id="car6" factory-bean="carFactory" factory-method="getCar"> <constructor-arg value="6"></constructor-arg> </bean

因为实例工厂本身要实例化, 所以我们可以在xml中 指定它里面容器的data, 解决了上面提到的静态工厂方法的缺点啦

client代码

public static void h2(){ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-factoryMethod.xml"); Car car1 = (Car) ctx.getBean("car4"); System.out.println(car1); car1 = (Car) ctx.getBean("car6"); System.out.println(car1); }

输出结果

May 31, 2016 12:22:28 AM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5d79a4c9: startup date [Tue May 31 00:22:28 CST 2016]; root of context hierarchy May 31, 2016 12:22:28 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [bean-factoryMethod.xml] Car [id=4, name=Honda, price=300000] Car [id=6, name=ford, price=500000]

小结

本人觉得实例工厂方式使用起来更加灵活啦, 不过项目中其实本文一开始提到的第三种方法FactoryBean比起工厂方法方式更加常见。

转载于:https://www.cnblogs.com/PengChengLi/p/9233080.html

spring注入bean的三种方法相关推荐

  1. Spring装配bean的三种方法:自动化装配,java代码装配,XML装配及它们的混合使用

    一.自动化装配 首先,把可能被装配的类声明为组件类,告知spring要为这个类创建bean如: import org.springframework.stereotype.Component;@ Co ...

  2. Spring 使用@Import注入Bean的三种方式

    一.准备工作 1.导入spring-context依赖 <dependency><groupId>org.springframework</groupId>< ...

  3. Spring框架学习教程,详解Spring注入bean的几种方式

    首先,要学习Spring中的Bean的注入方式,就要先了解什么是依赖注入. 依赖注入是指:让调用类对某一接口的实现类的实现类的依赖关系由第三方注入,以此来消除调用类对某一接口实现类的依赖. Sprin ...

  4. Spring创建Bean的三种方式的使用和区别

    在学习Spring的时候,发现Spring的IOC(控制反转)为我们提供的三种创建Bean的方式. 1.Spring创建Bean的三种方式 这里采用XML配置,分别演示三种创建Bean的方式和代码. ...

  5. spring 注入bean的两种方式

    我们都知道,使用spring框架时,不用再使用new来实例化对象了,直接可以通过spring容器来注入即可. 而注入bean有两种方式: 一种是通过XML来配置的,分别有属性注入.构造函数注入和工厂方 ...

  6. Spring 创建Bean的三种方式

    创建Bean的三种方式 第一种方式:使用默认构造函数创建. 在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时.采用的就是默认构造函数创建bean对象,此 ...

  7. Spring 实例化bean的三种方式

    第一种方法:直接配置Bean Xml代码   <bena id="所需要实例化的一个实例名称" class="包名.类名"/> 例如: 配置文件中的 ...

  8. 记下来 Spring 装配 Bean 的三种方式

    ps:拿笔记一下,面试可能会考.依赖注入DI和面向切面编程AOP是Spring框架最核心的部分.这次主要是总结依赖注入的bean的装配方式. 前言 什么是依赖注入呢?也可以称为控制反转,简单的来说,一 ...

  9. 总结 Spring 注入 bean 的四种方式

    一提到 Spring,大家最先想到的是啥?是 AOP 和 IOC 的两大特性?是 Spring 中 Bean 的初始化流程?还是基于 Spring 的 Spring Cloud 全家桶呢? 今天我们就 ...

  10. Java普通类获取Spring框架Bean 的五种方法

    方法一:在初始化时保存ApplicationContext对象 代码: ApplicationContext ac = new FileSystemXmlApplicationContex(" ...

最新文章

  1. 修复阻止程序安装或删除的问题
  2. Oracle 总复习
  3. windows下安装django的一些问题
  4. 在有赞工作两年半的感受
  5. Windows Server 2008网络基础结构的实现与管理
  6. Oracle学习:分组数据(group by)与笛卡尔积
  7. 京东商品详情页碎碎念
  8. Java 数字相关操作通用类 NumberUtils.java
  9. 《MySQL排错指南》——1.9 许可问题
  10. iOS 利用UIDocumentInteractionController打开和预览文档
  11. c语言实验指导,C语言实验指导
  12. anaconda显示ImportError: cannot import name ‘secure_write‘
  13. 比特率与波特率的区别
  14. dialog的各类显示方法
  15. 电池革命:固态电池量产还有多远?
  16. Windows 系统封装
  17. 谁也没想到,苹果为了利润竟然如此敷衍用户!
  18. 【项目】 基于BOOST的站内搜索引擎
  19. 毕业论文知网查重之应对办法
  20. 服务器提示位置不可用 拒绝访问,主编修复win10系统打开Local settings文件夹提示“位置不可用,拒绝访问的问题...

热门文章

  1. 数据和判定(二)------运算符
  2. linux添加动态连接库,CentOS下如何添加动态链接库?
  3. python中pickle模块_python中的pickle模块
  4. 数据库设计 表和表之间的三种关系
  5. VS2013中安装配置和使用Boost库
  6. 深入解密来自未来的缓存-Caffeine
  7. 实战java虚拟机配套代码
  8. 软件开发应用分层、每层的作用及各层之间调用关系
  9. java 7 json_java第七周----json
  10. readhat7mysql_Redhat7.3安装MySQL8.0.22的详细教程(二进制安装)