美文网首页java高级课件
反射学习之——IOC小案例

反射学习之——IOC小案例

作者: IT楠老师 | 来源:发表于2020-05-03 22:20 被阅读0次

    反射小练习

    一、注解定义

    package com.xinzhi.Annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * 自动注入的注解
     * @author zn
     * @date 2020/4/2
     **/
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AutoWired {
    }
    
    
    package com.xinzhi.Annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * @author zn
     * @date 2020/4/2
     **/
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Bean {
    }
    

    2、扫描文件解析注解,容器初始化

    package com.xinzhi.reflect;
    
    import com.xinzhi.Annotation.AutoWired;
    import com.xinzhi.Annotation.Bean;
    
    import java.io.File;
    import java.io.InputStream;
    import java.lang.reflect.Field;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Properties;
    import java.util.Set;
    
    /**
     * @author zn
     * @date 2020/4/2
     **/
    public class ApplicationContext<T> {
    
        private HashMap<Class,Object> beanFactory = new HashMap<>();
        private String filePath;
    
        //获取容器的bean
        public T getBean(Class clazz){
            return (T)beanFactory.get(clazz);
        }
    
        //初始化容器
        public void initContext(){
            InputStream resource = ApplicationContext.class.getClassLoader()
                    .getResourceAsStream("config/bean.config");
            Properties properties = new Properties();
            try {
                properties.load(resource);
                Set<Object> keys = properties.keySet();
                for (Object key : keys) {
                    beanFactory.put(Class.forName(key.toString()),
                            Class.forName(properties.getProperty(key.toString())).newInstance()  );
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
        //加载全部的类的实例
        public  void initContextByAnnotation()  {
            filePath = ApplicationContext.class.getClassLoader().getResource("").getFile();
            loadOne(new File(filePath));
            assembleObject();
        }
    
        //是不是给所有的字符赋值
        private void assembleObject() {
            for(Map.Entry<Class,Object> entry : beanFactory.entrySet()){
                //就是咱们放在容器的对象
                Object obj = entry.getValue();
                Class<?> aClass = obj.getClass();
                Field[] declaredFields = aClass.getDeclaredFields();
                for (Field field : declaredFields){
                    AutoWired annotation = field.getAnnotation(AutoWired.class);
                    if( annotation != null ){
                        field.setAccessible(true);
                        try {
                            System.out.println("正在给【"+obj.getClass().getName()+"】属性【" + field.getName() + "】注入值【"+ beanFactory.get(field.getType()).getClass().getName() +"】");
                            field.set(obj,beanFactory.get(field.getType()));
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    
        /**
         * 加载一个文件夹的类
         * @param fileParent
         */
        private  void loadOne(File fileParent) {
            if (fileParent.isDirectory()) {
                File[] childrenFiles = fileParent.listFiles();
                if(childrenFiles == null || childrenFiles.length == 0){
                    return;
                }
                for (File child : childrenFiles) {
                    if (child.isDirectory()) {
                        //如果是个文件夹就继续调用该方法,使用了递归
                        loadOne(child);
                    } else {
                        //通过文件路径转变成全类名,第一步把绝对路径部分去掉
                        //  D:\mytools
                        //  com\xinzhi\dao\UserDao.class
                        String pathWithClass = child.getAbsolutePath().substring(filePath.length() - 1);
                        //选中class文件
                        if (pathWithClass.contains(".class")) {
                            //    com.xinzhi.dao.UserDao
                            //去掉.class后缀,并且把 \ 替换成 .
                            String fullName = pathWithClass.replaceAll("\\\\", ".").replace(".class", "");
                            try {
                                Class<?> aClass = Class.forName(fullName);
    
                                //把非接口的类实例化放在map中
                                if(!aClass.isInterface()){
                                    Bean annotation = aClass.getAnnotation(Bean.class);
                                    if(annotation != null){
                                        Object instance = aClass.newInstance();
                                        //判断一下有没有接口
                                        if(aClass.getInterfaces().length > 0) {
                                            //如果有接口把接口的class当成key,实例对象当成value
                                            System.out.println("正在加载【"+ aClass.getInterfaces()[0] +"】,实例对象是:" + instance.getClass().getName());
                                            beanFactory.put(aClass.getInterfaces()[0], instance);
                                        }else{
                                            //如果有接口把自己的class当成key,实例对象当成value
                                            System.out.println("正在加载【"+ aClass.getName() +"】,实例对象是:" + instance.getClass().getName());
                                            beanFactory.put(aClass, instance);
                                        }
                                    }
                                }
                            } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:反射学习之——IOC小案例

        本文链接:https://www.haomeiwen.com/subject/lwxsghtx.html