开始之前我们先要清楚一个事IOC容器是干什么用的,IOC容器是控制对象的生成,维护对象之间的关系。在不适用IOC容器时我们使用对象,比如A需要B对象上的show方法,是在A对象中持有B对象的实例然后再调用它上面的show方法。而采用IOC容器我们可以结合注解使用
扫描包的工具类
package cn.yc.myspring.ioc.utils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/***
* 扫描包下类的工具类
*/
public abstract class ScannerClass {
/***
**参数1 要扫描包的完整路径 要扫描包的名称(cn.itcast.manage)
**返回参数 该包下面所有的类的全名称
**/
public static List<String> parseClassName(String packageName) {
List<String> array = new ArrayList<>();
String packagePath = resovlePackagePath(packageName);
File root = new File(packagePath);
resolveFile(root, packageName, array);
return array;
}
/***
**参数 包名(cn.itcast.manage)
**返回参数 该包的全路径
**/
private static String resovlePackagePath(String packageName) {
//扫码所有的包并把其放入到访问关系和方法放入到内存中
File f = new File(ScannerClass.class.getResource("/").getPath());
String totalPath = f.getAbsolutePath();
String pageName = ScannerClass.class.getPackage().getName().replace(".","\\");
totalPath = totalPath.replace(pageName,"");
String packagePath = packageName.replace(".","\\");
totalPath=totalPath+"\\"+packagePath;
return totalPath;
}
private static void resolveFile(File root, String packageName, List<String> classNames) {
if (!root.exists())
return;
File[] childs = root.listFiles();
if (childs != null && childs.length > 0) {
for (File child : childs) {
if (child.isDirectory()) {
String parentPath = child.getParent();
String childPath = child.getAbsolutePath();
String temp = childPath.replace(parentPath, "");
temp = temp.replace("\\", "");
resolveFile(child, packageName + "." + temp, classNames);
} else {
String fileName = child.getName();
if (fileName.endsWith(".class")) {
String name = fileName.replace(".class", "");
String className = packageName + "." + name;
classNames.add(className);
}
}
}
}
}
}
IOC容器核心类
package cn.yc.myspring.ioc.cache; import cn.yc.myspring.ioc.annotation.Autower; import cn.yc.myspring.ioc.define.BeanDefinition; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; public class MyIOCCache { private Map<String,BeanDefinition> defineMap = new HashMap<>(); private Map<String,Object> beanMap = new HashMap<>(); private MyIOCCache(){ } public void put(String name,Class clazz){ if(name==null||name.equals("")){ name = clazz.getInterfaces()[0].getSimpleName(); } if(name==null) name = clazz.getSimpleName(); if(name.startsWith("I")){ name = name.substring(1); } char temp = name.charAt(0); if(temp>='A'&&temp<='Z'){ name = name.substring(0,1).toLowerCase()+name.substring(1); } BeanDefinition beanDefinition = new BeanDefinition(); beanDefinition.setBeanClass(clazz); beanDefinition.setFields(clazz.getDeclaredFields()); defineMap.put(name,beanDefinition); } public <T> T getBean(Class clazz){ return getBean("",clazz); } public <T> T getBean(String name,Class clazz){ try { if (name == null || name.equals("")) name = clazz.getSimpleName(); Object bean = null; bean = beanMap.get(name); if (bean != null) return (T) bean; bean = resolveBean(name); beanMap.put(name,bean); return (T) bean; }catch (Exception e){ throw new RuntimeException(e); } } private Object resolveBean(String name)throws Exception{ Object bean = beanMap.get(name); if(bean==null){ BeanDefinition beanDefinition = defineMap.get(name); Class beanClass = beanDefinition.getBeanClass(); Field[] fields = beanDefinition.getFields(); bean = beanClass.newInstance(); if(fields!=null){ for(Field field:fields){ Autower autower = field.getAnnotation(Autower.class); if(autower==null) continue;; String autowerName = autower.value(); if(autowerName==null||autowerName.equals("")) autowerName = field.getName(); System.out.println(autowerName); Object attrBean = resolveBean(autowerName); field.setAccessible(true); field.set(bean,attrBean); } } beanMap.put(name,bean); } return bean; } public static MyIOCCache getInstance(){ return Inner.instance; } private static class Inner{ private static MyIOCCache instance = new MyIOCCache(); } }
初始化类public class BeanInit { public static void init(String packageName) throws Exception { List<String> classNames = ScannerClass.parseClassName(packageName); MyIOCCache instance = MyIOCCache.getInstance(); if(classNames!=null){ for (String className:classNames){ Class clazz = Class.forName(className); Component component = (Component) clazz.getAnnotation(Component.class); if(component!=null){ instance.put(component.value(),clazz); } } } } }
自定义注解import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Autower { String value() default ""; }
使用import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Component { String value() default ""; }
private static void test1() { try { BeanInit.init("cn.yc.myspring.ioc.manage"); MyIOCCache cache = MyIOCCache.getInstance(); IStudentService studentService = cache.getBean("studentService", IStudentService.class); Student student = new Student(); student.setName("test"); student.setContent("呵呵呵"); studentService.say(student); IStudentDao studentDao = cache.getBean("studentDao", IStudentDao.class); studentDao.say(student); System.out.println(studentDao); } catch (Exception e) { e.printStackTrace(); } }
只需要在要IOC的容器类添加@Componet注解在里面成员变量需要的字段添加@Autower注解
版权声明:本文为yinbucheng原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。