首页 > 其他分享 >手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】【任务阶段4】

手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】【任务阶段4】

时间:2024-08-15 11:22:35浏览次数:15  
标签:BeanPostProcessor spring hykedu StudentDao Spring import 机制 com annotation

手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】【任务阶段4】

任务阶段1、2、3链接
一、实现任务阶段 1- 编写自己 Spring 容器,实现扫描包, 得到 bean 的 class 对象
二、实现任务阶段 2- 扫描将 bean 信息封装到 BeanDefinition 对象, 并放入到 Map
三、实现任务阶段 3- 初始化 bean 单例池,并完成 getBean 方法 , createBean 方法

四、实现任务阶段 4- 完成依赖注入在这里插入图片描述

说明:整个实现思路,就是参考 Spring 规范
1.定义Autowired注解,实现了该注解的属性将会被进行依赖注入(看下面代码实现)

package com.hykedu.spring.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author 程序员蛇皮
 * @version 1.0
 */
@Target({ElementType.METHOD, ElementType.FIELD,})
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}

2.编辑CodeSnakeSpringApplicationContext类,在createBean方法增加识别Autowired注解进行依赖注入的功能

//完成createBean(BeanDefinition beanDefinition)方法
private Object createBean(BeanDefinition beanDefinition, String beanName) {
    //得到Bean的clazz对象
    Class clazz = beanDefinition.getClazz();
    try {
        //使用反射得到对象实例
        Object instance = clazz.getDeclaredConstructor().newInstance();
        //依赖注入
        //1.遍历当前要创建的对象的所有字段
        for (Field declaredField : clazz.getDeclaredFields()) {
            //2.判断这个字段是否有@Autowired
            if (declaredField.isAnnotationPresent(Autowired.class)) {
                //3.得到这个字段的名字
                String name = declaredField.getName();
                System.out.println("字段名:" + name);
                //4.通过getBean()获取要组装的对象
                Object bean = getBean(name);
                //5.进行组装
                //私有属性需要进行反射暴破
                declaredField.setAccessible(true);
                declaredField.set(instance, bean);
            }
        }
        System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------");
        System.out.println("=====创建好实例=====" + instance);
        if (instance != null) {
            return instance;
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    return null;
}

3.在StudentDao类中定义hi()方法,在StudentService类中定义m1()方法,在m1()调用StudentDao类的hi()方法
StudentDao.java

package com.hykedu.spring.component;

import com.hykedu.spring.annotation.Component;

/**
 * @author 程序员蛇皮
 * @version 1.0
 */
@Component
public class StudentDao {
    public void hi() {
        System.out.println("StudentDao hi~");
    }
}

StudentService.java

package com.hykedu.spring.component;

import com.hykedu.spring.annotation.Autowired;
import com.hykedu.spring.annotation.Component;
import com.hykedu.spring.annotation.Scope;

/**
 * @author 程序员蛇皮
 * @version 1.0
 */
@Scope(value = "prototype")
@Component
public class StudentService {
    //这里我们使用自己的 @Autowired 来修饰属性
    //表示该属性,是通过容器完成依赖注入
    //我们这里实现按照名字进行组装
    @Autowired
    private StudentDao studentDao;
    public void m1(){
        studentDao.hi();
    }
}

测试方法AppMain

package com.hykedu.spring;

import com.hykedu.spring.component.StudentDao;
import com.hykedu.spring.component.StudentService;
import com.hykedu.spring.ioc.CodeSnakeSpringApplicationContext;
import com.hykedu.spring.ioc.CodeSnakeSpringConfig;

/**
 * @author 程序员蛇皮
 * @version 1.0
 */
public class AppMain {
    public static void main(String[] args) {
        CodeSnakeSpringApplicationContext codeSnakeSpringApplicationContext = new CodeSnakeSpringApplicationContext(CodeSnakeSpringConfig.class);
        StudentService studentService = (StudentService) codeSnakeSpringApplicationContext.getBean("studentService");
        studentService.m1();
        System.out.println("ok");
    }
}

测试结果:StudentService中的StudentDao对象成功地进行了依赖注入

标签:BeanPostProcessor,spring,hykedu,StudentDao,Spring,import,机制,com,annotation
From: https://blog.csdn.net/2301_77647448/article/details/141217702

相关文章

  • SpringMVC流程
    SpringMVC流程 主要组件:DispatcherServlet:SpringMVC提供,我们需要使用web.xml配置使其生效,它是整个流程处理的核心,所有请求都经过它处理和分发。HandlerMapping:SpringMVC提供,我们需要进行IoC配置,使其加入到IoC容器。它内部缓存handler(controller方法),和handler访问路径数......
  • spring cloud面试题
    什么是SpringCloud?SpringCloud是一个微服务框架,‌它提供了全套的分布式系统解决方案。使用SpringCloud有什么优势将单体服务拆分所带来的问题:-服务实例太多怎么办-服务调用关系太杂乱怎么办-服务访问出错了怎么办-配置信息散落在各个服务中怎么办-服务调用链路......
  • 基于SpringBoot+MySQL+SSM+Vue.js的药房药品采购系统(附论文)
    获取见最下方名片获取见最下方名片获取见最下方名片演示视频技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoot文字描述基于SpringBoot+MySQL+SSM+Vue.js的药房药品采购系统(附论文......
  • 基于SpringBoot+MySQL+SSM+Vue.js的旅游咨询系统
    获取见最下方名片获取见最下方名片获取见最下方名片演示视频技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoot文字描述基于SpringBoot+MySQL+SSM+Vue.js的旅游咨询系统,用户,管理......
  • [NSSCTF 2022 Spring Recruit]ezgame
    首先查看本题描述:js分析,源码泄露,信息收集,大致了解了题的解法方向,进入题目页面查看一下,是一个射击游戏,查看源码发现要获得65分才能拿到成绩,一般来说这种游戏基本不可能拿到给定的分数,通常是对源码进行分析然后用bp抓包改包以此来进行分数获得。 结合前面题解的描述,我们先对js文......
  • Java 中的线程本地存储(ThreadLocal)机制介绍
    Java中的ThreadLocal是一个用于实现线程本地存储(ThreadLocalStorage,TLS)的机制。它可以为每个线程提供独立的变量副本,使得一个线程中的变量不受其他线程中的变量的影响。ThreadLocal通常用于在多线程环境下避免线程之间共享数据,从而实现线程安全。一、基本用法ThreadLoca......
  • Springboot项目中的VO包
    在SpringBoot项目中,VO(ValueObject)是一个非常重要的概念。VO代表值对象,它用于封装业务逻辑中的数据,并且在应用程序的不同层之间进行传递。VO在SpringBoot项目中起到了很多重要的作用,下面我们来详细讲解一下。数据封装:VO用于封装业务逻辑中的数据。在一个典型的SpringBoo......
  • Spring Boot的配置文件管理技巧
    SpringBoot的配置文件管理技巧大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!SpringBoot的配置文件管理是实现不同环境配置和快速部署的关键。SpringBoot提供了多种方式来管理配置文件,以下是一些有效的管理技巧。1.配置文件的命名SpringBoot......
  • Spring Boot集成Spring Data JPA进行数据库操作
    SpringBoot集成SpringDataJPA进行数据库操作大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!SpringDataJPA是一个用于简化数据库操作的ORM(对象关系映射)框架,它提供了一套统一的API来访问数据库,而无需编写大量的JDBC代码。SpringBoot与SpringDat......
  • Spring Boot应用的性能监控与优化
    SpringBoot应用的性能监控与优化大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!性能监控与优化是确保SpringBoot应用高效运行的关键。SpringBoot提供了多种工具和机制来帮助开发者监控应用性能并进行优化。1.应用性能指标SpringBootActuator......