"Spring Framework Running" 是指在 Spring 框架中运行应用程序的过程和相关内容。Spring Framework 提供了一个强大的运行时环境,用于构建企业级的Java应用程序。
Data Access/Integration(数据访问/集成):
Data Access/Integration 模块提供了与数据访问和集成相关的功能和工具。它包括对 JDBC、ORM(如 Hibernate)、事务管理和数据访问模板(如 JdbcTemplate)的支持,以及对集成框架(如 Spring Data)的集成。
Web(Web 应用程序开发):
Web 模块提供了 Spring Framework 在 Web 应用程序开发方面的支持。它包括 Spring MVC(Model-View-Controller)框架,用于开发 Web 应用程序的控制器、视图和模型层。此外,它还提供了对 WebSocket、RESTful Web Services、静态资源处理等功能的支持。
AOP(面向切面编程):
AOP 模块(Aspect-Oriented Programming)提供了面向切面编程的支持。它允许您通过定义切面(Aspect)和通知(Advice),在应用程序的多个组件中模块化地应用与业务逻辑无关的功能,如事务管理、安全性和日志记录等。
Aspect(切面):
Aspect 模块提供了 AOP 的基本功能,包括切点(Pointcut)、通知(Advice)、切面(Aspect)和连接点(Join Point)等。它为应用程序提供了对切面的定义和配置的能力。
Instrumentation(应用程序仪表化):
Instrumentation 模块提供了 Spring Framework 的仪表化和监控功能。它允许您通过使用 Java Instrumentation API,将代理注入到应用程序中的类中,从而监控和收集应用程序的运行时数据。
Messaging(消息传递):
Messaging 模块提供了与消息传递相关的功能和组件。它支持消息驱动的应用程序开发,包括消息发送和接收、消息转换、消息路由和消息端点等。
Core Container(核心容器):
- Beans: Beans 组件是 Spring Framework 的基础,它提供了依赖注入(DI)和控制反转(IoC)容器的实现。该组件负责管理和实例化应用程序中的对象(即 Beans),并处理它们之间的依赖关系。Beans 组件提供了创建、配置和管理 Beans 的机制,使得应用程序的组件能够被轻松地装配和使用。
-
Core: Core 组件提供了 Spring Framework 的核心功能和基础设施,包括资源加载、类型转换、事件处理、异常处理等。它包含了许多实用的工具类和基本的类库,用于支持其他 Spring 模块和应用程序开发。
-
Context: Context 组件是 Spring 应用程序上下文(Application Context)的实现,是 Spring Framework 的核心容器。它是 Beans 组件的扩展,提供了更高级的功能和特性,如国际化、事件发布、Bean 生命周期管理、AOP 集成等。Context 组件负责加载配置文件(如 XML 配置文件)或基于注解的配置,并创建和管理应用程序中的对象。
-
SpEL(Spring Expression Language): SpEL 是 Spring Framework 中的表达式语言,用于在运行时对对象进行查询和操作。它提供了一种灵活而强大的方式来访问和操作应用程序中的对象属性和方法,支持数学运算、逻辑运算、方法调用、属性访问等。SpEL 可以在配置文件(如 XML 配置文件)或注解中使用,使得配置更加动态和灵活。
Spring是一个开源的Java框架,用于构建企业级应用程序
Spring框架的核心特点包括:
-
DI (依赖注入)(Dependency Injection):Spring通过依赖注入机制来管理应用程序中的对象依赖关系。这样可以减少代码的耦合度,提高了代码的可测试性和可维护性。
- IOC(控制反转):IOC是一种设计原则,也是Spring框架的基础。它通过将对象的创建、组装和管理交给容器来实现,从而反转了传统应用程序中对象的控制权。在传统的应用程序中,对象的创建和依赖关系由开发人员手动管理,而在Spring框架中,开发人员只需要定义对象的依赖关系,容器会负责创建和管理对象。这种反转的控制方式减少了代码的耦合度,提高了代码的可测试性、可维护性和可扩展性。
- AOP(面向切面编程):AOP是一种编程范式,用于将横切关注点(如事务管理、安全性、日志记录等)从主要业务逻辑中分离出来。在传统的应用程序中,这些横切关注点往往会散布在各个业务模块中,导致代码的重复和散乱。AOP通过定义切面(Aspect)来集中处理这些横切关注点,从而提供了更好的代码模块化和重用性。在Spring框架中,AOP可以通过配置或注解来实现,开发人员可以将切面逻辑与主要业务逻辑分离开来,使代码更加清晰和易于维护。
详细介绍
DI:(Dependency Injection)
“依赖”是一个组件使用另一个组件的类、接口、方法、库、配置文件或其他资源。依赖描述了组件之间的相互关系,以及它们之间的依赖关系。
"注入"(Injection)是一种将依赖项传递给对象的过程,通过这种方式,对象可以获得所需的依赖项,而不需要自己创建或查找依赖项。
在 Spring 中,依赖注入可以通过以下方式进行:
-
构造函数注入(Constructor Injection): 通过构造函数将依赖项作为参数传递给对象。对象在被创建时,容器会负责实例化依赖项,并通过构造函数将其注入到对象中。
-
Setter 方法注入(Setter Injection): 通过 setter 方法将依赖项注入到对象中。对象在被创建后,容器会调用对象的 setter 方法,并将依赖项作为参数传递给这些方法,从而实现注入。
-
接口注入(Interface Injection): 通过接口定义注入方法,对象需要实现该接口,并在容器中声明注入方法。容器在创建对象后,通过调用注入方法将依赖项注入到对象中。
在 UserService
中,通过注入 UserRepository
,实际上是将 UserRepository
的实例传递给 UserService
对象,以便在 UserService
中可以访问和使用 UserRepository
中定义的方法。
1 2 3 4 5 6 7 8 9 10 11 | public class UserService { private UserRepository userRepository; // 构造函数注入 public UserService(UserRepository userRepository) { this.userRepository = userRepository; } // 其他方法... } UserService 类通过构造函数接收一个 UserRepository 对象作为参数,并将其赋值给 userRepository 字段。 |
1 2 3 4 5 6 7 8 9 10 11 | public class UserService { private UserRepository userRepository; // Setter方法注入 public void setUserRepository(UserRepository userRepository) { this.userRepository = userRepository; } // 其他方法... } UserService 类提供了一个名为 setUserRepository 的Setter方法,通过该方法将 UserRepository 实例注入到 userRepository 字段 |
1 2 3 4 5 6 | public class UserService { @Autowired private UserRepository userRepository; // 其他方法... }< br >< code >@Autowired</ code > 注解用于标记 < code >userRepository</ code > 字段,告诉Spring需要自动将 < code >UserRepository</ code > 的实例注入到该字段 |
IOC:(Inversion of Control)
控制的是对象的创建、组装和生命周期的管理。传统的应用程序开发中,对象的创建和管理通常由java程序代码自己控制,即应用程序代码负责创建对象并处理对象之间的依赖关系。而在控制反转中,控制的权力被转移到框架或容器中。框架负责创建和管理对象,并处理对象之间的依赖关系
"反转"(Inversion)指的是一种变换或倒置的概念。传统的应用程序开发中,对象的创建和依赖关系的管理由应用程序代码自行控制,这被称为"正转"(正常控制流)。而在控制反转中,这种控制关系被反转,即由框架或容器来负责对象的创建和依赖关系的管理
传统:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 假设我们有两个类,一个是 UserService,另一个是 UserRepository。UserService 依赖于 UserRepository 来进行数据持久化操作。 传统的应用程序开发方式中,UserService 负责创建 UserRepository 对象并调用其方法: public class UserService { private UserRepository userRepository; public UserService() { this.userRepository = new UserRepository(); } public void addUser(User user) { userRepository.save(user); } }< br >在这种情况下,< code >UserService</ code > 自己负责创建和管理 < code >UserRepository</ code > 对象。 |
框架:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | UserRepository 类负责处理用户数据的持久化操作。可以是接口,可以是类 public interface UserRepository { void save(User user); void update(User user); void delete(User user); User findById(String id); List< User > findAll(); }< br >public class UserRepositoryImpl implements UserRepository { @Override public void save(User user) { // 实现保存用户到数据库的逻辑 } @Override public void update(User user) { // 实现更新用户信息到数据库的逻辑 } @Override public void delete(User user) { // 实现从数据库中删除用户的逻辑 } @Override public User findById(String id) { // 实现根据ID从数据库中获取用户的逻辑 return null; } @Override public List< User > findAll() { // 实现从数据库中获取所有用户的逻辑 return null; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 如果UserRepository是一个类 public class UserRepository { public void save(User user) { // 实现保存用户到数据库的逻辑 } public void update(User user) { // 实现更新用户信息到数据库的逻辑 } public void delete(User user) { // 实现从数据库中删除用户的逻辑 } public User findById(String id) { // 实现根据ID从数据库中获取用户的逻辑 return null; } public List< User > findAll() { // 实现从数据库中获取所有用户的逻辑 return null; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 在UserService类中,可以编写业务逻辑和方法,以实现具体的用户服务功能。这些功能可能包括用户注册、登录、获取用户信息等操作< br >UserService 类依赖于 UserRepository,并在其基础上提供业务逻辑操作,可以包含以下方法< br >public class UserService { private UserRepository userRepository; public void setUserRepository(UserRepository userRepository) { this.userRepository = userRepository; } public void createUser(User user) { // 执行一些创建用户的业务逻辑 userRepository.save(user); } public void updateUser(User user) { // 执行一些更新用户的业务逻辑 userRepository.update(user); } public void deleteUser(User user) { // 执行一些删除用户的业务逻辑 userRepository.delete(user); } public User getUserById(String id) { // 执行一些获取用户的业务逻辑 return userRepository.findById(id); } public List< User > getAllUsers() { // 执行一些获取所有用户的业务逻辑 return userRepository.findAll(); } } |
1 2 3 4 5 6 7 8 9 10 11 | Spring Framework 来进行控制反转。需要在 Spring 的配置文件中声明 UserService 和 UserRepository 的 Bean。< br > < bean id="userRepository" class="com.example.UserRepository" /> < bean id="userService" class="com.example.UserService"> < property name="userRepository" ref="userRepository" /> </ bean > 在这里,我们将 UserRepository 和 UserService 都声明为 Spring 的 Bean。通过 ref 属性,我们将 UserRepository 注入到 UserService 中。 接下来,创建测试类。当应用程序需要使用 UserService 时,我们可以从 Spring 容器中获取该对象:< br >创建容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");< br >获取对象 UserService userService = context.getBean("userService", UserService.class);< br >打印信息< br >System.out.printLn(.getName())< br >通过这种方式,我们实现了控制反转,将对象的创建和依赖关系的管理交给了 Spring 容器 |
AOP: (Aspect-Oriented Programming)
在传统的面向对象编程中,应用程序的核心业务逻辑被组织为对象和类的层次结构,但横切关注点(如日志记录、事务管理、安全性、缓存等)往往分散在不同的对象和类中。这导致了代码的重复、可维护性差以及困难的跟踪和调试。
切面(Aspect)是一种模块化单元,用于描述和实现横切关注点(Cross-cutting Concerns),它将横切关注点从应用程序的核心业务逻辑中分离出来,并提供一种在不改变核心业务逻辑代码的情况下,将横切关注点织入到应用程序中的方法。
切面是由切点(Join Point)和通知(Advice)组成的。切点表示在应用程序中的某个特定位置,通常是方法执行的特定时机。通知定义了在切点处执行的额外行为。Spring框架提供了以下几种通知类型:
- 前置通知(Before Advice):在切点方法执行之前执行的通知。
- 后置通知(After Advice):在切点方法执行之后执行的通知,无论是否发生异常。
- 返回通知(After Returning Advice):在切点方法成功执行并返回结果后执行的通知。
- 异常通知(After Throwing Advice):在切点方法抛出异常后执行的通知。
- 环绕通知(Around Advice):围绕切点方法执行的通知,可以在方法执行前后自定义额外行为。
传统方式的代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public class OrderService { public void placeOrder(Order order) { try { // 日志记录 System.out.println("Placing order: " + order.getId()); // 核心业务逻辑 // ... // 日志记录 System.out.println("Order placed successfully."); } catch (Exception e) { // 异常处理 System.out.println("Failed to place order: " + e.getMessage()); } } } 我们在placeOrder方法的开始和结束位置打印了日志,并在发生异常时进行了简单的异常处理。 |
Spring框架的AOP来实现相同的功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 我们需要定义一个切面类,其中包含日志记录和异常处理的通知方法。切面类使用Spring的注解来标识切点和通知。 import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Aspect @Component public class LoggingAspect { @Before("execution(* com.example.OrderService.placeOrder(..))") public void beforeAdvice() { System.out.println("Placing order..."); } @AfterReturning("execution(* com.example.OrderService.placeOrder(..))") public void afterReturningAdvice() { System.out.println("Order placed successfully."); } @AfterThrowing(pointcut = "execution(* com.example.OrderService.placeOrder(..))", throwing = "ex") public void afterThrowingAdvice(Exception ex) { System.out.println("Failed to place order: " + ex.getMessage()); } }< br >定义了三个通知方法:< code >beforeAdvice</ code >(前置通知)、< code >afterReturningAdvice</ code >(返回通知)和< code >afterThrowingAdvice</ code >(异常通知)。这些通知方法分别在切点方法< code >placeOrder</ code >的不同时机执行。 |
1 2 3 4 5 | 在Spring配置文件中启用AOP,并将切面类纳入Spring容器管理 < beans > < context:component-scan base-package="com.example" /> < aop:aspectj-autoproxy /> </ beans > |
1 2 3 4 5 6 7 8 9 | 在核心业务逻辑代码中简化为只包含核心功能,而无需关注日志记录和异常处理. public class OrderService { public void placeOrder(Order order) { // 核心业务逻辑 // ... } } |
我们使用Spring框架的AOP将横切关注点(日志记录和异常处理)从核心业务逻辑中分离出来。通过这种方式,我们可以更好地关注核心功能,并且可以在需要时轻松添加、修改或删除切面行为
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!