ioc的简单实现

来源:互联网 发布:乌克丽丽调音软件 编辑:程序博客网 时间:2024/04/30 20:57
IOC的实现主要是基于注解或者配置文件了解关系,缓存被依赖类,在访问时实时构建.

主要实现类:

package iocTest;import java.io.File;import java.io.IOException;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.util.ArrayList;import java.util.Collections;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import java.util.function.Consumer;import java.util.function.Function;import java.util.stream.Collectors;import org.apache.commons.io.FileUtils;import org.apache.commons.lang3.ArrayUtils;import org.apache.commons.lang3.StringUtils;import com.alibaba.fastjson.JSON;public class BootStrap {    public static void main(String[] args) {        loadConfig();        createBeanCache();        // invoke("testAction", "say", "Hello World!");        // invokeInParallel("testAction", "say", "Hello World!", 100);    }    public static IocConfig iocConfig;    public static Map<String, IocRely> unmodifiableMap;    public static Map<String, Object> cachedObject;    @SuppressWarnings("unchecked")    private static void loadConfig() {        String content = null;        try {            content = FileUtils.readFileToString(new File("config/iocTest.json"), "utf-8");        } catch (IOException e) {            e.printStackTrace();        }        if (StringUtils.isEmpty(content)) {            throw new Error();        }        Map<String, Object> iocConfigMap = JSON.parseObject(content);        Boolean isAutoLoad = (Boolean) iocConfigMap.get("isAutoLoad");        Map<String, Object> iocTestConfig=(Map<String, Object>) iocConfigMap.get("iocTest");        Function<Map<String, Object>, IocConfig> initConfig = (configMap) -> (new IocConfig() {            {                Map<String, Object> config = (Map<String, Object>) configMap.get("conifg");                if (null != config.get("maxCacheSize"))                    this.setSameActionMaxSize((Integer) config.get("sameActionMaxSize"));            }        });        iocConfig = initConfig.apply(iocTestConfig);        if (isAutoLoad) {            //扫描注解            loadFromFile((String) iocConfigMap.get("rootPath"));        } else {            //通过json配置文件            loadFromJSON(iocTestConfig);        }    }    private static void loadFromFile(String basicPath) {        String rootPath = ClassLoader.getSystemResource(".").getPath() + basicPath;        File rootFile = new File(rootPath);        List<String> fileList = new ArrayList<String>();        try {            listFiles(rootFile, fileList);        } catch (IOException e) {            e.printStackTrace();        }        List<String> classes = fileList.stream().map(filestr -> filestr.substring(rootPath.length()).replace("\\", "."))                .collect(Collectors.toList());        Map<String,IocRely> resultMap=new HashMap<String,IocRely>();        classes.forEach(class_ -> analysisClass(basicPath + "." + class_,resultMap));        unmodifiableMap= Collections.unmodifiableMap(resultMap);    }    private static void analysisClass(String path,Map<String,IocRely> resultMap) {        Class<?> class_ = null;        try {            class_ = Class.forName(path);        } catch (ClassNotFoundException e) {            e.printStackTrace();        }        String name=StringUtils.uncapitalize(path.substring(path.lastIndexOf(".")+1));        IocRely  iocRely=new IocRely(name, path);        Field[] fields = class_.getDeclaredFields();        List<String> delys=new ArrayList<String>();        if (ArrayUtils.isNotEmpty(fields)) {            for (int i = 0, length = fields.length; i < length; i++) {                //TODO                //Inject inject = fields[i].getAnnotation(Inject.class);                delys.add(fields[i].getName());            }        }        iocRely.setRelys(delys);        resultMap.put(name, iocRely);    }    private static List<String> listFiles(File rootFile, List<String> fileList) throws IOException {        File[] allFiles = rootFile.listFiles();        for (File file : allFiles) {            if (file.isDirectory()) {                listFiles(file, fileList);            } else {                String path = file.getAbsolutePath();                fileList.add(path.substring(0, path.lastIndexOf(".")));            }        }        return fileList;    }    @SuppressWarnings("unchecked")    private static void loadFromJSON(Map<String, Object> iocTestConfig) {        // init relyMap        Function<Map<String, Object>, Map<String, IocRely>> initRelyMap = (configMap) -> {            HashMap<String, IocRely> resultMap = new HashMap<String, IocRely>();            // init basic            List<Map<String, Object>> beans = (List<Map<String, Object>>) configMap.get("beans");            beans.forEach(bean -> {                bean.entrySet().forEach(entry -> {                    String beanName = entry.getKey();                    Object beanContent = entry.getValue();                    if (beanContent instanceof java.lang.String) {                        resultMap.put(beanName, new IocRely(beanName, (String) beanContent));                    } else {                        Map<String, Object> contents = (Map<String, Object>) beanContent;                        IocRely iocRely = new IocRely(beanName, (String) contents.get("path"));                        Consumer<String> getValues = (key) -> {                            if (contents.containsKey(key)) {                                try {                                    IocRely.class.getDeclaredField(key).set(iocRely, contents.get(key));                                } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException                                        | SecurityException e) {                                    e.printStackTrace();                                }                            }                        };                        getValues.accept("isRequire");                        getValues.accept("isSingleton");                        getValues.accept("isCache");                        resultMap.put(beanName, iocRely);                    }                });            });            // init rely            Map<String, List<String>> shimList = (Map<String, List<String>>) configMap.get("shim");            shimList.entrySet().forEach(shim -> {                IocRely iocRely = null;                if ((iocRely = resultMap.get(shim.getKey())) != null) {                    iocRely.setRelys(shim.getValue());                }            });            return resultMap;        };        unmodifiableMap = Collections.unmodifiableMap(initRelyMap.apply(iocTestConfig));    }    private static void createBeanCache() {        cachedObject = new ConcurrentHashMap<String, Object>(unmodifiableMap.size());        unmodifiableMap.entrySet().forEach(entry -> {            List<String> relays = entry.getValue().getRelys();            if (null != relays && !relays.isEmpty()) {                relays.forEach(relay -> {                    if (!cachedObject.containsKey(relay) && entry.getValue().isCache) {                        inject(relay, true);                    }                });            }        });    }    private static Object inject(String name, Boolean isCache) {        Object itemObject = null;        if (null == (itemObject = cachedObject.get(name))) {            IocRely iocRely = null;            if (null != (iocRely = unmodifiableMap.get(name))) {                try {                    itemObject = Class.forName(iocRely.path).newInstance();                } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e1) {                    e1.printStackTrace();                }                List<String> relys = iocRely.getRelys();                if (null != relys && !relys.isEmpty()) {                    for (int i = 0, length = relys.size(); i < length; i++) {                        String currentName = relys.get(i);                        try {                            Field field = itemObject.getClass().getDeclaredField(currentName);                            field.setAccessible(true);                            field.set(itemObject, inject(currentName, true));                        } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException                                | SecurityException e) {                            e.printStackTrace();                        }                    }                }                if (iocRely.isCache && isCache)                    cachedObject.put(name, itemObject);            } else {                System.out.println(name);                throw new Error("unexpected class");            }        }        return itemObject;    }    private static void invoke(String className, String methodName, Object queryParams) {        if (StringUtils.isAnyEmpty(className, methodName))            return;        Object itemObject = inject(className, false);        try {            itemObject.getClass().getMethod(methodName, queryParams.getClass()).invoke(itemObject, queryParams);        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException                | SecurityException e) {            e.printStackTrace();        }    }    private static void invokeInParallel(String className, String methodName, Object queryParams, int threadNumber) {        if (threadNumber > 0) {            for (int i = 0; i < threadNumber; i++) {                new Thread(() -> {                    BootStrap.invoke(className, methodName, queryParams);                }).start();            }        }    }}

注解类:

@Target({ ElementType.FIELD })@Retention(RetentionPolicy.RUNTIME)public @interface Inject {    String value() default "default" ;    boolean isRequire() default true;    boolean isCache() default true;    boolean isSingleton() default true;}

配置文件:

{    "isAutoLoad":false,    "rootPath":"test",    "iocTest": {        "beans": [            {                "testAction": {                    "path": "test.TestAction",                    "isSingleton": true                }            },            {                "testService": "test.TestService"            },            {                "testDao1": "test.TestDao1"            },            {                "testDao2": {                    "path": "test.TestDao2",                    "isCache": false                }            }        ],        "shim": {            "testAction": [                "testService"            ],            "testService": [                "testDao1",                "testDao2"            ]        },        "conifg": {            "sameActionMaxSize": 5        }      } }

项目下载链接:http://pan.baidu.com/s/1i58zFpV

0 0
原创粉丝点击