自定义一个IOC容器

开始之前我们先要清楚一个事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版权协议,转载请附上原文出处链接和本声明。