• 19.Spring源码解读之简单手写spring框架


    1.Spring底层源码解读课程安排
    2.Springxml、注解实现IOC区别
    3.简单模拟手写出xml方式实现IOC
    4.简单模拟手写出注解方式实现IOC

    2022版本Spring5深入源码解读
    Spring5源码分析之IOC原理掌握Spring5的源码正确阅读方式、bean对象创建与初始化、一步一步手绘spring源码架构图
    Spring5源码分析之IOC原理掌握BeanFactory与FactoryBean原理分析、后置处理器增强、Bean的生命周期源码分析监听器与事件监听事件机制源码分析
    Spring5源码分析之循环依赖掌握怎么检测循环依赖、怎么解决循环依赖、循环依赖无法解决的场景、三级与二级缓存设计
    Spring5源码分析之AOP原理掌握手绘Aop流程架构图、Aop调用链、动态代理模式应用、事务失效之谜与底层实现
    Spring5源码分析之AOP原理掌握Spring5的高级应用、巧妙的运用在工作中、经典Spring面试题
    Spring5源码分析之事务原理掌握PlatformTransactionManager、TransactionManager、传播行为原理
    SpringMVC源码分析之SpringMVC请求处理流程掌握SpringMVC请求处理流程、SpringMVC的工作机制、DispatcherServlet
    SpringMVC源码分析之SpringMVC请求处理流程掌握SpringMVC请求的时候是如何找到正确的Controller、Controller的方法中参数的工作原理
    SpringMVC源码分析之SpringMVC请求处理流程掌握json、xml自动转换的原理研究、类型转换、数据绑定详解、MVC拦截器详解、MVC视图机制详解、异常处理机制详解
    SpringBoot源码解读之启动原理分析掌握@EnableAutoConfiguration @SpringBootApplication、Springboot自动装配的实现原理
    SpringBoot源码解读之自定义starter组件掌握SpringBoot自定义starter组件原理

    Spring环境搭建

    Spring 配置bean方式

    方式1 xml方式

    方式2 注解方式

    SpringBoot 底层 基于 Spring注解封装

    maven

        <dependencies>
            <dependency>
                <groupId>dom4j</groupId>
                <artifactId>dom4j</artifactId>
                <version>1.6.1</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/jaxen/jaxen -->
            <dependency>
                <groupId>jaxen</groupId>
                <artifactId>jaxen</artifactId>
                <version>1.2.0</version>
            </dependency>
            <!-- 反射框架 -->
            <dependency>
                <groupId>org.reflections</groupId>
                <artifactId>reflections</artifactId>
                <version>0.9.11</version>
            </dependency>
        </dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    xml方式

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!--
         配置SpringBean对象
         -->
        <bean id="userEntity" class="com.mayikt.entity.UserEntity"></bean>
        <bean id="mayiktService" class="com.mayikt.service.MayiktService"></bean>
    </beans>
    package com.mayikt.test;
    
    import com.mayikt.entity.UserEntity;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @author 余胜军
     * @ClassName Test01
     * @qq 644064779
     * @addres www.mayikt.com
     * 微信:yushengjun644
     */
    public class Test01 {
        public static void main(String[] args) {
            //1.读取spring.xml
            ClassPathXmlApplicationContext classPathXmlApplicationContext =
                    new ClassPathXmlApplicationContext("spring.xml");
            //2.从IOC容器读取到userEntity
            UserEntity userEntity =
                    classPathXmlApplicationContext.getBean("userEntity", UserEntity.class);
            System.out.println(userEntity);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    注解方式

    package com.mayikt.config;
    
    import com.mayikt.entity.UserEntity;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    /**
    * @author songchuanfu
    * @qq 1802284273
    */
    @Configuration
    @ComponentScan("com.mayikt.service")
    public class MayiktConfig {
        @Bean("user")
        public UserEntity userEntity() {
            return new UserEntity();
        }
    }
    package com.mayikt.test;
    
    import com.mayikt.config.MayiktConfig;
    import com.mayikt.entity.UserEntity;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /**
    * @author songchuanfu
    * @qq 1802284273
    */
    public class Test02 {
        public static void main(String[] args) {
            //加载MayiktConfig.class
            AnnotationConfigApplicationContext mayiktConfig
                    = new AnnotationConfigApplicationContext(MayiktConfig.class);
            // 获取userEntity
            UserEntity userEntity = mayiktConfig.getBean("userEntity", UserEntity.class);
            System.out.println(userEntity);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    简单手写spring框架

    简单手写spring框架 xml方式

    SpringIOC容器底层实现原理:

    反射+工厂模式+解析xml技术实现

    1.使用解析xml技术 解析spring.xml配置文件;

    2.获取 类的完整路径地址

    3.使用到反射技术初始化对象

    4.需要使用工厂模式封装初始化对象

    package com.mayikt.ext;
    
    import com.mayikt.entity.UserEntity;
    import com.mayikt.service.MayiktService;
    import org.dom4j.*;
    import org.dom4j.io.SAXReader;
    import org.springframework.core.io.ClassPathResource;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.Iterator;
    import java.util.List;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
    * @author songchuanfu
    * @qq 1802284273
    */
    public class SpringIOCXml {
        private ConcurrentHashMap<String, Object> beansHashMap = new ConcurrentHashMap<>();
    
        public SpringIOCXml() throws IOException, DocumentException {
            // 初始化IOC容器
            initIoc();
        }
    
        public <T> T getBean(String name, Class<T> requiredType) {
            Object o = beansHashMap.get(name);
            return (T) o;
        }
    
        private void initIoc() throws IOException, DocumentException {
            //1.解析xml配置
            ClassPathResource classPathResource = new ClassPathResource("spring.xml");
            File xmlFile = classPathResource.getFile();
            SAXReader saxReader = new SAXReader();
            Document doc = saxReader.read(xmlFile);
            // 获取到根节点
            Element rootElement = doc.getRootElement();
            List<Element> beans = rootElement.elements("bean");
            beans.forEach((bean -> {
                try {
                    //2.查找   
                    //3.利用反射机制初始化 class="com.mayikt.entity.UserEntity" 将bean对象存入Map集合中
                    String beanIdStr = bean.attribute("id").getValue();
                    String classStr = bean.attribute("class").getValue();
                    Class<?> bClass = Class.forName(classStr);
                    Object object = bClass.newInstance();
                    beansHashMap.put(beanIdStr, object);
                } catch (Exception e) {
                }
            }));
        }
    
        public static void main(String[] args) throws DocumentException, IOException {
            SpringIOCXml springIOCXml = new SpringIOCXml();
            UserEntity userEntity = springIOCXml.getBean("userEntity", UserEntity.class);
            MayiktService mayiktService = springIOCXml.getBean("mayiktService", MayiktService.class);
            mayiktService.add();
        }
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    简单手写spring框架ioc 注解方式

    思路:

    1.ioc容器底层核心 HashMap集合 (key=beanid value=bean对象)

    user()

    beanid:user bean对象 new UserEntity();

    HashMap.put(user ,new UserEntity());

    getBean("user ")-----new UserEntity()

    1.将spring.xml配置文件读取到程序中

    2.利用解析xml框架spring.xml

    3.获取(bean标签)节点 beanid ====HashMap.key value 利用反射机制初始化

    com.mayikt.service.OrderService

    @ComponentScan(“com.mayikt.service”)

    1.利用java反射机制获取到该包下所有的类(class)

    2.利用java反射机制 判断每个类上是否有加上@Component

    3.如果有加上该注解的情况下 类的名称 首字母变成小写 作为bean的id value

    该类class 利用反射初始化

    4.存入到map集合中。

    1.使用@Bean注解 ----没有反射初始化对象 根据方法返回值 作为 bean对象

    2.@ComponentScan 底层 使用反射初始化对象

    3.xml

    package com.mayikt.ext;
    
    import com.mayikt.config.MayiktConfig;
    import com.mayikt.entity.UserEntity;
    import com.mayikt.service.MayiktService;
    import com.mayikt.service.OrderService;
    import com.mayikt.utils.ClassUtils;
    import org.reflections.Reflections;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;
    import java.util.Arrays;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
    * @author songchuanfu
    * @qq 1802284273
    */
    public class SpringIOCAnnotation {
        private Object config;
        private ConcurrentHashMap<String, Object> beansHashMap = new ConcurrentHashMap<>();
    
        /**
         * 传递配置类
         */
        public SpringIOCAnnotation(Object config) {
            this.config = config;
            initIoc();
        }
    
        /**
         * 初始化IOC容器
         */
        public void initIoc() {
            Configuration configuration
                    = this.config.getClass().getDeclaredAnnotation(Configuration.class);
            if (configuration == null) {
                return;
            }
            // 如果该类上有配置configuration
            // 利用java反射机制
            Class<?> aClass = config.getClass();
            Method[] declaredMethods = aClass.getDeclaredMethods();
            Arrays.stream(declaredMethods).forEach(m -> {
                Bean bean = m.getDeclaredAnnotation(Bean.class);
                if (bean != null) {
                    try {
                        // 方法名称作为bean的id
                        String[] value = bean.value();
                        String beanId = value[0];
                        String defBeanId = m.getName();
                        // 获取方法返回值
                        Object result = m.invoke(config, null);
                        beansHashMap.put(StringUtils.isEmpty(beanId) ? defBeanId : beanId, result);
                    } catch (Exception e) {
    
                    }
                }
            });
            //ComponentScan
            //利用反射机制查找 该包下所有的class
            ComponentScan componentScan = aClass.getDeclaredAnnotation(ComponentScan.class);
            if (componentScan != null) {
                String[] strings = componentScan.value();
                Arrays.stream(strings).forEach(pack -> {
                    Class[] classByPackage = ClassUtils.getClassByPackage(pack);
                    Arrays.stream(classByPackage).forEach(c -> {
                        Annotation component = c.getDeclaredAnnotation(Component.class);
                        if (component != null) {
                            try {
                                // 注入到ioc容器中
                                String beanId = c.getSimpleName();
                                Object beanObject = c.newInstance();
                                beansHashMap.put(beanId, beanObject);
                            } catch (Exception e) {
    
                            }
                        }
                    });
                });
            }
    
        }
    
    
        public <T> T getBean(String name, Class<T> requiredType) {
            Object o = beansHashMap.get(name);
            return (T) o;
        }
    
        public static void main(String[] args) {
            SpringIOCAnnotation springIOCAnnotation =
                    new SpringIOCAnnotation(new MayiktConfig());
            OrderService orderService =
                    springIOCAnnotation.getBean("OrderService", OrderService.class);
            System.out.println(orderService);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103

    相关code

    📎spring源码day01.rar

  • 相关阅读:
    爬取春秋航空航班信息
    力扣 138. 随机链表的复制
    实验室管理系统LIMS
    LiteOS同步实验(实现生产者-消费者问题)
    【每日一题】Day 38 选择题
    Windows安装Go语言及VScode配置
    12.Vue2和Vue3中的全局属性
    超级账本Fabric的世界状态操作与账本操作
    HCIP —— BGP路径属性 (下)
    如何使用 Xshell 连接 Linux 服务器
  • 原文地址:https://blog.csdn.net/u014001523/article/details/126416137