package li.ioc;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import li.annotation.Inject;
import li.model.Bean;
import li.util.Files;
import li.util.Log;
import li.util.Reflect;
import li.util.Verify;
/**
* Ioc加载器,加载用注解方式配置的Bean
*
* @author li (limingwei@mail.com)
* @version 0.1.2 (2012-05-08)
*/
public class AnnotationIocLoader {
private static final Log log = Log.init();
private static final String CLASS_REGEX = "^.*\\.class$";
/**
* 扫描 Source Floder 下的所有类文件, 将其中加了@Bean注解的类返回,然后被加入到IocContext
*/
public List<Bean> getBeans() {
List<String> fileList = this.getClasseFiles();
List<li.model.Bean> beans = new ArrayList<li.model.Bean>();
for (String classFileName : fileList) {
try {
Class<?> type = Reflect.getType(getClassName(classFileName));
li.annotation.Bean beanAnnotation = type.getAnnotation(li.annotation.Bean.class);
if (beanAnnotation != null) {
li.model.Bean iocBean = new li.model.Bean();// 一个新的Bean
iocBean.type = type;
iocBean.name = beanAnnotation.value();
List<Field> fields = Reflect.getFields(type);
for (Field field : fields) {
Inject inject = field.getAnnotation(Inject.class);
if (null != inject) {
li.model.Field attribute = new li.model.Field();// 一个新的Field
attribute.name = field.getName();
attribute.type = field.getType();
attribute.value = inject.value();
iocBean.fields.add(attribute);
}
}
beans.add(iocBean);
log.debug("ADD BEAN: @Bean ? ?", type.getName(), iocBean.name);
}
} catch (Throwable e) {} // class not found 啥的,太多了,就先不打日志了
}
log.info("? ioc beans by annotation found", beans.size());
return beans;
}
/**
* 取/classes/之后的字符串(如果有/classes/的话),替换/为.,去掉.class
*/
static String getClassName(String classFileName) {
int classesIndex = classFileName.indexOf(File.separator + "classes" + File.separator);
return classFileName.substring(classesIndex > 0 ? classesIndex + 9 : 0, classFileName.length() - 6).replace('/', '.').replace('\\', '.');
}
/**
* 获取所有类文件,从class和jar
*/
static List<String> getClasseFiles() {
File rootFolder = Files.root();
List<String> classFileList = Files.list(rootFolder, CLASS_REGEX, true, 1);
log.info("Found ? class files, at ?", classFileList.size(), rootFolder);
classFileList.addAll(getClassFilesInJar());
return classFileList;
}
/**
* 获取jar里面的类
*/
private static List<String> getClassFilesInJar() {
String annotationInJar = Files.config().getProperty("annotationInJar", "");
try {
log.info("annotationInJar=?", annotationInJar);
String[] annotationInJarClasses = annotationInJar.split(",");
List<String> classFileList = new ArrayList<String>();
for (String annotationInJarClass : annotationInJarClasses) {
if (Verify.isEmpty(annotationInJarClass)) {
continue;
}
String jarFilePath = Reflect.getType(annotationInJarClass).getProtectionDomain().getCodeSource().getLocation().getFile();
if (!jarFilePath.endsWith(".jar")) {
log.info("? is not in jar but in ?", annotationInJarClass, jarFilePath);
continue;
}
log.info("Looking for class files of ? in ?", annotationInJarClass, jarFilePath);
JarFile jarFile = new JarFile(jarFilePath);
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = (JarEntry) entries.nextElement();
if (!jarEntry.isDirectory()) {
String entryName = jarEntry.getName();
if (entryName.endsWith(".class")) {
classFileList.add(entryName);
}
}
}
}
log.info("Found ? class files in jar of ?", classFileList.size(), annotationInJar);
return classFileList;
} catch (Exception e) {
throw new RuntimeException("annotationInJar=" + annotationInJar + " " + e + " ", e);
}
}
}