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.mzph.cn/news/127042.shtml

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

相关文章

【案例】3D地球(vue+three.js)

需要下载插件 <template><div class"demo"><div id"container" ref"content"></div></div> </template> <script> import * as THREE from three; // import mapJSON from ../map.json; import { Or…

pytorch 笔记:KLDivLoss

1 介绍 对于具有相同形状的张量 ypred​ 和 ytrue&#xff08;ypred​ 是输入&#xff0c;ytrue​ 是目标&#xff09;&#xff0c;定义逐点KL散度为&#xff1a; 为了在计算时避免下溢问题&#xff0c;此KLDivLoss期望输入在对数空间中。如果log_targetTrue&#xff0c;则目标…

新一代构建工具Vite-xyphf

一、什么vite? vite:是一款思维比较前卫而且先进的构建工具,他解决了一些webpack解决不了的问题——在开发环境下可以实现按需编译&#xff0c;加快了开发速度。而在生产环境下&#xff0c;它使用Rollup进行打包&#xff0c;提供更好的tree-shaking、代码压缩和性能优化&…

基于开源IM即时通讯框架MobileIMSDK:RainbowChat-iOS端v8.0版已发布

关于MobileIMSDK MobileIMSDK 是一套专门为移动端开发的开源IM即时通讯框架&#xff0c;超轻量级、高度提炼&#xff0c;一套API优雅支持 UDP 、TCP 、WebSocket 三种协议&#xff0c;支持 iOS、Android、H5、标准Java、小程序、Uniapp&#xff0c;服务端基于Netty编写。 工程…

计算机网络-应用层

文章目录 应用层协议原理万维网和HTTP协议万维网概述统一资源定位符HTML文档 超文本传输协议&#xff08;HTTP&#xff09;HTTP报文格式请求报文响应报文cookie 万维网缓存与代理服务器 DNS系统域名空间域名服务器和资源记录域名解析过程递归查询迭代查询 动态主机配置协议&…

SpringCloud Alibaba Demo(Nacos,OpenFeign,Gatway,Sentinel)

开源地址&#xff1a; ma/springcloud-alibaba-demo 简介 参考&#xff1a;https://www.cnblogs.com/zys2019/p/12682628.html SpringBoot、SpringCloud 、SpringCloud Alibaba 以及各种组件存在版本对应关系。可参考下面 版本对应 项目前期准备 启动nacos. ./startup.c…

数据结构(超详细讲解!!)第十八节 串(堆串)

1.定义 假设以一维数组heap &#xff3b;MAXSIZE&#xff3d; 表示可供字符串进行动态分配的存储空间&#xff0c;并设 int start 指向heap 中未分配区域的开始地址(初始化时start 0) 。在程序执行过程中&#xff0c;当生成一个新串时&#xff0c;就从start指示的位置起&#…

kotlin中集合操作符

集合操作符 1.总数操作符 any —— 判断集合中 是否有满足条件 的元素&#xff1b; all —— 判断集合中的元素 是否都满足条件&#xff1b; none —— 判断集合中是否 都不满足条件&#xff0c;是则返回true&#xff1b; count —— 查询集合中 满足条件 的 元素个数&#x…

python科研绘图:条形图

条形图&#xff08;bar chart&#xff09;是一种以条形或柱状排列数据的图形表示形式&#xff0c;可以显示各项目之间的比较。它通常用于展示不同类别的数据&#xff0c;例如在分类问题中的不同类别、不同产品或不同年份的销售数据等。 条形图中的每个条形代表一个类别或一个数…

基于goframe2.5.4、vue3、tdesign-vue-next开发的全栈前后端分离的管理系统

goframe-admin goframe-admin V1.0.0 平台简介 基于goframe2.5.4、vue3、tdesign-vue-next开发的全栈前后端分离的管理系统。前端采用tdesign-vue-next-starter 、vue3、pinia、tdesign-vue-next。 特征 高生产率&#xff1a;几分钟即可搭建一个后台管理系统认证机制&#x…

华为云资源搭建过程

网络搭建 EIP&#xff1a; 弹性EIP&#xff0c;支持IPv4和IPv6。 弹性公网IP&#xff08;Elastic IP&#xff09;提供独立的公网IP资源&#xff0c;包括公网IP地址与公网出口带宽服务。可以与弹性云服务器、裸金属服务器、虚拟IP、弹性负载均衡、NAT网关等资源灵活地绑定及解绑…

通过Google搜索广告传送的携带木马的PyCharm软件版本

导语 最近&#xff0c;一起新的恶意广告活动被发现&#xff0c;利用被入侵的网站通过Google搜索结果推广虚假版本的PyCharm软件。这个活动利用了动态搜索广告&#xff0c;将广告链接指向被黑客篡改的网页&#xff0c;用户点击链接后下载的并不是PyCharm软件&#xff0c;而是多种…

【代码数据】2023粤港澳大湾区金融数学建模B题分享

基于中国特色估值体系的股票模型分析和投资策略 首先非常建议大家仔细的阅读这个题的题目介绍&#xff0c;还有附赠的就是那个附件里的那几篇材料&#xff0c;我觉得你把这些内容读透理解了&#xff0c;就可以完成大部分内容。然后对于题目里它主要第一部分给出了常用的估值模…

AttributeError: partially initialized module ‘pandas‘ has no attribute ‘core‘

在使用jupyter notebook学习动手学深度学习时&#xff0c;出现以下错误&#xff1a; %matplotlib inline import math import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2lbatch_size, num_steps 32, 35 train_iter, voca…

android 8.1 disable unsupported sensor

如果device不支持某种sensor,可以在android/frameworks/base/core/java/android/hardware/SystemSensorManager.java里将其disabled掉。以disable proximity sensor为例。 public SystemSensorManager(Context context, Looper mainLooper) {synchronized(sLock) {if (!sNativ…

C#项目设计——学生成绩管理系统设计

学生成绩管理系统C语言.Net C#项目设计 全套代码加数据库文件&#xff0c;带设计报告&#xff0c;带设计报告哦&#xff01; 可以用Microsoft Visual Studio打开 用户名和密码在数据里。 报告部分内容&#xff1a; 设计一个学生成绩管理系统。包括“登录窗体”、“主窗体”和…

idea中启动多例项目配置

多实例启动 日常本地开发微服务项目时&#xff0c;博主想要验证一下网关的负载均衡以及感知服务上下线能力时&#xff0c;需要用到多实例启动。 那么什么是多实例启动嘞&#xff1f;简单说就是能在本地同时启动多个同一服务。打个比方项目中有一个 MobileApplication 服务&…

服务熔断保护实践--Sentinal

目录 概述 环境说明 步骤 Sentinel服务端 Sentinel客户端 依赖 在客户端配置sentinel参数 测试 保护规则设置 设置资源名 设置默认的熔断规则 RestTemplate的流控规则 Feign的流控规则 概述 微服务有很多互相调用的服务&#xff0c;构成一系列的调用链路&#xf…

蜜罐系统HFish的部署与功能实测

1. 引入 根据参考1对蜜罐的定义&#xff1a; 蜜罐&#xff08;Honeypot&#xff09;是一个计算机科学领域的术语&#xff0c;指用于检测或防御未经授权的行为或黑客攻击的陷阱。其名称来源于其工作原理类似于用来诱捕昆虫的蜜罐。蜜罐通常伪装成看似有利用价值的网路、资料、…

3.15每日一题(分部积分求不定积分)

解法一&#xff1a;令lnx等于t&#xff1b;求出x与t的关系&#xff0c;带入f(lnx)的式子中&#xff1b;通过凑微分&#xff0c;分部积分等方法求出答案 注&#xff1a;在分部积分后&#xff0c;求不定积分时 &#xff08;1&#xff09;可以加项减项拆的方法求&#xff08;常规…