使用Builder模式来初始化Bean
来源:互联网 发布:新手美工 编辑:程序博客网 时间:2024/04/30 06:07
这是写给项目组小伙伴培训用的文档。
一、使用setXXX来配置Bean的问题
如果在spring中采用xml来配置,需要bean中提供setXXXX方法来做bean参数的注入,比如:
Class Foo {
Public
void
setName(string name) {};
Public
void
setThreadCount(
int
count){};
}
这方式带来的问题是,setXXX和真正开始执行业务逻辑的代码之间往往有调用先后的要求,比如 Foo会根据ThreadCount来设置要启动的Thread个数:
Foo::execute(){
这里根据Threadcount 确定启动多少个线程;
}
考虑这个代码的执行:
Foo foo =
new
Foo();
foo.setName(xxxx);
foo.setThreadCount(
5
);
foo.execute()
//启动了5个线程;
foo.setThreadCount(
100
);
//这个方法调用后,会有什么副作用?
所以,针对这个问题,现在一般使用builder模式,来将Bean初始化和Bean的业务逻辑执行分离。
二、使用Builder模式
Builder模式将类的配置和执行分离。对于只写的参数,放在builder中处理; 对于控制业务流程,并可以动态修改的参数,可以在原类中处理:
Class Foo{
public
class
static
Builder{
private
String name;
private
int
count;
public
Builder name(String name){
this
.name = name;
return
this
;};
public
Builder threadCount(
int
count){
this
.count = count;
return
this
;};
public
Foo build(){
return
new
Foo(
this
);}
}
private
Builder builder;
public
static
newBuilder(){
return
new
Builder();
}
private
Foo(Builder builder){
this
.builder = builder;
}
public
void
execute(){
.....
new
ThreadExecutor(builder.count);
}
}
注意:
- Foo, Foo.Builder的构造函数不能是public的,避免被直接调用;
- Builder的构造函数也不能是public,避免直接调用;
- Builder的所有方法必须返回this,用来支持接连调用,如builder.name(xxx).threadcount(xxx).build();
- Foo中可以直接使用builder的属性;
三、 Builder如何支持类继承
如上所示,考虑如下类结构:
class
Bar extend Foo{
public
class
static
BarBuilder extend Builder{
public
BarBuilder age(
int
age){
this
.age=age;
return
this
};
}
public
Bar build(){
return
new
Bar(
this
);}
}
public
static
newBuilder(){
return
new
BarBuilder();
}
}
那么在构造Bar的时候,就出问题了:Bar.newBuilder().name(xxxx).age(12)
name()方法的返回值是Builder,不是BarBuilder, Builder是没有age方法的,所以调用Builder::age,就出现编译错误。
解决方法是使用模板类, Foo定义修改为:
Class Foo{
public
class
static
Builder<T
extends
Builder<T>>{
private
String name;
private
int
count;
public
T name(String name){
this
.name = name;
return
(T)
this
;};
public
T Builder threadCount(
int
count){
this
.count = count;
return
(T)
this
;};
public
Foo build(){
return
new
Foo(
this
);}
}
private
Builder<?> builder;
public
static
newBuilder(){
return
new
Builder();
}
private
Foo(Builder<?> builder){
this
.builder = builder;
}
public
void
execute(){
.....
new
ThreadExecutor(builder.count);
}
}
Bar定义修改为:
Class Bar{
public
class
static
BarBuilder
extends
Builder<BarBuilder>{
private
int
age;
public
BarBuilder age(
int
age){
this
.age = age;
return
this
;};
public
Bar build(){
return
new
Bar(
this
);}
}
private
BarBuilder builder;
这样,使用Bar.newBuilder(). name (xxxx).age(12) ,就没问题了。
0 0
- 使用Builder模式来初始化Bean
- 使用Builder模式代替来创建实例
- 如何使用另外一个managed bean的属性值来初始化inputText的值?
- 设计模式的Builder模式[结合使用Android中的MediaRecorder来浅析]
- Java 之 Builder模式使用
- 使用Borland C++ Builder来编写DLLs
- 使用electron-builder来打包electron应用
- 使用FactoryBean接口实现自定义bean初始化
- 使用FactoryBean接口实现自定义bean初始化
- bean 初始化
- bean初始化
- Bean初始化
- 学会使用BeanUtils 来操作bean属性
- 使用hibernate和bean来实现分页
- 通过使用构造器来配置Bean
- 利用静态内部类来实现builder模式
- Java中Builder模式的使用
- builder设计模式的使用以及优缺点
- Servlet自学第19讲:sendRedirect(重定向)与forworld(转发)区别
- selenium + python之元素定位
- 如何判断一个计算机系统的右移是“逻辑右移”,还是“算术右移”?
- oracle 数据块实现原理
- 代码片--Android--SharedPreferences
- 使用Builder模式来初始化Bean
- 黑马程序员——IOS基础(字符串)
- CocoaPods详解之----进阶篇
- MAVEN搭建多模块化项目
- 【2015/5/18】java中的接口+struct2概念入门
- 派生data与time
- 如何给ecshop的商品分类页添加自定义title标题
- CocoaPods详解之----制作篇
- mp3编程要点