手写Spring底层机制

这篇具有很好参考价值的文章主要介绍了手写Spring底层机制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

手写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中实现的,底层使用动态代理文章来源地址https://www.toymoban.com/news/detail-845424.html

 //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底层机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 手写模拟Spring的底层原理2.1

    先来引入两个问题 第一个懒加载还是立即加载的问题,这个问题还是在于就是说,当我们xml配置了一个对象bean的时候,它在spring容器里面是什么时候开始会给我们创建这个对象 那如果我们想对某个对象启动懒加载,可以添加@lazy这个注解  这个注解一加上,它就只会在得到

    2024年02月08日
    浏览(30)
  • Spring系列五:手动实现Spring底层机制

    上文中, 我们学习到了 Spring系列四:AOP切面编程 接下来我们学习, 手动实现Spring底层机制 ● java的类加载器 3 种 Bootstrap类加载器---------------------对应路径jrelib Ext类加载器------------------------------对应路径jrelibext App类加载器-----------------------------对应路径classpath ●classpath 类路

    2024年02月12日
    浏览(38)
  • 【Spring】手动实现Spring底层机制-问题的引出

    🎄欢迎来到@边境矢梦°的csdn博文🎄 🎄本文主要梳理手动实现Spring底层机制-问题的引出 🎄 🌈我是边境矢梦°,一个正在为秋招和算法竞赛做准备的学生🌈 🎆喜欢的朋友可以关注一下 🫰🫰🫰 ,下次更新不迷路🎆 Ps: 月亮越亮说明知识点越重要 (重要性或者难度越大)🌑

    2024年02月09日
    浏览(33)
  • SpringBoot 底层机制分析【Tomcat 启动+Spring 容器初始化+Tomcat 如何关联Spring 容器】【下】

    😀前言 本篇博文是关于SpringBoot 底层机制分析实现,希望能够帮助你更好的了解SpringBoot 😊 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的文章可以帮助到大家,您的满意是我的动力😉😉 💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客

    2024年02月13日
    浏览(34)
  • 【Spring底层原理高级进阶】轻松掌握 Spring MVC 的拦截器机制:深入理解 HandlerInterceptor 接口和其实现类的用法

     🎉🎉欢迎光临🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟特别推荐给大家我的最新专栏 《Spring 狂野之旅:底层原理高级进阶》 🚀 本专栏纯属为爱发电永久免费!!! 这是苏泽的个人主页可以看到我其他的内容哦👇👇 努力的苏泽 http://suze

    2024年02月20日
    浏览(42)
  • 实现SpringMVC底层机制(三)

    1.将方法的httpservletrequest和httpservletresponse参数封装到参数数组进行反射调用 1.修改SunDispatcherServlet.java的executeDispatch方法 2.debug测试 2.封装http请求参数 1.需求分析 2.自定义注解RequestsParam 3.修改MonsterService接口,添加方法 4.修改MonsterServiceImpl.java添加方法 5.修改SunDispatcherServlet.

    2024年04月28日
    浏览(23)
  • 实现SpringMVC底层机制(二)

    1.修改SunWebApplicationContext.java 2.修改SunDispatcherServlet.java 1.需求分析 2.编写Monster.java 3.自定义Service注解 4.编写Service接口MonsterService.java 5.编写Service实现类MonsterServiceImpl.java 6.修改SunWebApplicationContext.java的executeInstance方法,增加对Service注解的扫描 7.debug测试 1.自定义Autowired注解 2

    2024年04月27日
    浏览(24)
  • Java中ArrayList的底层扩容机制和Vector的底层扩容机制,以及ArrayList和Vector的对比与选择。附源码

    在 Java 的 ArrayList 中,当数组的容量不足以存储新元素时,会触发扩容操作。ArrayList 的底层使用数组来存储元素,而扩容机制主要涉及到创建一个更大的数组,并将现有元素复制到新数组中。ArrayList 支持无参扩容和有参扩容两种机制。 无参扩容机制 : 无参扩容是指 首次的

    2024年02月11日
    浏览(27)
  • Ribbon LoadBalanced底层机制源码探秘

    🍊 Java学习:社区快速通道 🍊 深入浅出RocketMQ设计思想:深入浅出RocketMQ设计思想 🍊 绝对不一样的职场干货:大厂最佳实践经验指南 📆 最近更新:2023年6月18日 🍊 点赞 👍 收藏 ⭐留言 📝 都是我最大的动力! 通过本文你可以学习到: LoadBalanced作用原理 拦截器到Rule的调

    2024年02月09日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包