阅读量:3
gitee地址(需要自取)ioc_Imitation: 简单仿写IOC (gitee.com)
项目目录结构
Autowired
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Autowired { }
Component
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Component { }
HydService
@Component public class HydService { public void test() { System.out.println("成功调用service方法"); } }
HydIOC
public class HydIOC { // 包名加类名(没有.java后缀) private List<String> bean_names; // 全类路径 private List<String> file_paths; // main方法路径 private String base_path; // 包名 private String base_package; // 放类实例 private Map<String,Object> beans = new HashMap<>(); public HydIOC(String basepath, String basepackage) { // 处理basepath和basepackage // basepath:/D:/javacode/myIOC/out/production/myIOC/com/hyd/springIOC/ // 处理成:D:\javacode\myIOC\out\production\myIOC\com\hyd\springIOC\ basepath=basepath.substring(1).replace("/","\\"); this.base_path=basepath; // 形如:com.hyd.springIOC this.base_package=basepackage; try{ // 扫描文件 scan_files(); } catch (FileNotFoundException e) { e.printStackTrace(); } // 获取实例的名称集合 this.bean_names = new ArrayList<>(); init_bean_names(); } /** * 生成bean_names */ private void init_bean_names() { for (String file_path : this.file_paths) { file_path = file_path.replace(this.base_path,""); if (file_path.endsWith(".class")){ file_path = file_path.substring(0,file_path.length()-6); } String bean_name = this.base_package + "." + file_path.replaceAll(Matcher.quoteReplacement(File.separator),"."); this.bean_names.add(bean_name); } } /** * 扫描当前路径下的文件 */ private void scan_files() throws FileNotFoundException { File file = new File(this.base_path); this.file_paths = new ArrayList<>(); if (file.exists()){ // 新建一个用来处理文件的队列 LinkedList<File> file_lists = new LinkedList<>(); file_lists.add(file); while (!file_lists.isEmpty()){ // 取出一个文件进行处理 File temp_file = file_lists.removeFirst(); if (temp_file!=null){ // 判断是否为文件夹 if (temp_file.isDirectory()){ // 是文件夹就把其子文件放到队列中 File[] files = temp_file.listFiles(); for (File file1 : files) { file_lists.add(file1); } }else { // 不是文件夹就把文件路径放到路径列表中 this.file_paths.add(temp_file.getPath()); } }else { continue; } } }else { throw new FileNotFoundException("找不到"+this.base_path+"路径下的文件"); } } public void initBeans() { for (String bean_name : this.bean_names) { try{ Class<?> cl = Class.forName(bean_name); // 获取类的全部注解 Annotation[] annotations = cl.getDeclaredAnnotations(); // 判断所有注解汇中是否有Component注解 for (Annotation annotation : annotations) { if (annotation instanceof Component){ // 有就把实例化对象放到map中 Object o = cl.newInstance(); this.beans.put(cl.getName(),o); } } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } // 处理Autowired注解的注入 // 遍历map所有的实例 for (Map.Entry<String, Object> entry : this.beans.entrySet()) { // 获取实例中的域 Field[] fields = entry.getValue().getClass().getDeclaredFields(); // 遍历所有的域 for (Field field : fields) { // 获取域的注解 Annotation[] annotations = field.getDeclaredAnnotations(); // 遍历注解 for (Annotation annotation : annotations) { // 判断注解中是否有Autowired注解 if (annotation instanceof Autowired){ // filed样例值:private com.hyd.springIOC.service.HydService com.hyd.springIOC.controller.HydController.hydService // name样例值:com.hyd.springIOC.service.HydService String name = field.getType().getName(); // 从map中获取对应的实例 Object o = this.beans.get(name); // 设置字段为可访问状态 field.setAccessible(true); try { // 将获取的对象实例 o 注入到当前字段所属的对象实例中 field.set(entry.getValue(),o); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } } } // 对外获取实例的方法 public Object getInstance(String name) { return this.beans.get(name); } }
HydController
@Component public class HydController { @Autowired private HydService hydService; public void hydtest(){ hydService.test(); } }
Main
public class Main { public static void main(String[] args) { String basepath = Main.class.getResource("").getPath(); // 获取Main的包名 String basepackage = Main.class.getPackage().getName(); HydIOC hydIOC = new HydIOC(basepath,basepackage); hydIOC.initBeans(); HydController hydController = (HydController) hydIOC.getInstance(HydController.class.getName()); hydController.hydtest(); } }
整体与之前的仿写MVC的思路相差不大,不做过多描述