- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Spring工厂方法创建(实例化)bean实例代码由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
目标明确 。
简单叙述一下本文想要解决的问题:如何在Spring中不再使用Spring创建Bean实例,而是把Bean创建过程转移到开发者手中.
思路清晰 。
创建Bean实例的方式:
1) 通过构造器(有参或无参) 。
方式: <bean id="" class=""/> 。
2) 通过静态工厂方法 。
方式: <bean id="" class="工厂类" factory-method="静态工厂方法"/> 。
注: 工厂类实例没有创建 。
3) 通过实例工厂方法(非静态方法) 。
方式
<bean id="factory" class="工厂类"/> 。
<bean id="" factory-bean="factory" factory-method="实例工厂方法"/> 。
注: 工厂类实例被创建 。
方法实用 。
示例1:
需求:
1 不想再bean.xml加载的时候实例化bean,而是想把加载bean.xml与实例化对象分离.
2 实现单例的bean 。
以上的情况,都可以通过工厂方法factory-method来创建bean.
这样再加载bean.xml时,不会直接实例化bean,而是当调用factory-method所指的方法时,才开始真正的实例化.
实现:通过spring的factory-method来创建单例的bean 首先通过静态内部类创建一个单例对象 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package
com.spring.test.factorymethod;
public
class
Stage {
public
void
perform(){
System.out.println(
"演出开始..."
);
}
private
Stage(){
}
private
static
class
StageSingletonHolder{
static
Stage instance =
new
Stage();
}
public
static
Stage getInstance(){
return
StageSingletonHolder.instance;
}
}
|
在spring配置文件中指定加载的方法getInstance 。
1
2
3
4
5
6
7
8
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
beans
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns
=
"http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<
bean
id
=
"theStage"
class
=
"com.spring.test.factorymethod.Stage"
factory-method
=
"getInstance"
></
bean
>
</
beans
>
|
通过应用上下文调用bean获取实例 。
1
2
3
4
5
6
7
8
9
10
11
12
|
package
com.spring.test.factorymethod;
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public
class
test {
public
static
void
main(String[] args) {
ApplicationContext ctx =
new
ClassPathXmlApplicationContext(
"bean.xml"
);
Stage stage = ((Stage)ctx.getBean(
"theStage"
));
//.getInstance();
stage.perform();
}
}
|
执行结果 。
1
2
3
4
5
6
7
|
一月 24, 2015 6:38:18 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@512dbd1a: startup date [Sat Jan 24 18:38:18 CST 2015]; root of context hierarchy
一月 24, 2015 6:38:19 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [bean.xml]
一月 24, 2015 6:38:19 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2d1879ea: defining beans [duke,sonnet29,poeticDuke,theStage]; root of factory hierarchy
演出开始...
|
工厂方法创建bean介绍 。
1. 使用静态工厂方法创建Bean 。
使用静态工厂方法创建Bean实例时,class属性也必须指定,但此时class属性并不是指定Bean实例的实现类,而是静态工厂类。因为Spring需要知道是用哪个工厂来创建Bean实例。另外,还需要使用factory-method来指定静态工厂方法名,Spring将调用静态工厂方法(可能包含一组参数),来返回一个Bean实例,一旦获得了指定Bean实例,Spring后面的处理步骤与采用普通方法创建Bean实例则完全一样。需要注意的是,当使用静态工厂方法来创建Bean时,这个factory-method必须要是静态的。这段阐述听上去有点晕,话不多说,上代码:
先定义一个接口,静态方法产生的将是该接口的实例:
1
2
3
|
public
interface
Animal {
public
void
sayHello();
}
|
下面是接口的两个实现类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public
class
Cat
implements
Animal {
private
String msg;
//依赖注入时必须的setter方法
public
void
setMsg(String msg){
this
.msg = msg;
}
@Override
public
void
sayHello(){
System.out.println(msg +
",喵~喵~"
);
}
}
public
class
Dog
implements
Animal {
private
String msg;
//依赖注入时必须的setter方法
public
void
setMsg(String msg){
this
.msg = msg;
}
@Override
public
void
sayHello(){
System.out.println(msg +
",旺~旺~"
);
}
}
|
下面的AnimalFactory工厂中包含了一个getAnimal的静态方法,该方法将根据传入的参数决定创建哪个对象。这是典型的静态工厂设计模式.
1
2
3
4
5
6
7
8
9
|
public
clas AnimalFactory {
public
static
Animal getAnimal(String type){
if
(
"cat"
.equalsIgnoreCase(type)){
return
new
Cat();
}
else
{
return
new
Dog();
}
}
}
|
如果需要指定Spring使用AnimalFactory来产生Animal对象,则可在Spring配置文件中作如下配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<!-- 配置AnimalFactory的getAnimal方法,使之产生Cat -->
<bean id="cat" class="com.abc.AnimalFactory" factory-method="getAnimal">
<!-- 配置静态工厂方法的参数,getAnimal方法将产生Cat类型的对象 -->
<constructor-arg value="cat" />
<!-- 通过setter注入的普通属性 -->
<property name="msg" value="猫猫" />
</bean>
<!-- 配置AnimalFactory的getAnimal方法,使之产生Dog -->
<bean id="dog" class="com.abc.AnimalFactory" factory-method="getAnimal">
<!-- 配置静态工厂方法的参数,getAnimal方法将产生Dog类型的对象 -->
<constructor-arg value="dog" />
<!-- 通过setter注入的普通属性 -->
<property name="msg" value="狗狗" />
</bean>
|
从上面的配置可以看出:cat和dog两个Bean配置的class和factory-method完全相同,这是因为两个实例都使用同一个静态工厂类、同一个静态工厂方法产生得到的。只是为这个静态工厂方法指定的参数不同,使用<constructor-arg />元素来为静态工厂方法指定参数.
主程序获取cat和dog两个Bean实例的方法不变,同样只需要调用Spring容器的getBean()即可:
1
2
3
4
5
6
7
8
9
10
|
public
class
Test {
public
static
void
main(String args[]){
ApplicationContext context =
new
ClassPathXmlApplicationContext(
"applicationContext.xml"
);
Animal a1 = context.getBean(
"cat"
, Animal.
class
);
a1.sayHello();
Animal a2 = context.getBean(
"dog"
, Animal.
class
);
a2.sayHello();
}
}
|
输出结果:
1
2
|
<code class="hljs">猫猫,喵~喵~
狗狗,旺~旺~</code>
|
使用静态工厂方法创建实例时必须提供工厂类和产生实例的静态工厂方法。通过静态工厂方法创建实例时需要对Spring配置文件做如下改变; 。
class属性不在是Bean实例的实现类,而是生成Bean实例的静态工厂类 。
使用factory-method指定生产Bean实例的静态工厂方法 。
如果静态工厂方法需要参数,使用<constructor-arg />元素为其配置 。
当我们指定Spring使用静态工厂方法来创建Bean实例时,Spring将先解析配置文件,并根据配置文件指定的信息,通过反射调用静态工厂类的静态工厂方法,并将该静态工厂方法的返回值作为Bean实例,在这个过程中,Spring不再负责创建Bean实例,Bean实例是由用户提供的静态工厂方法提供的.
2. 使用实例工厂方法创建Bean 。
实例工厂方法与静态工厂方法只有一点不同:调用静态工厂方法只需要使用工厂类即可,调用实例工厂方法则必须使用工厂实例。所以在Spring配置上也只有一点区别:配置静态工厂方法指定静态工厂类,配置实例工厂方法则指定工厂实例。同样是上面的例子将AnimalFactory修改为:
1
2
3
4
5
6
7
8
9
|
public
clas AnimalFactory {
public
Animal getAnimal(String type){
//这里仅仅是去掉了static关键字
if
(
"cat"
.equalsIgnoreCase(type)){
return
new
Cat();
}
else
{
return
new
Dog();
}
}
}
|
Spring文件修改为:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<!-- 先配置工厂类 -->
<
bean
id
=
"animalFactory"
class
=
"com.abc.AnimalFactory"
/>
<!-- 这里使用factory-bean指定实例工厂类对象 -->
<
bean
id
=
"cat"
factory-bean
=
"animalFactory"
factory-method
=
"getAnimal"
>
<!-- 同样指定factory-method的参数 -->
<
constructor-arg
value
=
"cat"
/>
<
property
name
=
"msg"
value
=
"猫猫"
/>
</
bean
>
<
bean
id
=
"dog"
factory-bean
=
"animalFactory"
factory-method
=
"getAnimal"
>
<
constructor-arg
value
=
"dog"
/>
<
property
name
=
"msg"
value
=
"狗狗"
/>
</
bean
>
|
测试类不用修改,输出结果和上面相同.
很多情况下使用<bean id=”bean1” class=”…” />定义一个bean,这种定义方式Spring将会调用默认的无参数构造方法创建Bean实例。除此之外还可以使用工厂方式创建Bean实例,实现Bean创建与使用的分离,将Bean创建工作交由工厂来完成.
配置工厂Bean的三种方式.
抽象接口:
1
2
3
|
public
interface
IMusicBox {
public
void
play();
}
|
1、静态工厂方法取得Bean实例 。
工厂类:
1
2
3
4
5
6
7
8
9
|
public
class
MusicBoxFactory {
public
static
IMusicBox createMusicBox(){
return
new
IMusicBox(){
public
void
play(){
System.out.println(
"Play piano..."
);
}
};
}
}
|
配置文件:
1
|
<
bean
id
=
"musicBox"
class
=
"test.spring.MusicBoxFactory"
factory-method
=
"createMusicBox"
/>
|
测试类:
1
2
3
4
5
6
|
public
static
void
main(String[] args) {
ApplicationContext ctx =
new
ClassPathXmlApplicationContext(
"bean-config.xml"
);
IMusicBox musicbox = (IMusicBox)ctx.getBean(
"musicBox"
);
musicbox.play();
}
|
2、工厂实例的方法取得Bean实例 。
工厂类:
1
2
3
4
5
6
7
8
9
|
public
class
MusicBoxFactory {
public
IMusicBox createMusicBox(){
//没有static修饰
return
new
IMusicBox(){
public
void
play(){
System.out.println(
"Play piano..."
);
}
};
}
}
|
配置文件:
1
2
|
<
bean
id
=
"factoryBean"
class
=
"test.spring.MusicBoxFactory"
/>
<
bean
id
=
"musicBox"
factory-bean
=
"factoryBean"
factory-method
=
"createMusicBox"
/>
|
“factory-bean”属性指定工厂Bean,”factory-method”属性指定工厂方法来取得Bean实例.
测试类:
1
2
3
4
5
6
|
public static void main(String[] args) {
ApplicationContext ctx =
new ClassPathXmlApplicationContext("bean-config.xml");
IMusicBox musicbox = (IMusicBox)ctx.getBean("musicBox");
musicbox.play();
}
|
3、工厂类实现org.springframework.beans.factory.FacotryBean接口 。
工厂类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import
org.springframework.beans.factory.FactoryBean;
public
class
MusicBoxFactory2
implements
FactoryBean {
public
Object getObject()
throws
Exception {
return
new
IMusicBox(){
public
void
play(){
System.out.println(
"Play piano..."
);
}
};
}
public
Class getObjectType() {
return
IMusicBox.
class
;
}
public
boolean
isSingleton() {
return
false
;
}
}
|
配置文件:
1
|
<
bean
id
=
"musicBox"
class
=
"test.spring.MusicBoxFactory2"
/>
|
测试类:
1
2
3
4
5
6
7
8
9
10
11
|
public
static
void
main(String[] args) {
ApplicationContext ctx =
new
ClassPathXmlApplicationContext(
"bean-config.xml"
);
//不加 & 返回工厂的“产品”
IMusicBox musicbox = (IMusicBox)ctx.getBean(
"musicBox"
);
musicbox.play();
//加 & 返回工厂类实例
Object obj = ctx.getBean(
"&musicBox"
);
System.out.println(obj.getClass().getName());
}
|
实现FactoryBean接口的类不会被视为普通的Bean,Spring会自动检测,调用getObject方法获取Bean实例 。
总结 。
Spring工厂方法实例化bean实例的介绍就到这里,有什么不足之处,大家可以留言指出。感谢朋友们对本站的支持! 。
原文链接:https://www.cnblogs.com/duanxz/p/3456948.html 。
最后此篇关于Spring工厂方法创建(实例化)bean实例代码的文章就讲到这里了,如果你想了解更多关于Spring工厂方法创建(实例化)bean实例代码的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是 python 的新手。我试图找到我的文本的频率分布。这是代码, import nltk nltk.download() import os os.getcwd() text_file=open(
我对安卓 fragment 感到困惑。我知道内存 fragment 但无法理解什么是 android fragment 问题。虽然我发现很多定义,比如 Android fragmentation re
尝试对 WordPress 进行 dockerise 我发现了这个场景: 2个数据卷容器,一个用于数据库(bbdd),另一个用于wordpress文件(wordpress): sudo docker
这个问题已经有答案了: From the server is there a way to know that my page is being loaded in an Iframe (1 个回答)
我正在玩小型服务器,试图对运行在其上的服务进行docker化。为简化起见,假设我必须主要处理:Wordpress和另一项服务。 在Docker集线器上有许多用于Wordpress的图像,但是它们似乎都
我想要发生的是,当帐户成功创建后,提交的表单应该消失,并且应该出现一条消息(取决于注册的状态)。 如果成功,他们应该会看到一个简单的“谢谢。请检查您的电子邮件。” 如果不是,那么他们应该会看到一条适当
就是这样,我需要为客户添加一个唯一标识符。通过 strip 元数据。这就是我现在完全构建它的方式,但是我只有最后一部分告诉我用户购买了哪个包。 我试着看这里: Plans to stripe 代码在这
我有一个类将执行一些复杂的操作,涉及像这样的一些计算: public class ComplexAction { public void someAction(String parameter
这个问题已经有答案了: maven add a local classes directory to module's classpath (1 个回答) 已关闭10 年前。 我有一些不应更改的旧 E
我使用 fragment 已经有一段时间了,但我经常遇到一个让我烦恼的问题。 fragment 有时会相互吸引。现在,我设法为此隔离了一个用例,它是这样的: Add fragment A(也使用 ad
我的 html 中有一个 ol 列表,上面有行条纹。看起来行条纹是从数字后面开始的。有没有办法让行条纹从数字开始? 我已经包含了正在发生的事情的片段 h4:nth-child(even) {
如何仅使用 css 将附加图像 html 化? 如果用纯 css 做不到,那我怎么能至少用一个图像来做 最佳答案 这不是真正的问题,而是您希望我们为您编写代码。我建议您搜索“css breadcrum
以下是 Joshua 的 Effective Java 的摘录: If you do synchronize your class internally, you can use various te
在这里工作时,我们有一个框向业务合作伙伴提供 XML 提要。对我们的提要的请求是通过指定查询字符串参数和值来定制的。其中一些参数是必需的,但很多不是。 例如,我们要求所有请求都指定一个 GUID 来标
我有 3 个缓冲区,其中包含在 32 位处理器上运行的 R、G、B 位数据。 我需要按以下方式组合三个字节: R[0] = 0b r1r2r3r4r5r6r7r8 G[0] = 0b g1g2g3g4
我最近发现了关于如何使用 History.js、jQuery 和 ScrollTo 通过 HTML5 History API 对网站进行 Ajax 化的要点:https://github.com/br
我们有一个 Spring Boot 应用程序,由于集成需要,它变得越来越复杂——比如在你这样做之后发送一封电子邮件,或者在你之后广播一条 jms 消息等等。在寻找一些更高级别的抽象时,我遇到了 apa
我正在尝试首次实施Google Pay。我面临如何指定gateway和gatewayMarchantId的挑战。 我所拥有的是google console帐户,不知道在哪里可以找到此信息。 priva
昨天下午 3 点左右,我为两个想要从一个 Azure 帐户转移到另一个帐户的网站设置了 awverify 记录。到当天结束时,Azure 仍然不允许我添加域,所以我赌了一把,将域和 www 子域重新指
我正在使用terms facet在elasticsearch服务器中获取顶级terms。现在,我的标签"indian-government"不被视为一个标签。将其视为"indian" "governm
我是一名优秀的程序员,十分优秀!