KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfox > ioc > factory > ConstrComponentFactory


1 /* JFox, the OpenSource J2EE Application Server
2  *
3  * Distributable under GNU LGPL license by gun.org
4  * more details please visit http://www.huihoo.org/jfox
5  */

6
7 package org.jfox.ioc.factory;
8
9 import java.lang.reflect.Constructor JavaDoc;
10 import java.lang.reflect.Modifier JavaDoc;
11
12 import org.jfox.ioc.Component;
13 import org.jfox.ioc.ComponentName;
14 import org.jfox.ioc.Registry;
15 import org.jfox.ioc.depend.Dependency;
16 import org.jfox.ioc.exception.ComponentException;
17 import org.jfox.ioc.ext.InstantiatedComponent;
18 import org.jfox.ioc.util.Classes;
19
20 /**
21  * 构造器组件工厂。根据注册组件时提供的参数,构造组件实例,并注射其依赖的组件。
22  * <br>
23  * 如果以组件类来注册组件,且只设置了构造器参数,系统会自动给组件使用该ComponentFactory。
24  * 如果注册组件时构造器参数为 null,系统会自动使用一个构造器,此时要求组件有且只有一个构造器。
25  * 如果要使用无参数的构造器,那么注册时构造器的参数应该为 Parameter[0]。
26  *
27  * @author <a HREF="mailto:young_yy@hotmail.com">Young Yang</a>
28  */

29
30 public class ConstrComponentFactory extends ComponentFactory {
31     /**
32      * 构造器参数列表
33      */

34     private Dependency[] constrParams;
35     /**
36      * 组件类
37      */

38     private Class JavaDoc implementation;
39     /**
40      * 组件注册到 Registry 中的名称
41      */

42     private ComponentName compName;
43     /**
44      * IoC 容器注册器
45      */

46     private Registry registry;
47
48     /**
49      * 组件是否正实例化,用来判断循环依赖
50      */

51     private boolean instantiating = false;
52     /**
53      * 构造器
54      */

55     private Constructor JavaDoc constructor;
56
57     /**
58      * 使用组件注册名称和构造器参数进行构造ComponentFactory。
59      * ComponentName中包含有组件类名。
60      * 在使用指定的ComponentName注册组件时,会用这个构造器来初始化ComponentFactory
61      *
62      * @param name 组件注册的名称
63      * @param constrParams 构造器参数
64      */

65     public ConstrComponentFactory(ComponentName name, Class JavaDoc implementation, Dependency[] constrParams) throws ComponentException {
66         this.constrParams = constrParams;
67         this.implementation = implementation;
68         checkImplementation(implementation);
69         setComponentName(name);
70         constructor = getContructor();
71     }
72
73     protected ConstrComponentFactory(Component comp) {
74         this.constrParams = Dependency.EMPTY_PARAMETERS;
75         this.implementation = comp.getClass();
76         setComponentName(ComponentName.newInstance(comp.getClass()));
77         constructor = null;
78     }
79
80     /**
81      * 生成组件实例。
82      * <br>
83      * 如果构造器参数为null,那么系统会默认该组件只有一个构造器,取出该构造器之后,
84      * 并根据构造器参数的类型自动取得对应的依赖组件。
85      * <pre>
86      * registry.registerComponent(TestComponent.class)
87      *
88      * or
89      *
90      * registry.registerComponent(TestComponent.class,null)
91      * </pre>
92      * <br>
93      * 如果构造器参数为empty (new Paramter[0]),系统则使用没有参数的构造器。
94      * <pre>
95      * registry.registerComponent(TestComponent.class,new Parameter[0])
96      *
97      * or
98      *
99      * registry.registerComponent(TestComponent.class,new Parameter[0],null)
100      * </pre>
101      *
102      * @return
103      * @throws org.jfox.ioc.exception.ComponentException
104      */

105     public Component makeComponent() throws ComponentException {
106         if(instantiating == true) {
107             throw new ComponentException("cycle depencies in component " + getImplementation().getName());
108         }
109         instantiating = true;
110
111         try {
112             Dependency[] params = getParameters();
113             Object JavaDoc[] paramValues = new Object JavaDoc[]{};
114             if(params != null) {
115                 paramValues = resolveParameters(params);
116             }
117             Component comp = instantiateComponent(constructor, paramValues);
118
119             if(comp instanceof InstantiatedComponent) {
120                 comp = ((InstantiatedComponent) comp).afterInstantiate(comp);
121             }
122
123             return comp;
124         }
125         finally {
126             instantiating = false;
127         }
128
129     }
130
131     /**
132      * 得到组件注册名称
133      */

134     public ComponentName getComponentName() {
135         return compName;
136     }
137
138     /**
139      * 设置组件注册名称
140      */

141     protected void setComponentName(ComponentName compName) {
142         this.compName = compName;
143     }
144
145     /**
146      * 得到组件类
147      */

148     public Class JavaDoc getImplementation() {
149         return implementation;
150     }
151
152     /**
153      * 得到组件注册的Registry
154      * @return
155      */

156     public Registry getRegistry() {
157         return registry;
158     }
159
160     /**
161      * 设置组件注册的Registry
162      * @param registry
163      */

164     public void setRegistry(Registry registry) {
165         this.registry = registry;
166     }
167
168     /**
169      * 得到用于组件构造器的参数
170      * @return
171      */

172     public Dependency[] getParameters() {
173         return constrParams;
174     }
175
176     private Constructor JavaDoc getContructor() throws ComponentException {
177         // not specified, must have only 1 constructor
178
// then, auto build the ParamPack
179
Class JavaDoc[] types = getParameterTypes(constrParams);
180
181         Constructor JavaDoc constructor = null;
182         try {
183             constructor = Classes.getConstructor(implementation, types);
184         }
185         catch(NoSuchMethodException JavaDoc e) {
186             throw new ComponentException(e);
187         }
188         return constructor;
189     }
190
191     /**
192      * 实现具体构造组件实例的过程
193      * @param constructor
194      * @param params
195      * @return
196      * @throws ComponentException
197      */

198     protected Component instantiateComponent(Constructor JavaDoc constructor, Object JavaDoc[] params) throws ComponentException {
199         try {
200             Object JavaDoc comp = constructor.newInstance(params);
201             return (Component) comp;
202         }
203         catch(Exception JavaDoc e) {
204             throw new ComponentException("instantiate component error " + getImplementation().getName(), e);
205         }
206     }
207
208     /**
209      * 检查 implementation 的有效性
210      *
211      * @param implementation
212      * @throws org.jfox.ioc.exception.ComponentException
213      */

214     private static void checkImplementation(Class JavaDoc implementation) throws ComponentException {
215         if(!Component.class.isAssignableFrom(implementation)) {
216             throw new ComponentException("component implementation " + implementation.getName() + " is not a valid component, because it not implements " + Component.class.getName());
217         }
218
219         // Assert that the component class is concrete.
220
boolean isAbstract = (implementation.getModifiers() & Modifier.ABSTRACT) == Modifier.ABSTRACT;
221         boolean isPrivate = (implementation.getModifiers() & Modifier.PRIVATE) == Modifier.PRIVATE;
222         boolean isProtected = (implementation.getModifiers() & Modifier.PROTECTED) == Modifier.PROTECTED;
223         if(implementation.isInterface() || isAbstract) {
224             throw new ComponentException("component implementation is not a concrete class " + implementation.getName());
225         }
226         if(isPrivate || isProtected) {
227             throw new ComponentException("component implementation is a private or protected class " + implementation.getName());
228         }
229     }
230
231 }
232
233
Popular Tags