Spring bean三种创建方式

  spring共提供了三种实例化bean的方式:构造器实例化(全类名,反射)、工厂方法(静态工厂实例化   动态工厂实例化)和FactoryBean ,下面一一详解:

 

1、构造器实例化

City.java

 1 package com.proc.bean;
 2 
 3 public class City {
 4 
 5     private String name;
 6     private String code;
 7     
 8     public City() {
 9     }
10 
11     public City(String name, String code) {
12         this.name = name;
13         this.code = code;
14     }
15 
16     public String getName() {
17         return name;
18     }
19 
20     public void setName(String name) {
21         this.name = name;
22     }
23 
24     public String getCode() {
25         return code;
26     }
27 
28     public void setCode(String code) {
29         this.code = code;
30     }
31 
32     @Override
33     public String toString() {
34         return "City [name=" + name + ", code=" + code + "]";
35     }
36 }

 

通过构造方式配置Bean

1 <bean id="city" class="com.proc.bean.City">
2     <constructor-arg value="北京"/>
3     <constructor-arg value="BJ"/>
4 </bean>

 

测试代码

1 ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
2 City city=ctx.getBean("city", City.class);
3 System.out.println(city);

输出结果

City [name=北京, code=BJ]

 

2、静态工厂实例化

  先创建一个静态工厂StaticCityFactory

 1 package com.proc.bean;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 
 6 public class StaticCityFactory {
 7     
 8     private static Map<String, City> cities;
 9     
10     static{
11         cities=new HashMap<String, City>();
12         cities.put("BJ", new City("北京", "BJ"));
13         cities.put("SH", new City("上海", "SH"));
14         cities.put("CD", new City("成都", "CD"));
15         cities.put("SZ", new City("深圳", "SZ"));
16     }
17 
18     public static City getCity(String code){
19         return cities.get(code);
20     }
21 }

 

  配置bean

1 <!-- 通过静态工厂实例化对象
2     class:静态工厂类型
3     factory-method:静态工厂静态方法名称
4     constructor-arg:为静态工厂方法指定参数
5  -->
6 <bean id="city" class="com.proc.bean.StaticCityFactory" factory-method="getCity">
7     <constructor-arg value="BJ"/>
8 </bean>

 

3、动态工厂实例化

  先创建一个实例化工厂

 1 package com.proc.bean;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 
 6 public class InstanceCityFactory {
 7     
 8     private Map<String, City> cities;
 9     {
10         cities=new HashMap<String, City>();
11         cities.put("BJ", new City("北京", "BJ"));
12         cities.put("SH", new City("上海", "SH"));
13         cities.put("CD", new City("成都", "CD"));
14         cities.put("SZ", new City("深圳", "SZ"));
15     }
16     
17     public City getCity(String code){
18         return cities.get(code);
19     }
20 }

  配置

1 <!-- 配置实例化工厂 -->
2 <bean id="cityFacotry" class="com.proc.bean.InstanceCityFactory"/>
3  
4  <!-- 通过实例化工厂获取对象 -->
5 <bean id="city" factory-bean="cityFacotry" factory-method="getCity">
6     <constructor-arg value="SH"/> <!-- 配置参数 -->
7 </bean>

 

4、FactoryBean

  

   一般情况下,Spring 通过反射机制利用 <bean> 的 class 属性指定实现类实例化 Bean ,在某些情况下,实例化 Bean 过程比较复杂,如果按照传统的方式,则需要在 <bean> 中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。 Spring 为此提供了一个org.springframework.bean.factory.FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 Bean 的逻辑。

  FactoryBean接口对于 Spring 框架来说占用重要的地位, Spring 自身就提供了 70 多个 FactoryBean 的实现。它们隐藏了实例化一些复杂 Bean 的细节,给上层应用带来了便利。从 Spring 3.0 开始, FactoryBean 开始支持泛型,即接口声明改为 FactoryBean<T> 的形式:

1 public interface FactoryBean<T> {  
2     T getObject() throws Exception;  
3     Class<?> getObjectType();  
4     boolean isSingleton();  
5 }

  在该接口中还定义了以下3 个方法:

    T getObject():返回由 FactoryBean 创建的 Bean 实例,如果 isSingleton() 返回 true ,则该实例会放到Spring 容器中单实例缓存池中;

    boolean isSingleton():返回由 FactoryBean 创建的 Bean 实例的作用域是 singleton 还是 prototype ;

    Class<T> getObjectType():返回 FactoryBean 创建的 Bean 类型。

  当配置文件中<bean> 的 class 属性配置的实现类是 FactoryBean 时,通过 getBean() 方法返回的不是FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的对象,相当于 FactoryBean#getObject() 代理了getBean() 方法。

 

  例:如果使用传统方式配置下面Car 的 <bean> 时, Car 的每个属性分别对应一个 <property> 元素标签。

 1 public class Car {
 2     private int maxSpeed;
 3     private String brand;
 4     private double price;
 5     public int getMaxSpeed() {
 6         return this.maxSpeed;
 7     }
 8     public void setMaxSpeed(int maxSpeed) {
 9         this.maxSpeed = maxSpeed;
10     }
11     public String getBrand() {
12         return this.brand;
13     }
14     public void setBrand(String brand) {
15         this.brand = brand;
16     }
17     public double getPrice() {
18         return this.price;
19     }
20     public void setPrice(double price) {
21         this.price = price;
22     }
23 }

  如果用FactoryBean 的方式实现就灵活点,下例通过逗号分割符的方式一次性的为 Car 的所有属性指定配置值:

public class CarFactoryBean implements FactoryBean<Car> {private String carInfo;public Car getObject() throws Exception {Car car = new Car();String[] infos = carInfo.split(",");car.setBrand(infos[0]);car.setMaxSpeed(Integer.valueOf(infos[1]));car.setPrice(Double.valueOf(infos[2]));return car;}public Class<Car> getObjectType() {return Car.class;}public boolean isSingleton() {return false;}public String getCarInfo() {return this.carInfo;}// 接受逗号分割符设置属性信息public void setCarInfo(String carInfo) {this.carInfo = carInfo;}
}

  有了这个CarFactoryBean 后,就可以在配置文件中使用下面这种自定义的配置方式配置 Car Bean 了:

1 <bean id="car" class="com.baobaotao.factorybean.CarFactoryBean">
2     <property name="carInfo" value="法拉利 ,400,2000000"/>
3 </bean>

  当调用getBean("car") 时, Spring 通过反射机制发现 CarFactoryBean 实现了 FactoryBean 的接口,这时Spring 容器就调用接口方法 CarFactoryBean#getObject() 方法返回。如果希望获取 CarFactoryBean 的实例,则需要在使用 getBean(beanName) 方法时在 beanName 前显示的加上 "&" 前缀:如 getBean("&car");

转载于:https://www.cnblogs.com/caoyc/p/5624697.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/256908.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Excel使用控件创建动态地图图表

[本文软件Excel 2010] 效果图&#xff1a; 首先我们看一下数据源 数据源中第二列是对应图形的名称。首先创建图形&#xff0c;我们可能在网络中找到各个地图的矢量图形。不过不是每个地图图形都适合我们&#xff0c;或许企业划分非按照行政区划分。因此可以尝试自己绘制&#x…

Windows 10 常用的快捷键及常用指令

系统快捷键 快捷键功能说明备注CtrlShiftEsc打开任务管理器macbook: fnshiftF11普通键盘: PrintScreen截屏幕图macbook: fnshiftoptionF11普通键盘: altPrintScreen截取当前窗口图片macbook: WinfnEsc普通键盘: WinPause/Break打开系统属性WinctrlD新建虚拟桌面Windows 10Winct…

学习笔记(35续):Python网络编程并发编程-基于gevent及线程池实现的并发套接字通讯

1.基于线程池实现并发套接字通讯&#xff1a;因为套接字涉及地是I/O密集模型&#xff0c;因此使用多线程会有高效率 服务器 #基于线程池完成并发的套接字通讯 from socket import * from threading import Thread from concurrent.futures import ThreadPoolExecutordef commun…

使用Configuration Manager部署及管理软件更新(2)

承接上一篇文章&#xff1a;http://ericxuting.blog.51cto.com/8995534/1543835 一、 确定软件更新符合性 1. 打开Configuration Manager管理控制台&#xff0c;点击软件库&#xff0c;展开软件更新&#xff0c;点击所有软件更新 2. 点击主页中的运行摘要&#xff0c;等待对话框…

NULL、nil、Nil、NSNull的区别

标志值含义NULL&#xff08;void *&#xff09;0C指针的字面零值nil&#xff08;id&#xff09;0Objecve-C对象的字面零值Nil&#xff08;Class&#xff09;0Objecve-C类的字面零值NSNull[NSNull null]用来表示零值的单独的对象转载于:https://www.cnblogs.com/wlsxmhz/p/56250…

Fiddler 域名过滤

原来一直没意识到Fiddler过滤&#xff0c;导致每次抓包都要自己判断、搜索好多东西&#xff0c;真是呵呵&#xff01; 过滤设置很简单&#xff0c;看懂一张图就解决问题了。 箭头 那两处设置下&#xff0c;圆圈处保存再进行抓包即可 转载于:https://www.cnblogs.com/eejron/p/4…

windows中VS卸载opencv配置,重新安装其他版本

1、找到工程的属性管理器&#xff0c;电机Debug64和Release64下面的 包含目录和库目录&#xff0c;删掉其原由配置的oepncv路径&#xff1b; 找到链接器中的附加依赖项&#xff0c;删掉原有的配置&#xff1b;

学习笔记(36):Python网络编程并发编程-IO模型介绍

立即学习:https://edu.csdn.net/course/play/24458/296460?utm_sourceblogtoedu I/O模型介绍&#xff1a;I/O模型表示处于等待状态的模型&#xff0c;如套接字通讯的accept和recv函数一样 1.同步I/O 2.异步I/O 3.阻塞I/O 4.非阻塞I/O

AD9 如何画4层pcb板

新建的PCB文件默认的是2层板&#xff0c;教你怎么设置4层甚至更多层板。在工具栏点击Design-->Layer Stack Manager.进入之后显示的是两层板&#xff0c;添加为4层板&#xff0c;一般是先点top layer, 再点Add Layer,再点Add Layer&#xff0c;这样就成了4层板。见下图。 有…

gulp 流处理

包含的内容&#xff1a; 穿插流流合并流队列流筛选1. 穿插流// passthrough stream 把流传递给其他的// usegulp.src(glob,{passthrough:true})// function 进行流的合并处理&#xff0c;避免多余配置以及冗余代码 2. 合并流// 使用merge2// install yarn add merge2 or …

windows上使用cmake 编译yaml-cpp源码,生成yam-cpp.lib

1、打开cmake-gui 2、添加CmakeList 3、建立build 4、进入工程中生成debug和release版本的lib

BZOJ 3039: 玉蟾宫( 悬线法 )

最大子矩阵...悬线法..时间复杂度O(nm)悬线法就是记录一个H向上延伸的最大长度(悬线), L, R向左向右延伸的最大长度, 然后通过递推来得到. ------------------------------------------------------------------#include<bits/stdc.h>using namespace std;#define ok(c) …

学习笔记(37):Python实战编程-yield实现生成器

立即学习:https://edu.csdn.net/course/play/19711/255579?utm_sourceblogtoedu1.yield return generator yield是一个返回的是一个生成器对象&#xff0c;是通过next函数一次一次地进行函数地迭代来获取结果的&#xff0c;而return函数则是将结果返回后&#xff0c;不再与…

ie6、7 下input的边框问题 ?

input的border设置为none,ie8及以上border都兼容&#xff0c;ie6和7的border还继续存在&#xff0c;将border设为0时所有浏览器上都不存在了&#xff0c;但是border为0时还是会继续的渲染。 将input的border设为"0 none",ie7及以上都正常了&#xff0c;但是ie6上inpu…

Mocha BSM产品亮点——关联事件分析

业务需求与挑战企业经常会遇到下列场景&#xff1a;• 企业某应用&#xff0c;例如&#xff0c;WebSphere Portal Server&#xff0c;已经不可用&#xff0c;是由于应用自身已不可用&#xff1f;还是应用所连接的数据库出了问题&#xff1f;还是应用的LDAP服务不可用&#xff1…

轻量级文本编辑器,Notepad最佳替代品:Notepad++

目录 正文之前1. 目的2. 原帖3. 为何推荐Notepad3.1. Notepad的一些基本特点3.2. notepad&#xff0c;notepad2&#xff0c;notepad&#xff0c;ultraEdit比较4. 使用Notepad前要了解的知识4.1. Notepad的名称和缩写4.2. Notepad修改设置后&#xff0c;立即生效4.3. Notepad的版…

学习笔记(38):Python实战编程-窗体显示

立即学习:https://edu.csdn.net/course/play/19711/343100?utm_sourceblogtoedu GUI&#xff1a;图形用户接口——GUI组件&#xff0c;组件定义&#xff0c;组件布局管理 主体窗口的设置&#xff1a; import tkinter#导入创建窗体的相关模块class Mainwindow():#创建窗口类de…

Tomcat 配置和spring-framework MVC配置简介

Tomcat启动时&#xff0c;先找系统变量CATALINA_BASE&#xff0c;如果没有&#xff0c;则找CATALINA_HOME。然后找这个变量所指的目录下的conf文件夹&#xff0c;从中读取配置文件。最重要的配置文件&#xff1a;server.xml 。要配置tomcat&#xff0c;基本上了解server.xml&am…

SDL 库 无法解析的外部符号 __imp__fprintf

VS2015 在链接器-》命令行 里加入legacy_stdio_definitions.lib 另外一个常见错误关于stderr的用 extern "C" { FILE __iob_func[3] { *stdin,*stdout,*stderr }; }转载于:https://www.cnblogs.com/zhaogaojian/p/5646885.html

ultra edit ftp帐号管理导入导出方法

在更换电脑或ultra edit新安装时往往需要将原来使用的ftp帐号导入过来&#xff0c;可以在高级-备份/恢复用户定制-选中其他保存备份&#xff0c;拷贝出来然后再导入。 也可以在配置-ftp/sftp中保存&#xff0c;拷贝出来然后在安装好后配置。 步骤1. 导出ftp帐号信息&#xff1a…