自己实现的 - Facility Container - 简易容器

廉鸿运
2023-12-01
FacilityContainer - 简易的IOC容器

容器是应用程序运行的框架这点似乎不错;容器里可以保存很多对象,当需要使用时根据名字或某种条件来取得单个或多个对象。
那么保存对象的前提就是创建对象。

1.FacilityContainer创建对象的方式 - 在FacilityContainer中把每个需要实例化的对象称为组件.
通过配置文件实例化组件 首先的是通过没有参数的共有的构造函数来创建组件.

public class Entity {
public Entity() {

}

public Entity(String s, String t) {
System.out.println("[s] " + s + " [t] " + t);
}

public Entity(String s, int i) {
System.out.println("[s] " + s + " [i] " + i);
}
}
<1>

<fc:components xmlns:fc = "http://xiaochen-su.iteye.com/fc">
<component id = "demo" class = "sc.demo.Entity"/>
</fc:compoennts>

创建了一个sc.demo.Entity对象以demo作为名称保存在容其中.

<2>

<fc:components xmlns:fc = "http://xiaochen-su.iteye.com/fc">
<component id = "demo" class = "sc.demo.Entity">
<constructor>
<property><string>entity_s</string></property>
<property><string>entity_t</string></property>
</constructor>
</component>
</fc:compoennts>

通过public Entity(String s, String t)以字符串面量 entity_s, entity_t 创建了一个sc.demo.Entity对象

<3>

<fc:components xmlns:fc = "http://xiaochen-su.iteye.com/fc">
<component id = "demo" class = "sc.demo.Entity">
<constructor>
<property><string>entity_s</string></property>
<property><int>213</int></property>
</constructor>
</component>
</fc:compoennts>

通过public Entity(String s, int i)以字符串面量 entity_s 和整型 213 创建了一个sc.demo.Entity对象.

1.2硬性编码创建组件


<1>

ControllableFacilityContainer container = new DefaultFacilityContaienr();
ComponentScarfskin componentScarfskin = new ConstructorComponentScarfskin( Entity.class, new SimpleNaming("demo"), ConstantContext.EMPTY_PARAMETER_ARRAY, true);
container.registerComponent(componentScarfskin);

通过不带参数的共有的构造方法创建组件

<2>

Parameter entity_s = new BasicParameter("entity_s", String.class);
Parameter entity_t = new BasicParameter("entity_t", String.class);
//顺序要与构造函数的顺序一致
Parameter[] params = new Parameter[]{entity_s, entity_t};

ControllableFacilityContainer container = new DefaultFacilityContaienr();
ComponentScarfskin componentScarfskin = new ConstructorComponentScarfskin( Entity.class, new SimpleNaming("demo"), params, true);
container.registerComponent(componentScarfskin);


通过带有参数的共有的构造方法创建组件 (不带有基本类型)

<3>

Parameter entity_s = new BasicParameter("entity_s", String.class);
Parameter entity_i = new BasicParameter(Integer.valueOf(213), int.class);
//顺序要与构造函数的顺序一致
Parameter[] params = new Parameter[]{entity_s, entity_i};

ControllableFacilityContainer container = new DefaultFacilityContaienr();
ComponentScarfskin componentScarfskin = new ConstructorComponentScarfskin( Entity.class, new SimpleNaming("demo"), params, true);
container.registerComponent(componentScarfskin);

通过带有参数的共有的构造方法创建组件 (带有基本类型)

2.FacilityContainer操作对象的方式

上下文 - 获取资源并操作容器的对象.(FacilityContainer接口 也就是说不能通过上下文放入组件).

FacilityContainerContext <<interface>>
AbstractAdapterFacilityContainerContext <<abstract>>
FileSystemAdapterFacilityContainerContext
URLAdapterFacilityContainerContext
AbstractFacilityContainerContext <<abstract>>
ClassPathFacilityContainerContext
FileSystemFacilityContainerContext
URLFacilityContainerContext
资源 - 管理资源源头的对象.

Resource <<interface>>
AbstractResource
ClassPathResource
FileResource
URLResource
FileResourceAdapter
URLResourceAdapter

以上出现了 上下文 -> 资源 的并行层次结构.
===========================================================================================================

public class IndexController extends HttpServlet {

private static final long serialVersionUID = 20080602113050L;

//委托名称
private static final String DELEGATE_ID = "index_guide";
//向导委托
private Guide delegate = null;
private FacilityContainerContext fcc = null;

public void init() {
ServletContext servletContext = this.getServletContext();
ServletConfig servletConfig = this.getServletConfig();

try {
URL xmlURL = servletContext.getResource(servletConfig.getInitParameter("component context"));
URL propertiesURL = servletContext.getResource(servletConfig.getInitParameter("container strategy"));

fcc = new URLAdapterFacilityContainerContext(xmlURL, propertiesURL);
//当然这里返回的可以是任何对象 这个向导的委托其实就好是Action对象
delegate = (Guide)fcc.getComponentByKey(DELEGATE_ID);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
delegate.execute(request, response, null, false);
}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
doGet(request, response);
}

}
=================================================================================================================
3.FacilityContainer 不具备的
1.引用其他上下文的中的组件,体现在xml中如下.

<fc:components xmlns:fc = "http://xiaochen-su.iteye.com/fc">
<import name = "importother" path = "./othercontext.xml"/>

<component id = "demo" class = "sc.demo.Entity">
<constructor>
<property><string>entity_s</string></property>
###################################################
<property><ref>importother:entity_t</ref></property>
###################################################
</constructor>
</component>
</fc:compoennts>
由#符号扩起来的元素
<ref>importother:entity_t</ref>
引用path = "./othercontext.xml"下的id为entity_t的组件

2.删除组件
删除某一个组件的同时要考虑到上下文中是否存在引用他的组件,一旦删除很有可能将导致其他组件的不可用.
但以上情况是在 A -> B 但A没有缓存参数之前就删除了B才会出现.
这种情况下的没有问题是针对上下文引用他的组件而言,对于容器的客户来讲删除一个组件之后,是会带来影响的.


============================================================
容器引用了 sc.utils 包
sc.utils 我的Blog里面有
 类似资料: