zoukankan      html  css  js  c++  java
  • 手写简单IOC

    ReflectUtils.java (反射工具类)
    package top.icss.ioc;
    
    import java.io.File;
    import java.io.FileFilter;
    import java.io.IOException;
    import java.net.JarURLConnection;
    import java.net.URL;
    import java.net.URLDecoder;
    import java.util.ArrayList;
    import java.util.Enumeration;
    import java.util.List;
    import java.util.jar.JarEntry;
    import java.util.jar.JarFile;
    
    /**
     * @author cd
     * @desc 反射工具类
     * @create 2020/3/26 11:30
     * @since 1.0.0
     */
    public class ReflectUtils {
    
        /**
         * 是否循环迭代
         */
        private final static boolean recursive = true;
    
        /**
         * 扫描 包下面所有Class
         * @param packageName 包名称
         * @param <T>
         * @return
         */
        public static <T> List<Class<T>> getClass(String packageName){
            List<Class<T>> list = new ArrayList<>();
    
            String packageNamePath = packageName;
            packageNamePath = packageNamePath.replace(".", "/");
    
            Enumeration<URL> resources;
            try {
                //定义一个枚举的集合 并进行循环来处理这个目录下的things
                resources = Thread.currentThread().getContextClassLoader().getResources(packageNamePath);
                //循环迭代
                while (resources.hasMoreElements()){
                    URL url = resources.nextElement();
                    //得到协议的名称
                    String protocol = url.getProtocol();
                    //如果是以文件的形式保存在服务器上
                    if("file".equals(protocol)){
                        System.err.println("file类型的扫描");
                        String filePath = URLDecoder.decode(url.getFile(), "utf-8");
                        // 获取此包的目录 建立一个File
                        File dir = new File(filePath);
                        list.addAll(getClass(dir, packageName));
                    }
                }
    
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
            return list;
        }
    
        /**
         * 迭代查找文件类
         * @param filePath
         * @param packageName
         * @param <T>
         * @return
         */
        private static <T> List<Class<T>> getClass(File filePath, String packageName){
            List<Class<T>> classes = new ArrayList<>();
            if(!filePath.exists()){
                return classes;
            }
    
            // 如果存在 就获取包下的所有文件 包括目录
            File[] files = filePath.listFiles(new FileFilter() {
                //自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
                @Override
                public boolean accept(File file) {
                    return (recursive && file.isDirectory())
                            || file.getName().endsWith(".class");
                }
            });
    
            for (File file : files){
                // 如果是目录 则继续扫描
                if(file.isDirectory()){
                    classes.addAll(getClass(file, packageName + "." + file.getName()));
                }else {
                    // 如果是java类文件 去掉后面的.class 只留下类名
                    String fileName = file.getName();
                    String className = fileName.substring(0, fileName.length() - 6);
                    className = packageName + "." + className;
                    try {
                        //这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净
                        //Class<T> cls = (Class<T>) Class.forName(className);
                        Class<T> cls = (Class<T>) Thread.currentThread().getContextClassLoader().loadClass(className);
                        classes.add(cls);
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
    
            }
    
            return classes;
        }
    public static void main(String[] args) {
            getClass("top.icss");
        }
    }
    MyService.java MyAutowired.java (注解类)
    package top.icss.ioc.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * @author cd
     * @desc
     * @create 2020/3/26 14:57
     * @since 1.0.0
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface MyService {
    
        String value() default "";
    }
    package top.icss.ioc.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * @author cd
     * @desc 自动注入
     * @create 2020/3/26 14:59
     * @since 1.0.0
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface MyAutowired {
    
        String value() default "";
    }
    IocContainer.java (IOC容器)
    package top.icss.ioc;
    
    import top.icss.ioc.annotation.MyAutowired;
    import top.icss.ioc.annotation.MyService;
    
    import java.lang.reflect.AccessibleObject;
    import java.lang.reflect.Field;
    import java.util.LinkedHashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * @author cd
     * @desc ioc容器
     * @create 2020/3/26 14:48
     * @since 1.0.0
     */
    public class IocContainer {
    
        private Set<Class<?>> clss = new LinkedHashSet<Class<?>>();
        private Map<String, Object> beans = new ConcurrentHashMap<String, Object>();
    
        /**
         * 获取类上 @MyService的注解类
         *
         * @param packageName
         */
        public void doScanner(String packageName) {
            List<Class<Object>> list = ReflectUtils.getClass(packageName);
            for (Class cls : list) {
                boolean service = cls.isAnnotationPresent(MyService.class);
                if (service) {
                    clss.add(cls);
                }
            }
        }
    
        /**
         * 将class中的类实例化,经key-value:类名(小写)-类对象放入ioc字段中
         */
        public void doInstance() {
            for (Class cls : clss) {
                if (cls.isAnnotationPresent(MyService.class)) {
                    MyService myService = (MyService) cls.getAnnotation(MyService.class);
                    String beanName = "";
                    if(cls.isInterface()){
                        beanName = cls.getName();
                    }else {
                        beanName = ("".equals(myService.value().trim())) ? toLowerFirstWord(cls.getSimpleName()) : myService.value();
                    }
                    try {
    
                        Object instance = cls.newInstance();
                        beans.put(beanName, instance);
    
                        Class[] interfaces = cls.getInterfaces();
                        for (Class<?> i:interfaces){
                            beans.put(i.getName(), instance);
                        }
    
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
    
                }
            }
        }
    
        /**
         * 自动化的依赖注入
         */
        public void doAutowired(){
            if(beans.isEmpty()){
                return;
            }
    
            try {
                Set<Map.Entry<String, Object>> entries = beans.entrySet();
                for (Map.Entry<String, Object> entry: entries){
                    Class<?> cls = entry.getValue().getClass();
    
                    Field[] fields = cls.getDeclaredFields();
                    //强制获取私有字段
                    AccessibleObject.setAccessible(fields,true);
                    for (Field f: fields){
                        if(!f.isAnnotationPresent(MyAutowired.class)){
                            continue;
                        }
    
                        MyAutowired myAutowired = f.getAnnotation(MyAutowired.class);
                        String beanName = "";
                        Class icls = f.getType();
                        if(icls.isInterface()){
                            beanName = icls.getName();
                        }else {
                            beanName = ("".equals(myAutowired.value().trim())) ? toLowerFirstWord(icls.getName()) : myAutowired.value();
                        }
                        //获取当前类实例
                        Object obj = entry.getValue();
                        //容器中获取字段实例
                        Object value = beans.get(beanName);
    
                        f.set(obj, value);
    
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
        /**
         * 获取实例
         * @param cls
         * @param <T>
         * @return
         */
        public <T> T getBean(Class<?> cls){
            MyService myService = cls.getAnnotation(MyService.class);
            String beanName = "";
            if(cls.isInterface()){
                beanName = cls.getName();
            }else {
                beanName = ("".equals(myService.value().trim())) ? toLowerFirstWord(cls.getSimpleName()) : myService.value();
            }
    
            return (T) beans.get(beanName);
        }
    
        /**
         * 将字符串首字母转换为小写
         * @param name
         * @return
         */
        private String toLowerFirstWord(String name) {
            char[] charArray = name.toCharArray();
            charArray[0] += 32;
            return String.valueOf(charArray);
        }
    }

      测试

    Service1.java Service2.java (接口类)
    public interface Service1 {
    
        public void print1();
    }
    
    
    public interface Service2 {
        public void print2();
    }
    Service1Impl.java Service2Impl.java (实现类)
    package top.icss.ioc.test.impl;
    
    import top.icss.ioc.annotation.MyAutowired;
    import top.icss.ioc.annotation.MyService;
    import top.icss.ioc.test.Service1;
    import top.icss.ioc.test.Service2;
    
    /**
     * @author cd
     * @desc
     * @create 2020/3/26 15:45
     * @since 1.0.0
     */
    @MyService
    public class Service1Impl implements Service1 {
    
        @MyAutowired
        private Service2 service2;
    
        @Override
        public void print1() {
            service2.print2();
        }
    }
    package top.icss.ioc.test.impl;
    
    import top.icss.ioc.annotation.MyAutowired;
    import top.icss.ioc.annotation.MyService;
    import top.icss.ioc.test.Service1;
    import top.icss.ioc.test.Service2;
    
    /**
     * @author cd
     * @desc
     * @create 2020/3/26 15:45
     * @since 1.0.0
     */
    @MyService
    public class Service2Impl implements Service2 {
    
        @MyAutowired
        private Service1 service1;
    
    
        @Override
        public void print2() {
            System.out.println("print2");
        }
    }
    IocTest.java (测试类)
    public class IocTest {
    
        public static void main(String[] args) throws InterruptedException {
            IocContainer ioc = new IocContainer();
            ioc.doScanner("top.icss.ioc.test");
            ioc.doInstance();
            ioc.doAutowired();
    
            Service2 bean = ioc.getBean(Service2Impl.class);
            bean.print2();
    
    
        }
    }
  • 相关阅读:
    第八章 多线程编程
    Linked List Cycle II
    Swap Nodes in Pairs
    Container With Most Water
    Best Time to Buy and Sell Stock III
    Best Time to Buy and Sell Stock II
    Linked List Cycle
    4Sum
    3Sum
    Integer to Roman
  • 原文地址:https://www.cnblogs.com/iathanasy/p/12575706.html
Copyright © 2011-2022 走看看