实现Spring的IOC机制,当然这里面没有对类进行注解标示(类似Spring的@Service,@Configuration,@Controller),而是对全部类进行装载,可以自定义注解后通过class.getAnnotations()获取并筛选装载。
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import com.google.gson.Gson;
public class PackageLoader {
/**类实例映射**/
private static final Map<Class<?>, Object> MAP = new HashMap<Class<?>, Object>();
public static void main(String[] args) {
try {
String packageName = "com.google";
load(packageName);
Gson o = getBean(Gson.class);
System.out.println(o.getClass().getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 从已经装载的类中获取指的的实例
* @param clazz
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(Class<T> clazz){
Object object = MAP.get(clazz);
return (T) object;
}
/**
* 装载类
* @param packageName
* @return
* @throws ClassNotFoundException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws IOException
*/
public static void load(String packageName) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException{
List<String> classNames = classNames(packageName);
for(String cn : classNames){
Class<?> clazz = Class.forName(cn);
if(Modifier.isAbstract(clazz.getModifiers()) || Modifier.isInterface(clazz.getModifiers())){//抽象类和接口去掉
continue;
}
Constructor<?>[] dcs = clazz.getDeclaredConstructors();
boolean noArgsConst = false;
for(Constructor<?> c : dcs){
if(c.getParameterTypes().length == 0 && Modifier.isPublic(c.getModifiers())){
noArgsConst = true;
break;
}
}
if(!noArgsConst){//没有public的无参构造方法的去掉
continue;
}
Object object = clazz.newInstance();
MAP.put(clazz, object);
}
}
/**
* 获取包下面的说有类名
* @param packageName
* @return
* @throws IOException
*/
private static List<String> classNames(String packageName)throws IOException {
String packageDirName = packageName.replace('.', '/');
Enumeration<URL> resources = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
List<String> classes = new ArrayList<String>();
while(resources.hasMoreElements()){
URL url = resources.nextElement();
String protocol = url.getProtocol();
if("jar".equals(protocol)){//项目引用的第三方jar文件
JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile();
classesFromJar(jar, packageName, classes);
}
if("file".equals(protocol)){//项目自身pachage的.class文件
String packagePath = URLDecoder.decode(url.getFile(), "UTF-8");
classesFromFile(packagePath,packageName, classes);
}
}
return classes;
}
/**
* 从自身pachage中的.class获取类名
* @param packagePath
* @param packageName
* @param classes
*/
private static void classesFromFile(String packagePath,String packageName,List<String> classes){
File dir = new File(packagePath);
if (!dir.exists() || !dir.isDirectory()) {
return;
}
File[] files = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isDirectory() || pathname.getName().endsWith(".class");
}
});
for(File file : files){
if(file.isDirectory()){
classesFromFile(file.getAbsolutePath(), packageName + "." + file.getName(), classes);
}else{
classes.add(packageName + "." + file.getName().replace(".class", ""));
}
}
}
/**
* 从引用的第三方jar中的.class获取类名
* @param jar
* @param packageName
* @param classes
*/
private static void classesFromJar(JarFile jar,String packageName,List<String> classes){
Enumeration<JarEntry> entries = jar.entries();
while(entries.hasMoreElements()){
JarEntry entry = entries.nextElement();
String name = entry.getName();
if(!name.replace("/", ".").startsWith(packageName) || !name.endsWith(".class")){
continue;
}
classes.add(name.replace("/", ".").replace(".class", ""));
}
}
}
网友评论