Facility Container 1.1 修改后的源代码及介绍
章锦
2023-12-01
Facility Container 提供IOC的简易容器实现.
---通过反射机制实现的IOC容器,简单而小巧.
A.能够做的事情
1.根据上下文也就是配置文件创建组件.
2.参数包括大部分的基本类型的创建,引用类型,集合参数类型(List Set Map Array).
3.参数还可以引用其上下文中的组件.
4.依赖注入的方式 通过构造函数,setter方法进行注入,还提供通过客户的配置调用任意方法的功能.
B.不能够做的事情,并且下一步需要作的事情.
1.引用其他上下文中的组件.
2.提供更好的上下文装饰策略接口 - 对创造好的容器的装饰 如日志打印装饰.
C.配置文件的介绍
让我们先看看xml配置文件把.
<appname:components xmlns:appname = "http://xiaochen-su.iteye.com/fc">
<component id = "" class = "" single = "">
<constructor>
...多个任意类型的参数
</contructor>
<setter name = "">
...单个任意类型的参数
</setter>
<method name = "">
...多个任意类型的参数
</method>
</component>
</appname:components>
以上是配置文件是一个组件元素的完整表示方式.
1.属性
id是在容器的名称
class就是组件的类型.
single容器是否以单体保存(每次返回该类型的实力是否重新创建,默认值为true表示只有在头一次引用才创建组件的实体).
2.子元素
constructor 通过构造函数去创建一个组件.
setter 通过该setter方法进行注射. 需要提供属性名称.
method 调用该方法.需要提供完整的方法名称.
该方法必须都是容器可以访问到的保护级别.
3.参数个数
1..构造方法依赖注入 <controller><property>...</property></controller> 参数的长度可以有多个
2.setter依赖注入 <setter name = "id"><property>...</property></setter> 参数的长度仅能有一个
3.method进行方法调用 <method name = "setId"><property>...</property></method> 参数的长度可以有多个
参数类型
<property><short></short></property>
<property><int></int></property>
<property><long></long></property>
<property><float></float></property>
<property><double></double></property>
<property><boolean></boolean></property>
<property><string></string></property>
<property><ref></ref></property>
<property>
<list>
<item><string></string></item>
<item><ref></ref></item>
</list>
</property>
<property>
<set>
<item><string></string></item>
<item><ref></ref></item>
</set>
</property>
<property>
<array type = "java.lang.Object">
<item><string></string></item>
<item><ref></ref></item>
</array>
</property>
<property>
<map>
<key name = ""><string></string></key>
<key name = ""><ref></ref></key>
</map>
</property>
具体约束参见E.
D.使用方法
例子1.
<um:components xmlns:um = "http://xiaochen-su.iteye.com/fc">
<!-- 测试构造函数列表为null但通过ConstructorComponentScarfskin构造组件 -->
<component id = "um_0" class = "demo.component.UserModel">
<setter name = "id">
<property>
<int>1100</int>
</property>
</setter>
<setter name = "userName">
<property><string>用户名 - 你好世界</string></property>
</setter>
<setter name = "password">
<property><string>密码 - 世界你好</string></property>
</setter>
<setter name = "email">
<property><string>电子邮件 - 世界你好@HelloWorld.com</string></property>
</setter>
<method name = "print">
<property>
<ref>out</ref>
</property>
<property>
<string>上下文打印信息</string>
</property>
</method>
<method name = "print"/>
</component>
<component id = "out" class = "java.io.PrintStream">
<constructor>
<property>
<string>/home/suchen/files/user model.txt</string>
</property>
</constructor>
</component>
</um:components>
package demo.component;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
/**
* 用户模型.
*
* @author suchen
* @time 2008-7-30 上午10:41:30
* @email xiaochen_su@126.com
*/
public class UserModel {
private int id;
private String password;
private String userName;
private String email;
public UserModel() {
}
public UserModel(int id, String userName, String password, String email) {
this.id = id;
this.userName = userName;
this.password = password;
this.email = email;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public void print() {
System.out.println(toString());
}
public void print(PrintStream out, String title) {
out.print(title + " # ");
out.println(toString());
}
public void print(OutputStream out, String title) {
try {
out.write(("print(OutputStream, String) # " + title + " # " + toString()).getBytes());
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String toString() {
return "[id] " + id + " [userName] " + userName + " [password] " + password + " [email] " + email;
}
}
try {
FacilityContainerContext containerContext = new ClassPathFacilityContainerContext("demo/testing/file/user-model.xml"); //1
containerContext.getComponentByKey("um_0"); //2
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
执行以上这段代码将会在屏幕上打印 [id] 1100 [userName] 用户名 - 你好世界 [password] 密码 - 世界你好 [email] 电子邮件 - 世界你好@HelloWorld.com
第一行创建了一个根据类路径查找配置的上下文
第二行是从上下文返回该组件,该组件设置为单体第一次调用会构造这个组建并创造依赖把并把实体和注入所需要的依赖保存住.
屏幕上打印字符串的方法是由<method name = "print"/>表示的,也就是public void print()方法.
在/home/suchen/files/user model.txt下打印的由
<method name = "print">
<property>
<ref>out</ref>
</property>
<property>
<string>上下文打印信息</string>
</property>
</method>
标记表示,也就是public void print(PrintStream outStream, String title)方法.
例子2
<component id = "smcms" class = "demo.component.SetterMethodCollectionModel">
<setter name = "array">
<property>
<array type = "java.lang.Object">
<item><string>setter - array - str - value</string></item>
<item><string>setter - array - str1 - value</string></item>
<item><string>setter - array - str2 - value</string></item>
<item><string>setter - array - str3 - value</string></item>
<item><string>setter - array - str4 - value</string></item>
<item><ref>createdate</ref></item>
</array>
</property>
</setter>
<setter name = "array1">
<property>
<array type = "java.lang.Object">
<item><string>setter - array1 - str - value</string></item>
<item><string>setter - array1 - str1 - value</string></item>
<item><string>setter - array1 - str2 - value</string></item>
<item><string>setter - array1 - str3 - value</string></item>
<item><string>setter - array1 - str4 - value</string></item>
<item><ref>createdate</ref></item>
</array>
</property>
</setter>
<setter name = "set">
<property>
<set>
<item><string>setter - set - str - value</string></item>
<item><string>setter - set - str1 - value</string></item>
<item><string>setter - set - str2 - value</string></item>
<item><string>setter - set - str3 - value</string></item>
<item><string>setter - set - str4 - value</string></item>
<item><ref>createdate</ref></item>
</set>
</property>
</setter>
<setter name = "set1">
<property>
<set>
<item><string>setter - set1 - str - value</string></item>
<item><string>setter - set1 - str1 - value</string></item>
<item><string>setter - set1 - str2 - value</string></item>
<item><string>setter - set1 - str3 - value</string></item>
<item><string>setter - set1 - str4 - value</string></item>
<item><ref>createdate</ref></item>
</set>
</property>
</setter>
<setter name = "map">
<property>
<map>
<key name = "str"><string>setter - map - str - value</string></key>
<key name = "str1"><string>setter - map - str1 - value</string></key>
<key name = "str2"><string>setter - map - str2 - value</string></key>
<key name = "str3"><string>setter - map - str3 - value</string></key>
<key name = "str4"><string>setter - map - str4 - value</string></key>
<key name = "createDate"><ref>createdate</ref></key>
</map>
</property>
</setter>
<setter name = "map1">
<property>
<map>
<key name = "str"><string>setter - map1 - str - value</string></key>
<key name = "str1"><string>setter - map1 - str1 - value</string></key>
<key name = "str2"><string>setter - map1 - str2 - value</string></key>
<key name = "str3"><string>setter - map1 - str3 - value</string></key>
<key name = "str4"><string>setter - map1 - str4 - value</string></key>
<key name = "createDate"><ref>createdate</ref></key>
</map>
</property>
</setter>
<setter name = "list">
<property>
<list>
<item><string>setter - list - str - value</string></item>
<item><string>setter - list - str1 - value</string></item>
<item><string>setter - list - str2 - value</string></item>
<item><string>setter - list - str3 - value</string></item>
<item><string>setter - list - str4 - value</string></item>
<item><ref>createdate</ref></item>
</list>
</property>
</setter>
<setter name = "list1">
<property>
<list>
<item><string>setter - list1 - str - value</string></item>
<item><string>setter - list1 - str1 - value</string></item>
<item><string>setter - list1 - str2 - value</string></item>
<item><string>setter - list1 - str3 - value</string></item>
<item><string>setter - list1 - str4 - value</string></item>
<item><ref>createdate</ref></item>
</list>
</property>
</setter>
</component>
public class SetterMethodCollectionModel {
private List list = null;
private Set set = null;
private Map map = null;
private List list1 = null;
private Set set1 = null;
private Map map1 = null;
private Object[] array = null;
private Object[] array1 = null;
//setter getter方法
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("list\n").append(StringUtils.toString(list));
buffer.append("list1\n").append(StringUtils.toString(list1));
buffer.append("array\n").append(StringUtils.toString(array));
buffer.append("array1\n").append(StringUtils.toString(array1));
buffer.append("set\n").append(StringUtils.toString(set));
buffer.append("set1\n").append(StringUtils.toString(set1));
buffer.append("map\n").append(StringUtils.toString(map));
buffer.append("map1\n").append(StringUtils.toString(map1));
return buffer.toString();
}
}
public static void testingDoubleCollectionSetter() {
try {
FacilityContainerContext containerContext =
new ClassPathFacilityContainerContext("demo/testing/file/collection-testing.xml");
SetterMethodCollectionModel smcms = (SetterMethodCollectionModel)containerContext.getComponentByKey("smcms");
System.out.println(smcms);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
这个是打印集合类型.
更多的测试实例参见demo包下的类.
E.支持类型
参数类型
1.集合参数的支持
<list>
<item><string></string></item>
<item><ref></ref></item>
</list>
<set>
<item><string></string></item>
<item><ref></ref></item>
</set>
<array type = "java.lang.Object">
<item><string></string></item>
<item><ref></ref></item>
</array>
<map>
<key name = ""><string></string></key>
<key name = ""><ref></ref></key>
</map>
2.基本类型的支持
short, int, long, float, double, boolean
F.简单的小应用
很简单的小应用连接数据库有 insert select update 三种操作的小应用.
用户在一个网页上 插入信息 更新信息 查看信息的操作.