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();
    
    
        }
    }
  • 相关阅读:
    分布式编程下的CAS
    《码农翻身》读后感
    PHP Socket服务器搭建和测试
    在Java中使用Hibernate,使用不同数据库服务名
    linq的表关系解决办法
    SilverLight中使用WCF Ria出现的问题empty domain service class
    cmd中更换用户权限
    Flex中TabBar与ViewStack
    使用ApdComPort
    拖动控件
  • 原文地址:https://www.cnblogs.com/iathanasy/p/12575706.html
Copyright © 2011-2022 走看看