Spring - 手写模拟Spring底层原理

手写Spring

定义配置类AppConfig

@ComponentScan("com.spring.zsj")
public class AppConfig {@Beanpublic ApplicationListener applicationListener() {return new ApplicationListener() {@Overridepublic void onApplicationEvent(ApplicationEvent event) {System.out.println("接收到了一个事件"+event );}};}}

定义容器ZSJApplicationContext

public class ZSJApplicationContext {private Class configClass;private Map<String,BeanDefinition> beanDefinitionMap =new HashMap<>();//bean定义private Map<String,Object> singleObjects = new HashMap<>(); //单例池private List<BeanPostProcessor> beanPostProcessorList =new ArrayList<>(); //后置处理public ZSJApplicationContext(Class configClass)  {this.configClass = configClass;scanComponent(configClass);//找出单例beanfor (Map.Entry<String,BeanDefinition> entry: beanDefinitionMap.entrySet()) {String beanName = entry.getKey();BeanDefinition beanDefinition = entry.getValue();if(beanDefinition.equals("singleton")){Object bean = createBean(beanName, beanDefinition);singleObjects.put(beanName,bean);}}}private Object createBean(String beanName,BeanDefinition beanDefinition){Class clazz = beanDefinition.getType();Object newInstance = null;try {newInstance =  clazz.getConstructor().newInstance();//依赖注入for (Field field : clazz.getDeclaredFields()) {if (clazz.isAnnotationPresent(Autowired.class)) {field.setAccessible(true);field.set(newInstance, getBean(field.getName()));}}//执行回调方法if (newInstance instanceof  BeanNameAware){((BeanNameAware) newInstance).setBeanName(beanName);}//执行初始化前的方法for (BeanPostProcessor beanPostProcessor: beanPostProcessorList) {newInstance = beanPostProcessor.postProcessBeforeInitialization(newInstance, beanName);}//当前对象是否实例化了if(newInstance instanceof  InitializingBean){((InitializingBean) newInstance).afterPropertiesSet();}//执行初始化后的方法(例如Aop)for (BeanPostProcessor beanPostProcessor: beanPostProcessorList) {newInstance = beanPostProcessor.postProcessAfterInitialization(newInstance, beanName);}} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();}return newInstance;}private void scanComponent(Class configClass) {if(configClass.isAnnotationPresent(ComponentScan.class)){ComponentScan annotation =(ComponentScan) configClass.getAnnotation(ComponentScan.class);String path = annotation.value();path = path.replace(".", "/");ClassLoader classLoader = ZSJApplicationContext.class.getClassLoader();URL resource = classLoader.getResource(path);File file = new File(resource.getFile());if(file.isDirectory()){//若是文件夹,则取出对应的文件for (File f: file.listFiles()) {String absolutePath = f.getAbsolutePath();//System.out.println(absolutePath);String com = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));String replace = com.replace("\\", ".");// System.out.println(replace);try {Class<?> clazz = classLoader.loadClass(replace);if(clazz.isAnnotationPresent(Component.class)){//clazz 是否实现了BeanPostProcessor接口if(BeanPostProcessor.class.isAssignableFrom(clazz)){BeanPostProcessor instance = (BeanPostProcessor)clazz.getConstructor().newInstance();beanPostProcessorList.add(instance);}//获取bean 的名字Component annotation1 = clazz.getAnnotation(Component.class);String beanName = annotation1.value();if("".equals(beanName)){String name = Introspector.decapitalize(clazz.getSimpleName());}BeanDefinition beanDefinition = new BeanDefinition();beanDefinition.setType(clazz);if(clazz.isAnnotationPresent(Scope.class)){//圆型的Scope scope = clazz.getAnnotation(Scope.class);String value = scope.value();beanDefinition.setScope(value);}else {//单例的beanDefinition.setScope("singleton");}beanDefinitionMap.put(beanName,beanDefinition);//   System.out.println(clazz);}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}}//   System.out.println(path);}}//通过bean名称获取bean对象public Object getBean(String beanName){if(!beanDefinitionMap.containsKey(beanName)){throw new NullPointerException();}BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);if(beanDefinition.getScope().equals("singleton")){Object singletonBean = singleObjects.get(beanName);if(singletonBean== null){singletonBean = createBean(beanName, beanDefinition);singleObjects.put(beanName,singletonBean);}return singletonBean;}else {//原型的Object prototypeBean = createBean(beanName, beanDefinition);return prototypeBean;}}
}

定义注解@Autowired  @Component  @Scope @ComponentScan

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {String value() default "";
}@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {String value() default "";
}@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {String value() default "";
}@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Scope {String value() default "";
}

定义后置处理器BeanPostProcessor,用于初始化

public interface BeanPostProcessor {default Object postProcessBeforeInitialization(Object bean, String beanName)  {return bean;}default Object postProcessAfterInitialization(Object bean, String beanName) {return bean;}
}

   定义ZSJBeanPostProcessor实现BeanPostProcesso

@Component
public class ZSJBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {if(beanName.equals("userService")){Object proxyInstance = Proxy.newProxyInstance(ZSJBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//切面System.out.println("切面逻辑");return method.invoke(bean,args);}});return proxyInstance;}return bean;}
}

定义初始化接口InitializingBean

public interface InitializingBean {void afterPropertiesSet();
}

定义普通的类(可实例化成单例bean)

@Component("userService")
@Scope("singleton")
//public class UserService implements InitializingBean {
public class UserService implements UserInterface {@Autowiredprivate OrderService orderService;@ZSanValue("zhangsan")private String user;//圆型bean 表示多例beanpublic void test(){System.out.println(orderService);}//    @Override
//    public void afterPropertiesSet() {
//        System.out.println("初始化");
//    }
}

定义普通的类(可实例化成原型bean)

@Component("orderService")
@Scope("prototype")
public class OrderService {//圆型bean 表示多例beanpublic void test(){System.out.println("hello");}
}

定义启动类main


public class Test {public static void main(String[] args) {//非懒加载的单例bean
//        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
//        UserService userService = (UserService)context.getBean("userService");
//
//        userService.test();ZSJApplicationContext context = new ZSJApplicationContext(AppConfig.class);UserInterface userService = (UserInterface)context.getBean("userService");userService.test();//      System.out.println(context.getBean("userService"));
//        System.out.println(context.getBean("userService"));
//        System.out.println(context.getBean("userService"));
//        System.out.println(context.getBean("orderService"));
//        System.out.println(context.getBean("orderService"));
//        System.out.println(context.getBean("orderService"));//        AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(context);
//        reader.register(User.class);
//        System.out.println(context.getBean("user"));StringToUserPropertyEditor propertyEditor = new StringToUserPropertyEditor();propertyEditor.setAsText("1");User value =new User();System.out.println(value);}
}

BeanPostProcesso扩展使用方法

自定义注解@ZSanValue

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ZSanValue {String value() default "";
}

使用注解时,将注解的值赋给属性:如

@ZSanValue("zhangsan")
private String user;

 实现后置处理器,并执行初始化前的操作,将自定义的注解值进行属性赋值

@Component
public class ZSanValueBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {for (Field field : bean.getClass().getDeclaredFields()) {if(field.isAnnotationPresent(ZSanValue.class)){field.setAccessible(true);try {field.set(bean,field.getAnnotation(ZSanValue.class).value());} catch (IllegalAccessException e) {e.printStackTrace();}}}return bean;}
}

回调方法使用BeanNameAware

定义回调接口

public interface BeanNameAware {void setBeanName(String name);
}

则实现类需要实现BeanNameAware接口

@Component("userService")
@Scope("singleton")
//public class UserService implements InitializingBean {
public class UserService implements UserInterface,BeanNameAware {@Autowiredprivate OrderService orderService;@ZSanValue("zhangsan")private String user;private String beanName;//圆型bean 表示多例beanpublic void test(){System.out.println(orderService);}@Overridepublic void setBeanName(String name) {this.beanName=name;}//    @Override
//    public void afterPropertiesSet() {
//        System.out.println("初始化");
//    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/178407.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【WinForm详细教程五】WinForm中的MenuStrip 、ContextMenuStrip 、ToolStrip、StatusStrip控件

文章目录 1.MenuStrip2.ContextMenuStrip3.ToolStrip4.StatusStrip 1.MenuStrip MenuStrip作为一个容器可以包含多个菜单项。MenuStrip 的重要属性包括&#xff1a; Name&#xff1a;菜单的名字Dock&#xff1a;菜单的停靠位置Items&#xff1a;菜单项的集合 ToolStripMenuI…

前端接口请求支持内容缓存和过期时间

前端接口请求支持内容缓存和过期时间 支持用户自定义缓存时间&#xff0c;在规则时间内读取缓存内容&#xff0c;超出时间后重新请求接口 首先封装一下 axios&#xff0c;这一步可做可不做。但是在实际开发场景中都会对 axios 做二次封装&#xff0c;我们在二次封装的 axios …

vue3中解析地址(address-parse插件的使用)

1.安装 npm install address-parse --save 2.使用 // 引入address-parse import AddressParse, { AREA, Utils } from "address-parse";const adressValue ref([])const getResolutionContent () > {const [result] AddressParse.parse(EnterpriseSalesDetai…

JAVA虚拟机-第2章 Java自动内存管理-异常实践

Java堆溢出 堆的参数设置&#xff1a;将堆的最小值-Xms参数与最大值-Xmx参数设置 public class HeapOOM {static class OOMObject {}public static void main(String[] args) {List<OOMObject> list new ArrayList<OOMObject>();while (true) {list.add(new OO…

JTS: 13 Polygonizer 多线合成面

这里写目录标题 版本代码 版本 org.locationtech.jts:jts-core:1.19.0 链接: github 代码 线段 生成之后的面 public class GeometryPolygonization {private static final GeometryFactory geometryFactory new GeometryFactory();private static final Logger LOGGER …

陪诊系统|挂号陪护搭建二开陪诊师入驻就医小程序

我们的陪诊小程序拥有丰富多样的功能&#xff0c;旨在最大程度满足现代人的需求。首先&#xff0c;我们采用了智能排队系统&#xff0c;通过扫描二维码获取排号信息&#xff0c;让您从繁琐的排队过程中解放出来。其次&#xff0c;我们提供了多种支付方式&#xff0c;不仅可以实…

管理类联考——数学——汇总篇——知识点突破——代数——函数、方程——记忆

文章目录 考点记忆/考点汇总——按大纲 整体局部 本篇思路&#xff1a;根据各方的资料&#xff0c;比如名师的资料&#xff0c;按大纲或者其他方式&#xff0c;收集/汇总考点&#xff0c;即需记忆点&#xff0c;在通过整体的记忆法&#xff0c;比如整体信息很多&#xff0c;通常…

python线程(进程子单位)

进程是由CPU给分配的执行单元&#xff0c;比较消耗空间和内存 创建、使用线程 import threading# 进程 # 线程 from time import sleepdef download():list1 ["girl.png", "boy.png", "child.png"]for l in list1:print(l)sleep(1.5)print(&qu…

变量的作用域

在javascript中&#xff0c;var定义的变量实际是有作用域的。 1 假设在函数体内声明&#xff0c;但在函数体外不可以使用 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </…

Java实验一编程环境使用

1&#xff0e;String类的常用方法&#xff08;StringExample.java&#xff09; package step1;public class StringExample {public static void main(String args[]) {String s1 new String("you are a student");String s2 new String("how are you")…

Lodash 真的死了吗?Lodash 5 在哪里?

与一些传言相反&#xff0c;Lodash依然活跃&#xff0c;并正在迈向Lodash 5的发布&#xff01; Lodash 是那些为 JavaScript 提供便利功能的实用程序库之一&#xff0c;它使编程变得更加轻松。许多开发者使用它来简化对象和数组的处理。 它也是一个像 Moment.js那样被捕获得措手…

038-第三代软件开发-简易视频播放器-自定义Slider (二)

第三代软件开发-简易视频播放器-自定义Slider (二) 文章目录 第三代软件开发-简易视频播放器-自定义Slider (二)项目介绍简易视频播放器自定义Slider (二)横向纵向 关键字&#xff1a; Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目&…

【UE】从UI中拖拽生成物体

目录 效果 步骤 一、准备工作 二、创建UI 三、创建Actor 四、拖拽生成Actor的逻辑 效果 步骤 一、准备工作 1. 首先新建一个第三人称模板工程 2. 新建一个游戏模式基础&#xff0c;这里命名为“BP_UIGameMode” 在世界场景设置中设置游戏模式覆盖为“BP_UIGameMode”…

Vue中切换tab路由,提示this.$confirm确定和取消执行不同的逻辑

beforeRouteLeave (to, from, next) { // 离开页面 if (this.editFlag true) { this.$confirm(页面尚未保存&#xff0c;确认离开吗?, 提示, { distinguishCancelAndClose: true, // 区分取消和关闭 confirmButtonText: 确定, cancelButtonText: 取消, type: info }).then(()…

RT-Thread 9. VS2012下仿真RT-Thread 和LVGL

1. 在ENV中添加组件 2. 下载组件 3. 生成代码 4. 打开代码 双击project.vcxproj 编译 5. 运行

Linux | 如何保持 SSH 会话处于活动状态

在远程服务器管理和安全数据传输中&#xff0c;SSH&#xff08;Secure Shell&#xff09;是不可或缺的工具。然而&#xff0c;它的便利性和安全性有时会因常见的问题而受到损害&#xff1a;冻结 SSH 会话。 此外&#xff0c;session 的突然中断可能会导致工作丢失、项目延迟和无…

深度学习_1 介绍;安装环境

深度学习 学习自李沐老师的课程。笔记主要以总结老师所讲解的内容以及我个人的想法为主&#xff0c;侵删&#xff01; 课程链接&#xff1a;课程安排 - 动手学深度学习课程 (d2l.ai) 介绍 AI地图&#xff1a; 我们以前写的非 AI 类程序基本都是人自己去想会遇到什么样的问题…

基于transformer的解码decode目标检测框架(修改DETR源码)

提示:transformer结构的目标检测解码器,包含loss计算,附有源码 文章目录 前言一、main函数代码解读1、整体结构认识2、main函数代码解读3、源码链接二、decode模块代码解读1、decoded的TransformerDec模块代码解读2、decoded的TransformerDecoder模块代码解读3、decoded的De…

Ubuntu 20.04设置虚拟内存 (交换内存swap)解决内存不足

数据库服务器程序在运行起来之后&#xff0c;系统内存不足。 在系统监控中发现&#xff0c;当数据库服务程序启动后&#xff0c;占用了大量内存空间&#xff0c;导致系统的剩余的内存往往只有几十MB。 在ubuntu系统中&#xff0c;swap空间就是虚拟内存&#xff0c;所以考虑在磁…

【kubernetes】k8s对象☞pod

文章目录 1、什么是pod2、pod的使用2.1 用于管理pod的工作负载资源2.2 pod怎样管理多个容器2.3 pod 操作系统2.4 pod和控制器2.5 pod模板 3、pod的更新与替换3.1 资源共享和通信3.2 pod中的存储3.3 pod联网 4、容器的特权模式4.1 linux 特权容器4.2 windows特权容器 5、静态pod…