我的前端坑
  • 关于本书
  • CSS JS 常用
    • 常用 CSS 样式
    • 坑爹的 CSS
    • sass 入门
    • canvas 总结
    • 常用 JS 函数
    • 表单和 FormData 对象
    • 水平滑动 tab 居中
    • js 中的 this
    • sse 和 fetch
    • js 原型链与 class 类
  • TypeScript
    • TS 概念
    • interface 与 type
    • interface 接口
    • Ts 配合 ESLint 和 prettier
  • 小程序
    • 常用小程序代码
  • VUE
    • VUE2 小技巧
    • VUE-CLI 中的 NODE_ENV
  • VUE3
    • VUE3 自行构建 sfc 遇到的坑
    • VUE3 v-model 的实现
    • VUE3 使用总结
    • VUE3 ref
  • vite
    • vite
  • http 请求
    • 前端实现下载
    • cors 跨域请求
    • windows hosts 文件
    • err_blocked_by_client 错误
  • 前端工具
    • npm 和 Node
      • 常见问题
      • npmTips
      • package.json 与 package-lock.json
      • npx
      • exports 与 module.exports
      • ESLint
    • VIM
      • vim 常用
    • Git
      • Git 常用命令
      • Git 小 tips
    • express
  • 后端工具
    • mysql 常见问题
    • docker 常见问题
    • docker
  • java
    • java 常用
    • lambda 表达式
    • java 字符串
    • java 泛型
    • java 反射
    • intellij IDEA
    • 多态
    • java 包管理
    • sql 查询语言
    • java 反射
    • java 异常
    • java 集合
    • spring
  • 命令行
    • 命令行 常用
  • 专利撰写 ppt
  • 后台简述
Powered by GitBook
On this page
  • spring 容器的核心概念
  • 手写一个简单的 spring 实现
  • spring 是怎么实现的

Was this helpful?

  1. java

spring

  • spring 容器,一个 IOC(Inversion of Control 控制反转)容器

  • springMVC,基于 Spring 和 servlet 的 web 应用框架

  • springBoot,集成度和自动化程度更高

spring 容器的核心概念

  • Bean 容器中的最小工作单元,通常为一个 java 对象

  • BeanFactory ApplicationContext

  • 依赖注入(dependence injection)容器负责注入所有的依赖

  • 控制翻转(inversion of control)用户将控制权交给容器

手写一个简单的 spring 实现

注意: 为了简单起见,依然使用了 maven 依赖插件 springContext 的 Autowired 注 解接口来获取依赖:

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.20</version>
        </dependency>
    </dependencies>
  1. 定义 Bean 配置文件:我们使用 Java 支持的古老的.properties 配置文件格式 在 src/main/resource/ioc.properties

orderDao = com.github.hcsp.OrderDao
orderService = com.github.hcsp.OrderService
  1. Bean 文件:

  • src/mian/java/org/example/OrderDao

package org.example;

public class OrderDao {
    public void select(){
        System.out.println("执行成功!");
    }
}
  • src/mian/java/org/example/OrderService

package org.example;

import org.springframework.beans.factory.annotation.Autowired;

public class OrderService {
    @Autowired
    private OrderDao orderDao;
    public void doSomeThing(){
        orderDao.select();
    }
}
  1. 实例化 Bean,查找依赖,实现自动注入

  • src/mian/java/org/example/MyIocContainer

package org.example;

import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class MyIocContainer {
    public static Map<String, Object> initBeans;

    public static void init() {
        Properties properties = new Properties();
        try {
            // 加载Bean配置文件(类映射文件)
            properties.load(MyIocContainer.class.getResourceAsStream("/ioc.properties"));
            System.out.println(properties);
            Map<String, Object> beans = new HashMap<>();
            // properties:{orderDao=org.example.OrderDao, orderService=org.example.OrderService}
            // 实例化配置文件中所有的 Bean 并放到Map集合 beans 中
            properties.forEach((beanName, fullyQualifiedClassName) -> {
                try {
                    Class klass = Class.forName((String) fullyQualifiedClassName);
                    Object beanInstance = klass.getConstructor().newInstance();
                    beans.put((String) beanName, beanInstance);
                } catch (ClassNotFoundException | InvocationTargetException | InstantiationException |
                         IllegalAccessException | NoSuchMethodException e) {
                    throw new RuntimeException(e);
                }
            });
            // 遍历beans中的实例化对象,使用反射获取对应实例的依赖
            beans.forEach((beanName, beanInstance) -> {
                dependencyInject(beanName, beanInstance, beans);
            });
            initBeans = beans;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static void dependencyInject(String beanName, Object beanInstance, Map<String, Object> beans) {
        // 获取有Autowired注解的字段
        List<Field> fieldsTobeAutowired = Stream.of(beanInstance.getClass().getDeclaredFields())
                .filter(field -> field.getAnnotation(Autowired.class) != null)
                .collect(Collectors.toList());
        fieldsTobeAutowired.forEach(field -> {
            try {
                String fieldName = field.getName();
                // 在已经实例化所有所需要的bean对象的beans中查找依赖的那个实例对象
                Object depencyBeanInstance = beans.get(fieldName);
                field.setAccessible(true);
                // 将当前对象所依赖的对象注入
                field.set(beanInstance, depencyBeanInstance);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        });
    }

    public static void main(String[] args) {
        // 执行
        init();
        OrderService orderService = (OrderService) initBeans.get("orderService");
        OrderDao orderDao = (OrderDao) initBeans.get("orderDao");
    }
}

spring 是怎么实现的

  • 在xml中定义Bean,或者使用注解定义Bean

  • BeanDefinition的载入和解析

  • Bean 的实例化和依赖注入

  • 对外提供服务

Previousjava 集合Next命令行

Last updated 2 years ago

Was this helpful?