自寫Spring 二

2020-08-13 20:36:15

今天實現了bean的構造方法注入和set方法注入,明顯感覺邏輯開始變得複雜混亂,明天休息一天整理下看看。

一 將Context構造方法的邏輯抽取爲refresh方法。

二 昨天未考慮到如果bean中沒有預設的構造方法就無法用newInstance方法

獲取範例。

在setBean方法中加入識別:

private void setBean(Class<?> c) throws IllegalAccessException, InstantiationException {

        if (c.isAnnotationPresent(Component.class)) {

            boolean flag = true;

            for (Constructor<?> constructor : c.getDeclaredConstructors()) {

                if (constructor.getParameterCount() == 0) {

                    Object instance = c.newInstance();

                    beanMap.put(c, new BeanDefine(StringUtil.firstToLowerCase(c.getSimpleName()), instance));

                    flag = false;

                    break;

                }

            }

            if (flag) {

                needArgsToCreateBeans.add(c);

            }

        }

    }

createBean方法如下:

private Object createBean(Class<?> c) throws IllegalAccessException, InstantiationException, InvocationTargetException {

        for (Constructor<?> constructor : c.getDeclaredConstructors()) {

            constructor.setAccessible(true);

            if (constructor.getParameterCount() == 0) {

                return c.newInstance();

            } else {

                Parameter[] parameters = constructor.getParameters();

                Object[] objs = new Object[parameters.length];

                for (int i = 0; i < parameters.length; i++) {

                    System.out.println(getBean(parameters[i].getType()));

                    objs[i] = getBean(parameters[i].getType());

                }

                return constructor.newInstance(objs);

            }

        }

        return null;

    }

其中,無預設構造方法的bean被放入

private static final Set<Class<?>> needArgsToCreateBeans = new HashSet<>();

中,等待其他bean載入後載入:

 for (Class<?> aClass : classes) {

                setBean(aClass);

            }

            for (Class<?> aClass : classes) {

                setField(aClass);

            }

            for (Class<?> c : needArgsToCreateBeans) {

                Object bean = createBean(c);

                beanMap.put(c, new BeanDefine(StringUtil.firstToLowerCase(c.getSimpleName()), bean));

            }

並且對refresh方法的異常做了進一步的修改:

catch (IllegalArgumentException e) {

            logger.error("***** {}", e.getMessage());

            logger.error("***** help : can not find bean in context, please check the class you need autowired");

            e.printStackTrace();

        } catch (IllegalAccessException e) {

            logger.error("***** {}", e.getMessage());

            logger.error("***** help : wrong in reflect , waiting for repairing");

            e.printStackTrace();

        } catch (InvocationTargetException e) {

            logger.error("***** {}", e.getMessage());

            logger.error("***** help : wrong in invoking method by reflect, please check the class you need autowired");

            e.printStackTrace();

        } catch (Exception e) {

            logger.error("***** something wrong in create context : {}", e.getMessage());

            e.printStackTrace();

        }

,,,,,,太亂了!!!