前文:面向过程手写 Spring IoC手写 Spring IoC 模块设计手写 Spring IoC 容器 —— BeanDefinition 加载与解析
手写 Spring IoC 容器 —— Bean 的实例化与依赖注入引言在 Spring IoC 容器的核心功能中,Bean 的实例化与依赖注入至关重要。
本文将实现 Spring IoC 的实例创建部分:
定位并加载XML资源文件
创建Document文档对象
解析Document文档
解析Document中的Bean标签
注册BeanDefinition
1. BeanFactory 设计BeanFactory 是 Spring IoC 容器的顶级接口,定义了 getBean 方法。
123456789/ * Spring 容器的顶级接口 */public interface BeanFactory { / * 根据 bean 名称获取实例 */ Object getBean(String beanName);}
设计思路:
统一所有 IoC 容器的基本行为。
允许不同 ...
前文:面向过程手写 Spring IoC手写 Spring IoC 模块设计
手写 Spring IoC 容器 —— BeanDefinition 加载与解析引言在 Spring IoC 容器中,BeanDefinition 负责描述 Bean 的基本信息,如类名、作用域、初始化方法等。本文先实现 Spring IoC 的核心模块之一:BeanDefinition 加载与解析。
主要功能
资源加载:从 XML 文件中读取配置信息。
解析 XML:解析 XML 文件内容并转换为 BeanDefinition 对象。
注册 BeanDefinition:将解析后的 BeanDefinition 存储到 BeanDefinitionRegistry。
1. 资源加载Spring 允许从多种来源(如 Classpath、文件系统、网络等)加载 XML 配置文件。这里我们定义 Resource 接口,提供统一的资源访问方式。
1.1 资源接口123456/ * 提供对资源的操作功能(资源可能存在于磁盘、网络、classpath等) */public interface Resource ...
Spring IoC 模块面向对象设计1. 设计概述基于Spring IoC容器的核心机制,主要涉及Bean的定义、加载、解析、注册以及实例化等关键步骤,采用面向对象设计(OOD)来实现各个组件的协作关系。
2. 主要模块及其职责BeanDefinition 加载模块该模块负责从XML资源文件中解析并加载Bean定义。
主要流程
定位并加载XML资源文件
创建Document文档对象
解析Document文档
解析Document中的Bean标签
注册BeanDefinition
相关类
BeanDefinition
beanName: String
className: String
classType: Class
scope: String
initMethod: String
propertyValues: List<PropertyValue>
PropertyValue
name: String
value: Object
TypedStringValue
value: String
targetType: Class
RuntimeBea ...
Spring 框架的意义Spring 框架是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,它的核心是控制反转和依赖注入。
控制反转(IoC):将对象的创建和对象之间的依赖关系交给 Spring 容器管理,降低了组件之间的耦合度。
举个例子看看如果没有 IoC
123456789101112131415161718192021222324252627/** * 使用者根本不想关心UserServiceImpl对象是怎么new的,他只是想测试查询功能。 * IoC要做的事情,就是让使用对象的同学只需要找工厂去要对应的对象即可,不需要自己创建。 * IoC是将创建对象的权利,由程序员这边,反转给spring容器去创建 */@Testpublic void test(){ // 需要创建userService对象, 还需要创建userDao对象(依赖注入userservice), 还需要创建dataSource对象(依赖注入userDao) UserServiceImpl userService = new UserServiceImpl(); ...
1. 智能体与搜索问题1. 理性智能体(Rational Agents)智能体(Agent) 是一个能 感知(perceive) 环境并 采取行动(act) 的实体。理性智能体(Rational Agent) 选择 能最大化预期效用(expected utility) 的行为。智能体的决策受以下因素影响:感知能力(Percepts)环境特性(Environment)行动空间(Action Space)理性智能体的特点不是全知全能(Omniscient):它们只能根据感知到的信息做决策。不是预知未来(Clairvoyant):它们无法提前知道所有环境的动态变化。必须探索和学习(Exploration & Learning):在未知环境中,智能体需要不断调整策略。智能体 ≠ 绝对成功理性智能体不一定总是成功,但它们能 自主行动(Autonomous),尽可能地做出最佳决策。2. 智能体的 PEAS 结构智能体的行为可以用 PEAS(Performance Measure, Environment, Actuators, ...
1. 优惠券活动查询缓存预热
1. 定时程序预热通过定时任务,查询数据库中一个月内即将开始或者已开始的优惠券活动。同时将活动的优惠券库存写入缓存,已开始的活动库存不更新,未开始的活动库存更新。定时程序代码
12345678910111213/** * 活动预热,整点预热 * */@XxlJob("activityPreheat")public void activityPreHeat() { log.info("优惠券活动定时预热..."); try { activityService.preHeat(); } catch (Exception e) { e.printStackTrace(); }}
service代码
1234567891011121314151617181920212223242526272829303132333435363738@Overridepublic void preHeat() { / ...
1. 配置过滤器过滤器通过 Spring 的 FilterRegistrationBean 注册,拦截所有请求,并按顺序进行处理。
1234567891011121314151617@Configurationpublic class UserConfiguration { /** * 用户操作流量风控过滤器 */ @Bean @ConditionalOnProperty(name = "short-link.flow-limit.enable", havingValue = "true") public FilterRegistrationBean<UserFlowRiskControlFilter> globalUserFlowRiskControlFilter( StringRedisTemplate stringRedisTemplate, UserFlowRiskControlConfiguration userFlowRiskCo ...
当有短链接访问时,收集短链接的访问数据,并发送到消息队列进行异步处理,确保高并发情况下的数据处理不会影响短链接访问的实时性。
生产者1234567891011121314151617181920212223242526272829@Component@RequiredArgsConstructorpublic class ShortLinkStatsSaveProducer { private final RocketMQTemplate rocketMQTemplate; @Value("${rocketmq.producer.topic}") private String statsSaveTopic; /** * 发送延迟消费短链接统计 */ public void send(Map<String, String> producerMap) { String keys = UUID.randomUUID().toString(); pr ...
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172@SneakyThrows@Overridepublic void restoreUrl(String shortUri, ServletRequest request, ServletResponse response) { // 短链接接口的并发量有多少?如何测试?详情查看:https://nageoffer.com/shortlink/question // 面试中如何回答短链接是如何跳转长链接?详情查看:https://nageoffer.com/shortlink/question String serverName = request.getServerName(); String serverPort = Optional.of(request.getServerPort ...
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091@Transactional(rollbackFor = Exception.class)@Overridepublic void updateShortLink(ShortLinkUpdateReqDTO requestParam) { verificationWhitelist(requestParam.getOriginUrl()); LambdaQueryWrapper<ShortLinkDO> queryWrapper = Wrappers.lambdaQuery(ShortLinkDO.class) .eq(ShortLinkDO::getGid, requestParam.ge ...