Spring Framework核心模块

news/2024/10/18 18:29:20/

core

Spring Core是Spring框架的基础API核心模块,提供了基本的IoC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入)功能。

core核心功能举例

资源管理-系统资源加载

FileSystemResource是Spring框架中的一个实现了Resource接口的类,用于从文件系统中加载资源。它可以根据指定的文件路径来加载文件系统中的资源。

当你使用FileSystemResource加载资源时,你需要提供一个文件路径,它指向文件系统中的实际文件。FileSystemResource将会根据提供的路径去访问文件系统并加载相应的资源。

Bean

bean核心功能举例-IOC容器/DI依赖注入

Spring Core提供了一个容器,也称为应用上下文(Application Context),它负责管理和装配应用程序中的对象。它实现了控制反转(IoC),即框架负责创建和管理对象的生命周期,而不是由开发人员手动创建和管理。同时还通过依赖注入管理对象间的依赖关系。对应的接口为:BeanFactory。

DI 依赖注入

BeanFactory通过Autowired实现依赖注入,AutowiredAnnotationBeanPostProcessor是@Autowire注解的实现类,它是一个后置处理器,用于在Bean实例化后对标记了@Autowired注解的字段、构造函数或方法进行依赖注入。它会扫描Bean中的@Autowired注解,解析注解所标记的依赖关系,并将相应的依赖对象注入到对应的位置。processInjection()方法是在Spring框架中用于执行依赖注入的方法。

	//缓存已检查过的成员变量private final Set<String> lookupMethodsChecked = Collections.newSetFromMap(new ConcurrentHashMap<>(256));//缓存类的候选构造函数private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache = new ConcurrentHashMap<>(256);//缓存类的依赖注入元数据private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);public void processInjection(Object bean) throws BeanCreationException {Class<?> clazz = bean.getClass();//查找Bean中的包含@Autowire注解的字段、构造方法、方法InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null);try {metadata.inject(bean, null, null);}catch (BeanCreationException ex) {throw ex;}catch (Throwable ex) {throw new BeanCreationException("Injection of autowired dependencies failed for class [" + clazz + "]", ex);}}//遍历方法实现private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {// Fall back to class name as cache key, for backwards compatibility with custom callers.String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());// Quick check on the concurrent map first, with minimal locking.InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);if (InjectionMetadata.needsRefresh(metadata, clazz)) {synchronized (this.injectionMetadataCache) {metadata = this.injectionMetadataCache.get(cacheKey);if (InjectionMetadata.needsRefresh(metadata, clazz)) {if (metadata != null) {metadata.clear(pvs);}metadata = buildAutowiringMetadata(clazz);this.injectionMetadataCache.put(cacheKey, metadata);}}}return metadata;}
DI 依赖查找

BeanFactory定义了依赖查找的方法。依赖查找是一种主动获取依赖对象的方式,用于获取其他Bean或依赖的实例。通过依赖查找,可以在需要的时候动态的获取所需的依赖对象,并在代码中使用。

AOP

面向切面编程(Aspect-Oriented Programming)是一种编程范式,旨在通过将横切关注点与主要业务逻辑分离,提供一种更好的代码组织和模块化的方式。

AOP的思想是将这些横切关注点从主要业务逻辑中抽离出来,形成一个独立的模块,称为切面。切面可以定义通过预定义的方式或者在运行时动态的与主业务逻辑进行织入,从而实现对横切关注点的统一处理。

AOP核心功能举例-AOP可以做什么

AOP可以将横切关注点从主要业务逻辑中分离出来,使主要业务逻辑更加清晰明了。

AOP可以消除重复的代码。通过使用AOP注解或配置,可以将需要切入的代码逻辑集中到切面中,从而避免在每个地方重复编写相同的代码。当切面需要修改时,只需修改一处逻辑,即可实现全局的变更。

AOP可以降低代码的复杂性。通过将横切关注点与主要业务逻辑分离,使得主要业务逻辑更加专注和清晰,减少了代码的混杂程度,提高了代码的可读性和可维护性。

下面是一个简单的例子,说明 AOP 如何解决日志记录的问题:

假设我们有一个类 UserService,其中包含了一些用户管理的方法,如 createUser()、deleteUser() 等。我们希望在每个方法执行前后记录日志。

传统方法
public class UserService {public void createUser(User user) {Logger.log("Creating user: " + user.getName());// 执行创建用户的逻辑Logger.log("User created: " + user.getName());}public void deleteUser(String userId) {Logger.log("Deleting user: " + userId);// 执行删除用户的逻辑Logger.log("User deleted: " + userId);}
}
使用AOP
public aspect LoggingAspect {before(): execution(public void UserService.*(..)) {Logger.log("Method execution started: " + thisJoinPoint.getSignature().getName());}after(): execution(public void UserService.*(..)) {Logger.log("Method execution completed: " + thisJoinPoint.getSignature().getName());}
}
public class UserService {public void createUser(User user) {// 执行创建用户的逻辑}public void deleteUser(String userId) {// 执行删除用户的逻辑}
}

Context

事件驱动、注解驱动、模块驱动等。

Context核心功能举例

	private final Set<Integer> registriesPostProcessed = new HashSet<>();private final Set<Integer> factoriesPostProcessed = new HashSet<>();/*** Prepare the Configuration classes for servicing bean requests at runtime* by replacing them with CGLIB-enhanced subclasses.*/@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {int factoryId = System.identityHashCode(beanFactory);if (this.factoriesPostProcessed.contains(factoryId)) {throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + beanFactory);}this.factoriesPostProcessed.add(factoryId);if (!this.registriesPostProcessed.contains(factoryId)) {// BeanDefinitionRegistryPostProcessor hook apparently not supported...// Simply call processConfigurationClasses lazily at this point then.processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);}enhanceConfigurationClasses(beanFactory);beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));}

入参:BeanDefinitionRegistry接口定义了对Bean定义的注册和管理操作,用于注册、存储、管理Bean定义。

  • 通过该方法,可以扫描和解析@Configuration注解,将其转化为相应的Bean定义。
  • 通过该方法,可以处理@Bean注解,在解析@Configuration类时,processConfigBeanDefinitions()会处理其中使用@Bean注解的方法,创建对应的Bean定义,并将其注册到传入的BeanDefinitionRegistry对象中。
  • 处理其他注解相关的功能:除了@Bean注解外,processConfigBeanDefinitions()方法还会处理其他与注解相关的功能。例如,它会处理@Autowired注解、@Value注解、@Conditional注解等,以实现依赖注入、属性注入、条件化配置等功能。
  • 注册额外的Bean定义:在处理配置类和注解相关功能之后,processConfigBeanDefinitions()方法会将生成的Bean定义注册到传入的BeanDefinitionRegistry对象中。这样,这些配置类中定义的Bean就可以在Spring容器中被实例化和管理。

expression

Spring表达式语言模块。

public class SpelTest {public static void main(String[] args) {SpelExpressionParser parser = new SpelExpressionParser();Expression exp = parser.parseExpression("'xxx'.concat('yyy')");String value = (String) exp.getValue();System.out.println(value);exp = parser.parseExpression("'xxx'.bytes");byte[] bytes = (byte[]) exp.getValue();exp = parser.parseExpression("'xxx'.bytes.length");Object expValue = exp.getValue();System.out.println("length: " + expValue);UserDto userDto = new UserDto();userDto.setUserName("test");userDto.setRoleNameZh("admin");userDto.setId(1);UserDto userDto2 = new UserDto();userDto2.setUserName(userDto.getUserName());//定义解析器ExpressionParser expressionParser = new SpelExpressionParser();//制定表达式Expression expression = expressionParser.parseExpression("userName");// 2 使用解析器解析表达式,获取对象的属性值String name = (String) expression.getValue(userDto2);//获取解析结果System.out.println(name);//使用解析器解析表达式,获取对象的属性值并进行运算Expression exp2 = expressionParser.parseExpression("userName == 'xxx'");// 3.1 获取解析结果boolean result = exp2.getValue(userDto2, Boolean.class);System.out.println(result);//true}
}

http://www.ppmy.cn/news/1063003.html

相关文章

网络工程----小型网络配置1

此次作业设计&#xff1a; 硬件&#xff1a;二层交换机、三层交换机、路由、服务器、pc 配置知识&#xff1a;dhcp, dns配置&#xff0c;vlan划分&#xff0c;不同vlan间通信&#xff0c;静态路由&#xff0c;Nat动态地址&#xff0c; nat server映射&#xff0c;acl 配置命…

docker安装报错: Requires: container-selinux >= 2:2.74

一. docker 安装报错 [rootmaster01 opt]# sudo yum install docker-ce-19.03.15 docker-ce-cli-19.03.15 containerd.ioLoaded plugins: fastestmirror Repository epel-testing is listed more than once in the configuration Repository epel-testing-debuginfo is listed…

【算法系列总结之分组循环篇】

【算法系列总结之分组循环篇】 分组循环1446.连续字符1869.哪种连续子字符串更长1957.删除字符使字符串变好2038.如果相邻两个颜色均相同则删除当前颜色1759.统计同质子字符串的数目2110.股票平滑下跌阶段的数目1578.使绳子变成彩色的最短时间1839.所有元音按顺序排布的最长子字…

深度学习5:长短期记忆网络 – Long short-term memory | LSTM

目录 什么是 LSTM&#xff1f; LSTM的核心思路 什么是 LSTM&#xff1f; 长短期记忆网络——通常被称为 LSTM&#xff0c;是一种特殊的RNN&#xff0c;能够学习长期依赖性。由 Hochreiter 和 Schmidhuber&#xff08;1997&#xff09;提出的&#xff0c;并且在接下来的工作中…

【FreeRTOS】【应用篇】任务管理相关函数

文章目录 前言一、函数解析1. 任务挂起 vTaskSuspend()① 使用场景② 设计思路③ 代码 2. 任务恢复 vTaskResume()① 作用② 设计思路③ 代码 3. 挂起任务调度器 vTaskSuspendAll()① 作用② 代码 4. 恢复任务调度器 xTaskResumeAll()① 设计思路② 代码 5. 任务删除函数 vTask…

什么是 RESTful API

什么是 RESTful API&#xff1f; RESTful API是一种设计哲学和架构风格&#xff0c;它基于 HTTP 协议和其状态管理原则&#xff0c;用于构建分布式系统。RESTful API 遵循以下设计原则&#xff1a; 资源层&#xff1a;API 应该代表一种资源&#xff0c;例如一个用户、一个订单…

芯科科技宣布推出下一代暨第三代无线开发平台,打造更智能、更高效的物联网

第三代平台中的人工智能/机器学习引擎可将性能提升100倍以上 Simplicity Studio 6软件开发工具包通过新的开发环境将开发人员带向第三代平台 中国&#xff0c;北京 - 2023年8月22日 – 致力于以安全、智能无线连接技术&#xff0c;建立更互联世界的全球领导厂商Silicon Labs&…

【八股】2023秋招八股复习笔记4(MySQL Redis等)

文章目录 目录1、MySQLmysql索引实现mysql索引优化mysql索引失效的情况mysql 千万数据优化mysql 事务隔离级别 & 实现原理mysql MVCC版本链&#xff08;undo log&#xff09;mysql数据同步机制 & 主从复制 &#xff08;binlog&#xff09;mysql 日志&数据恢复&…