public class AplicationContextAnnotationListener implements
ServletContextListener {
Map<String, Object> map = new HashMap<String, Object>();
public void contextDestroyed(ServletContextEvent event) {
}
public void contextInitialized(ServletContextEvent envent) {
InputStream in = this.getClass().getResourceAsStream("beans.xml");
SAXReader reader = new SAXReader();
Document doc = null;
try {
doc = reader.read(in);
Element root = doc.getRootElement();
String packageName = root.element("context").attributeValue("base-package");
Set<Class> classes = this.getClasses(packageName);
this.instanceBeans(classes);
this.injectObject(map);
} catch (DocumentException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
//注入属性
private void injectObject(Map<String,Object> map) {
//对已实例化并存放在map里的所有对象进行迭代 注入属性
Set<Map.Entry<String, Object>> set = map.entrySet();
Iterator<Map.Entry<String, Object>> iter = set.iterator();
while(iter.hasNext()){
Entry<String, Object> entry = iter.next();
Object bean = entry.getValue();
Class beanClass = bean.getClass();
Field[] fields = beanClass.getDeclaredFields();
//获取该bean里所有的构造方法
Constructor[] constructors = beanClass.getConstructors();
try {
//获得该对象的属性描述
PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(beanClass).getPropertyDescriptors();
for(Field field : fields){
if(field.isAnnotationPresent(Resource.class)){
String className = field.getAnnotation(Resource.class).value();
String fieldName = field.getName();
//迭代构造方法看构造方法里的参数有没有这个fileName
for(Constructor constructor : constructors){
TypeVariable[] typeVariables = constructor.getTypeParameters();
System.out.println(typeVariables.length);
for(TypeVariable typeVariable : typeVariables){
String variableName = typeVariable.getName();
System.out.println(variableName);
}
}
Object property = map.get(className);
//对属性描述进行迭代 查看标注Resource注解的属性的属性名是否与属性描述相同的
for(PropertyDescriptor propertyDescriptor : propertyDescriptors){
if(fieldName.equals(propertyDescriptor.getName())){
//获取该属性的set方法
Method method = propertyDescriptor.getWriteMethod();
if(method==null){
continue;
}
method.invoke(bean, property);
}
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
}
//获取该包及其子包的class
public Set<Class> getClasses(String packageName){
//是否允许迭代子包
boolean recursive = true;
//定义存放class的集合
Set<Class> classes = new LinkedHashSet<Class>();
String packagedir = packageName.replace(".", "/");
try {
Enumeration<URL> dirs = Thread.currentThread().getContextClassLoader().getResources(packagedir);
while(dirs.hasMoreElements()){
URL url = dirs.nextElement();
String protocol = url.getProtocol();
if("file".equals(protocol)){
//获取包的物理路径 大致是这个样子/D:/Tomcat 6.0/webapps/upload/WEB-INF/classes/com/cn/service/
//不能直接用url.getFile() 否则 结果会是/D:/Tomcat%206.0/webapps/upload/WEB-INF/classes/com/cn/service/
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
this.findAndAddClasses(packageName,filePath,classes,recursive);
}
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
} catch (IOException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
return classes;
}
public void findAndAddClasses(String packageName,String filePath,Set<Class> classes,final boolean recursive){
File dir = new File(filePath);
//看该路径是否存在 且必须是一个目录
if(!(dir.exists())||!(dir.isDirectory())){
return;
}
//对文件进行过滤 如果是子包且允许迭代或是一个class文件则不过滤
File[] dirFiles = dir .listFiles(new FileFilter() {
public boolean accept(File pathname) {
return (recursive && pathname.isDirectory())||pathname.getName().endsWith(".class");
}
});
//对文件列表进行迭代
for(File file:dirFiles ){
//如果是目录则继续进行扫描
if(file.isDirectory()){
findAndAddClasses(packageName+"."+file.getName(),file.getAbsolutePath(),classes,recursive);
}else{
//将.class去掉
String className = file.getName().substring(0, file.getName().length()-6);
try {
//加载该class文件 并将获得的Class添加进classes
classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName+"."+className));
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
}
}
public void instanceBeans(Set<Class> classes){
for(Class cls : classes){
if(cls.isAnnotationPresent(Repository.class)){
String id = ((Repository) cls.getAnnotation(Repository.class)).id();
//如果id为""则将该类名的首字母变成小写赋给id
if("".equals(id)){
id = cls.getSimpleName().substring(0,1).toLowerCase().concat(cls.getSimpleName().substring(1));
}
try {
map.put(id, cls.newInstance());
} catch (Exception e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
}
}
public Object getBean(String beanName){
return map.get(beanName);
}
//查看bean里有没有设置该属性的setter方法
public boolean hasFieldSetMethod(){
return false;
}
//查看bean里有没有设置该属性的构造方法
public boolean hasIncludeFiledConstructor(){
return false;
}
}