自定义迷你版Spring框架

2023-10-10 12:20

本文主要是介绍自定义迷你版Spring框架,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

自定义迷你版Spring框架

一、需求概述

​ 自定义@Service、@Autowired、@Transactional注解类,完成基于注解的IOC容器(Bean对象创建及依赖注入维护)和声明式事务控制,写到转账工程中,并且可以实现转账成功和转账异常时事务回滚

二、实现思路分析

根据需求的描述,我们可以参考spring框架的xml文件启动方式简单实现

1.创建配置文件beans.xml 配置一个包扫描路径

2.根据包扫描路径我们可以得到包以及子包下的所有类全限定名

3.根据反射对带有@Service注解的类进行实例化存到缓存并把有实例对象的bean以及beanDefinition放入缓存

4.对带有Autowired注解的属性注入对象实例并赋值

三、主要代码实现展示

public class DefaultAnnotationHandler {private Map<Class<?>, BeanDefinition> hasInstanceBeanCache = new HashMap<>();public void processAnnotations(List<String> allClassName) {if (allClassName != null) {for (String className : allClassName) {//根据类名对bean做加载注册到缓存map对象processAnnotations(className);}}}public void processAnnotations(String className) {Class<?> clazz = null;try {clazz = Class.forName(className);} catch (ClassNotFoundException e) {e.printStackTrace();}if (clazz == null) {return;}//如果反射获取到的类不为空且不是接口且不是注解的话做处理if (clazz != null && !clazz.isInterface() && !clazz.isAnnotation()) {// AAA.处理对象实例化Service service = clazz.getAnnotation(Service.class);//如果类上有@Service注解做处理if (service != null) {// 0.根据当前类名称注入 把beanDefinition(当前类的代理对象和bean实例)注入mapBeanDefinition beanDefinition = BeanFactory.registryBeanByInterface(clazz.getName(), clazz);// 1.service注解有指定idString id = service.value();if (!StringUtils.isEmpty(id)) {//如果在注解上加上了命名id则根据id注入beanDefinitionBeanFactory.registryBean(id, beanDefinition);}// 2.未指定ID,则根据父接口名注入beanDefinitionClass<?>[] interfaces = clazz.getInterfaces();if (interfaces != null) {for (Class<?> anInterface : interfaces) {BeanFactory.registryBeanByInterface(anInterface.getName(), beanDefinition);}}//把有实例对象的bean以及beanDefinition放入缓存hasInstanceBeanCache.put(clazz, beanDefinition);}}}//对带有Autowired注解的属性注入对象实例public void doProcessPropertiesBeanAutowired() {for (Map.Entry<Class<?>, BeanDefinition> entry : hasInstanceBeanCache.entrySet()) {Class<?> aClass = entry.getKey();//获取有实例对象bean的所有属性Field[] fields = aClass.getDeclaredFields();for (Field field : fields) {Autowired autowired = field.getAnnotation(Autowired.class);//如果属性带有Autowired注解且required=true那么就给属性依赖注入if (autowired != null && autowired.required()) {field.setAccessible(true);//根据属性类名获取对象Object   bean = BeanFactory.getBean(field.getType());try {//获取BeanDefinitionBeanDefinition needInjected = entry.getValue();//把对象实例赋值给对象field.set(needInjected.getInstance(), bean);} catch (IllegalAccessException e) {e.printStackTrace();}}}}hasInstanceBeanCache.clear();}
}

四、效果演示

在工程中能拿到注解对应的bean说明我们的IOC容器管理是没有问题的
然后在转账中故意制造了一个异常测试事务的效果
在这里插入图片描述
在这里插入图片描述
工程结构
在这里插入图片描述

五、总结

通过以上需求那么我们对基本的自定义Spring框架是有了一定的了解,那么我们可以更好的理解spring的思想,对于看spring源码

也可以有一定的思路,希望大家有兴趣的哥们之间多探讨技术,有助于彼此的提升,不好的地方欢迎指出。

注意:数据源需要换成自己的本地数据库信息,工程中附带demo的sql脚本

代码地址:https://gitee.com/xiangaiya/csdn/tree/master/lagou-transfer

这篇关于自定义迷你版Spring框架的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/180403

相关文章

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

Springboot处理跨域的实现方式(附Demo)

《Springboot处理跨域的实现方式(附Demo)》:本文主要介绍Springboot处理跨域的实现方式(附Demo),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录Springboot处理跨域的方式1. 基本知识2. @CrossOrigin3. 全局跨域设置4.

springboot security使用jwt认证方式

《springbootsecurity使用jwt认证方式》:本文主要介绍springbootsecurity使用jwt认证方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录前言代码示例依赖定义mapper定义用户信息的实体beansecurity相关的类提供登录接口测试提供一

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu