package dynamicConfiguration;
/*
*主类(author by qiangliu)
*/
public class DynamicClassTest {
public static void main(String[] args) {
Configutaion conf = new Configutaion(System.getProperty("user.dir")+"\\src\\class-config.xml") ;
Printer pr = conf.newPrintInstance() ;
pr.print();
}
}
/*
*
*/
package dynamicConfiguration;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class Configutaion {
private static Hashtable<String, String> classMap = new Hashtable<String, String>();
private static final Class<?>[] EMPTY_ARRAY = new Class[] {};
private static final Map<Class<?>, Constructor<?>> CONSTRUCTOR_CACHE = new HashMap<Class<?>, Constructor<?>>(); // 类构造器缓存
static {
ClassLoader cL = Thread.currentThread().getContextClassLoader();
if (cL.getResource("config.xml") != null) {
System.out.println("config.xml find! ");
}
}
private static ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
public Configutaion(String filePath) {
getClassNameFromXml(filePath);
}
/**
* 生成指定类的对象
*
* @param <T>
* @param theClass
* @param conf
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T newPrintInstance() {
T result;
try {
String printClassName = classMap.get("printer") ;
Class<?> printClass = Class.forName(printClassName, true, classLoader);
Constructor<T> meth = (Constructor<T>) CONSTRUCTOR_CACHE.get(printClass);
if (meth == null) {
meth = (Constructor<T>) printClass.getConstructor(EMPTY_ARRAY);//通过类对象的getConstructor()或getDeclaredConstructor()方法获得构造器
}
result = meth.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
return result;
}
/**
* 解析并保存xml文件的配置参数
* @param path
*/
@SuppressWarnings("unused")
private void getClassNameFromXml(String path) {
try {
InputStream xmlIns = new FileInputStream(path);
if (xmlIns == null) {
return ;
}
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = docBuilderFactory.newDocumentBuilder();
Document doc = builder.parse(xmlIns);
Element root = doc.getDocumentElement();
NodeList props = root.getChildNodes();
for (int i = 0; i < props.getLength(); i++) {
Node propNode = props.item(i);
if (!(propNode instanceof Element))
continue;
Element prop = (Element) propNode;
if ("class".equals(prop.getTagName())) {
String classname = prop.getAttribute("name");
String value = prop.getAttribute("value");
if (classname != null && value != null) {
classMap.put(classname, value);
}
}
}
if (xmlIns != null) { //关闭流
xmlIns.close() ;
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
package dynamicConfiguration;
public interface Printer {
public void print() ;
}
package dynamicConfiguration;
public class Printer1 implements Printer {
public Printer1() {
}
public void print() {
System.out.println("I'm Printer1! ");
}
}
package dynamicConfiguration;
public class Printer2 implements Printer {
public Printer2() {
}
public void print() {
System.out.println("I'm Printer2! ");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
<class name="printer" value="dynamicConfiguration.Printer1">
</class>
-->
<class name="printer" value="dynamicConfiguration.Printer2">
</class>
</configuration>