手写Spring底层机制
  5DfGM4DuibK0 2024年04月09日 13 0

手写Spring底层机制

IOC容器

    //定义 BeanDefinitionMap 存放 beanDefinition
    private ConcurrentHashMap<String,BeanDefinition> beanDefinitionMap =
            new ConcurrentHashMap<>();

    //定义 singletonObjects 存放 单例
    private ConcurrentHashMap<String,Object> singletonObjects =
            new ConcurrentHashMap<>();


    //定义beanPostProcessorList 存放 BeanPostProcessor
    private ArrayList<BeanPostProcessor> beanPostProcessorList=
            new ArrayList<>();


构造器

//构造器
public ZyApplicationContext(Class configClass) {
    this.configClass = configClass;

    beanDefinitionsByScan();

    //初始化单例池
    initSingletonObjects();
}

扫描包

private void beanDefinitionsByScan() {
        //获得扫描的包
        ComponentScan componentScan =
                (ComponentScan)this.configClass.getDeclaredAnnotation(ComponentScan.class);

        //获取路径
        String path = componentScan.value();

        path = path.replace(".","/");
        //获取工作路径
        ClassLoader classLoader = ZyApplicationContext.class.getClassLoader();

        URL resource = classLoader.getResource(path);

        File file = new File(resource.getFile());
        if (file.isDirectory()){
            File[] files = file.listFiles();
            for (File f : files) {
                //获取绝对路径
                String fileAbsolutePath = f.getAbsolutePath();
                if (fileAbsolutePath.endsWith(".class")) {
                    //获取className
                    String className = fileAbsolutePath.substring(fileAbsolutePath.lastIndexOf("\\") + 1, fileAbsolutePath.indexOf(".class"));

                    String fullPath = path.replace("/", ".") + "." + className;

                    try {
                        Class<?> clazz = classLoader.loadClass(fullPath);
                        if (clazz.isAnnotationPresent(Component.class)) {

                            //初始化beanPostProcessorList
                            if (BeanPostProcessor.class.isAssignableFrom(clazz)){
                              BeanPostProcessor beanPostProcessor =
                                      (BeanPostProcessor)clazz.newInstance();
                                beanPostProcessorList.add(beanPostProcessor);
                                continue;
                            }


                            //处理className
                            String value = clazz.getDeclaredAnnotation(Component.class).value();
                            if ("".equals(value)){
                                className = StringUtils.uncapitalize(className);
                            }else {
                                className = value;
                            }
                            System.out.println("是一个bean 类名= " + className);
                            //设置 beanDefinition
                            BeanDefinition beanDefinition = new BeanDefinition();
                            //设置scope
                            if (clazz.isAnnotationPresent(Scope.class)){
                                beanDefinition.setScope(clazz.getDeclaredAnnotation(Scope.class).value());
                            }else{
                                beanDefinition.setScope("singleton");
                            }
                            beanDefinition.setClazz(clazz);

                            //放入 beanDefinitionMap
                            beanDefinitionMap.put(className,beanDefinition);




                        } else {
                            System.out.println("不是一个bean 类名= " + className);
                        }
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }

初始化单例池

private void initSingletonObjects() {
        Enumeration<String> keys = beanDefinitionMap.keys();
        while (keys.hasMoreElements()){
            String beanName = keys.nextElement();
            BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
            String scope = beanDefinition.getScope();
            if ("singleton".equals(scope)){
                Object bean = createBean(beanDefinition,beanName);
                singletonObjects.put(beanName,bean);
            }

        }
    }

getBean()

 public Object getBean(String name){
        if (beanDefinitionMap.containsKey(name)){
            BeanDefinition beanDefinition = beanDefinitionMap.get(name);
            String scope = beanDefinition.getScope();
            if ("singleton".equals(scope)){
                return singletonObjects.get(name);
            }else{
                return createBean(beanDefinition,name);
            }
        }
        return null;
    }

createBean()

 private Object createBean(BeanDefinition beanDefinition,String beanName){
        try {
            Class clazz = beanDefinition.getClazz();
            Object instance = clazz.getDeclaredConstructor().newInstance();
            
            return instance;
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }

依赖注入

  • 加入到createBean()中

  private Object createBean(BeanDefinition beanDefinition,String beanName){
        try {
            Class clazz = beanDefinition.getClazz();
            Object instance = clazz.getDeclaredConstructor().newInstance();

            //依赖注入
            Field[] declaredFields = clazz.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                if (declaredField.isAnnotationPresent(Autowired.class)){
                    if (declaredField.getDeclaredAnnotation(Autowired.class).required()){
                        //获的字段名
                        String fieldName = declaredField.getName();
                        //获取实例
                        Object bean = getBean(fieldName);
                        declaredField.setAccessible(true);
                        declaredField.set(instance,bean);
                    }
                }
            }

          
            return instance;
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }

后置处理器

  • 加入到createBean()中

  private Object createBean(BeanDefinition beanDefinition,String beanName){
        try {
            Class clazz = beanDefinition.getClazz();
            Object instance = clazz.getDeclaredConstructor().newInstance();

            //依赖注入
            Field[] declaredFields = clazz.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                if (declaredField.isAnnotationPresent(Autowired.class)){
                    if (declaredField.getDeclaredAnnotation(Autowired.class).required()){
                        //获的字段名
                        String fieldName = declaredField.getName();
                        //获取实例
                        Object bean = getBean(fieldName);
                        declaredField.setAccessible(true);
                        declaredField.set(instance,bean);
                    }
                }
            }

            //后置处理器 before()
            //遍历 beanPostProcessorList
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                Object current = beanPostProcessor.
                        postProcessBeforeInitialization(instance, beanName);
                if (current!=null){
                    instance = current;
                }

            }


            //初始化bean
            if (instance instanceof InitializingBean){
                try {
                    ((InitializingBean)instance).afterPropertiesSet();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }



            //后置处理器 after()
            //遍历 beanPostProcessorList
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                Object current = beanPostProcessor.
                        postProcessAfterInitialization(instance, beanName);
                if (current!=null){
                    instance = current;
                }

            }


            System.out.println("");
            System.out.println("-------------------------------------");
            System.out.println("");
            return instance;
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }

AOP

  • AOP需要在后置处理器的before方法中实现

 @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("ZyBeanPostProcessor后置处理器-After-beanName= "+beanName);


        //aop实现

        if("smartDog".equals(beanName)) {
            Object proxyInstance = Proxy.newProxyInstance(ZyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {


                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    Object result = null;

                    if ("getSum".equals(method.getName())) {
                        SmartAnimalAspect.showBeginLog();
                        result = method.invoke(bean, args);
                        SmartAnimalAspect.showBeginLog();
                    }else {
                        result = method.invoke(bean, args);//执行目标方法
                    }

                    return result;
                }
            });
            return proxyInstance;
        }

        return bean;
    }

几个Spring的问题

1.单例/多例怎么实现的?@scope为什么可以实现?

回答:@scope 的value属性可以设置为singleton /prototype

通过getBean()方法 如果bean中的属性scope为singleton 就从单例池直接拿,如果是prototype 就调用createBean()创建一个实例

2.如何实现依赖注入?@Autowired Spring容器如何实现依赖注入?

回答: 遍历clazz的所有属性 通过@Autowired注解 如果有 先获取字段名 再通过getBean()获取对应的bean 最后用filed.set()方法将实例的该属性设置为 获取到的bean 实现依赖注入

3.后置处理器 为什么在创建bean 时 调用bean 的 init方法初始化前/后 调用?

//后置处理器 before()
            //遍历 beanPostProcessorList
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                Object current = beanPostProcessor.
                        postProcessBeforeInitialization(instance, beanName);
                if (current!=null){
                    instance = current;
                }

            }


            //初始化bean
            if (instance instanceof InitializingBean){
                try {
                    ((InitializingBean)instance).afterPropertiesSet();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }



            //后置处理器 after()
            //遍历 beanPostProcessorList
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                Object current = beanPostProcessor.
                        postProcessAfterInitialization(instance, beanName);
                if (current!=null){
                    instance = current;
                }

            }

4.后置处理器和AOP有什么关系,Spring Aop如何实现??

回答:aop的实现实在后置处理器的before中实现的,底层使用动态代理

 //aop实现

        if("smartDog".equals(beanName)) {
            Object proxyInstance = Proxy.newProxyInstance(ZyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {


                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    Object result = null;

                    if ("getSum".equals(method.getName())) {
                        SmartAnimalAspect.showBeginLog();
                        result = method.invoke(bean, args);
                        SmartAnimalAspect.showBeginLog();
                    }else {
                        result = method.invoke(bean, args);//执行目标方法
                    }

                    return result;
                }
            });
            return proxyInstance;
        }

        return bean;
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年04月09日 0

暂无评论

推荐阅读
  8s1LUHPryisj   19小时前   6   0   0 Java
5DfGM4DuibK0