写点什么

高阶面经:Spring 框架全析

作者:王中阳Go
  • 2025-01-07
    山东
  • 本文字数:3010 字

    阅读完需:约 10 分钟

高阶面经:Spring框架全析

在 Java 开发的浩瀚世界里,Spring 框架无疑是一颗璀璨耀眼的明珠。无论是初涉编程领域的新手,还是经验丰富的资深开发者,都难以忽视它的强大与实用。它宛如一把万能钥匙,为诸多复杂的企业级应用开发难题解锁,那么 Spring 框架究竟是什么呢?下面就带你一探究竟。

一、Spring 框架 是什么?

Spring 是轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,可以很方便地对数据库进行访问、可以很方便地集成第三方组件。Spring 框架通过提供一系列的工具和特性,极大地简化了企业级 Java 应用的开发过程。它不仅提高了代码的可维护性和可测试性,还帮助开发者快速构建高效、可靠和可扩展的应用程序。


Spring 官网https://spring.io/


二、什么是控制反转(IOC)?

在传统的编程模型中,应用程序代码通常直接控制对象的创建和依赖关系。例如,一个对象需要依赖另一个对象时,通常会在代码中直接创建依赖对象。这种方式使得代码紧密耦合,不利于测试和维护。<br>控制反转的理念是将这种控制权从应用程序代码中移除,转而交给一个容器来管理。这个容器就是 Spring IOC 容器。通过这种方式,对象的创建和依赖关系的管理被反转了,应用程序代码不再负责这些任务,而是由容器来处理。<br>而**依赖注入(DI)**是实现控制反转的一种方式。

Spring IOC 容器

Spring IOC 容器负责管理应用程序中对象的生命周期和依赖关系。


它的主要职责包括:<br>对象的创建:根据配置文件或注解创建对象。<br>依赖注入:将对象的依赖注入到相应的对象中。<br>对象的销毁:在适当的时候销毁对象,释放资源。<br>

三、Spring 的依赖注入是什么?

依赖注入(Dependency Injection,简称 DI)是 Spring 框架实现控制反转(IOC)的主要手段。DI 的核心思想是将对象的依赖关系从对象内部抽离出来,通过外部注入的方式提供给对象。这样,依赖对象的创建和管理由 Spring 容器负责,而不是由对象自身负责,使得代码更加模块化、松耦合和易于测试。<br>在传统编程中,一个对象通常会自己创建它所依赖的其他对象。这种方式使得代码紧密耦合,不利于维护和测试。依赖注入通过将依赖关系从代码中移除,转而由外部容器(如 Spring 容器)来注入,从而实现了对象之间的松耦合。

依赖注入的配置方式

XML 配置:通过 XML 文件定义 Bean 及其依赖关系。


<beans>    <bean id="repository" class="com.example.Repository"/>    <bean id="service" class="com.example.Service">        <constructor-arg ref="repository"/>    </bean></beans>
复制代码


Java 配置:通过 Java 类和注解定义 Bean 及其依赖关系。


@Configurationpublic class AppConfig {    @Bean    public Repository repository() {        return new Repository();    }    @Bean    public Service service() {        return new Service(repository());    }}
复制代码


注解配置:通过注解(如 @Component,@Autowired)自动扫描和注入 Bean。


@Componentpublic class Repository {}@Componentpublic class Service {    @Autowired    private Repository repository;}
复制代码

四、什么是 AOP

aop 是 spring 框架的一个核心。常见的可以做日志记录,事务管理等公共性的处理。当我们想要统一做一些水平统一的操作的时候,就常用 aop。<br>aop 的核心概念就是面向切面变成。通过 aop 可以在范围内的类方法执行之前,执行之后,或者异常的时候,做统一的操作。<br>aop 可以提高代码的可维护性,任何修改只需要在切面中进行,而不需要修改业务逻辑代码。<br>基于动态代理机制,还可以在不修改源代码的情况下为现有代码添加功能。在 boot 应用使用中,只需要配合 Aspect 注解,即可实现功能。<br>


@Aspect@Componentpublic class LogAspect {    // 定义切点 在执行UserService的每个方法前执行:    @PointCut("execution(public * com.mszlu.service.UserService.*(..))")    public void pt() {}
//定义通知 @Around("pt()") public Object doLogging(ProceedingJoinPoint pjp) throws Throwable{ //方法调用 Object ret = pjp.proceed(); return ret; }}
复制代码

五、说说 Spring 常用的注解


**@Component:**将一个类标记为 Spring 组件类,表示这个类的实例将由 Spring 容器管理。<br>**@Autowired:**自动注入依赖对象。可以用于构造器、字段、Setter 方法或其他任意方法。<br>**@Qualifier:**在有多个候选 Bean 时,指定要注入的 Bean。通常与 @Autowired 一起使用。<br>


@Componentpublic class MyComponent {    @Autowired    @Qualifier("specificBean")    private Dependency dependency;}
复制代码


**@Configuration:**标记一个类为 Spring 配置类,该类可以包含一个或多个 @Bean 方法。


@Configurationpublic class AppConfig {    @Bean    public MyComponent myComponent() {        return new MyComponent();    }}
复制代码


**@Bean:**定义一个方法,返回一个要注册为 Spring 容器管理的 Bean。


@Beanpublic MyComponent myComponent() {    return new MyComponent();}
复制代码


**@Service:**标记一个类为服务层组件,实际上是 @Component 的特殊化。


@Servicepublic class MyService {    // 服务逻辑}
复制代码


**@Repository:**标记一个类为数据访问层组件,实际上是 @Component 的特殊化,并且支持持久化异常转换。


@Repositorypublic class MyRepository {    // 数据访问逻辑}
复制代码


**@Controller:**标记一个类为 Spring MVC 控制器,实际上是 @Component 的特殊化


@Controllerpublic class MyController {    // 控制器逻辑}
复制代码


**@RestController:**标记一个类为 RESTful Web 服务的控制器,等同于 @Controller 和 @ResponseBody 的组合。


@RestControllerpublic class MyRestController {    @GetMapping("/hello")    public String hello() {        return "Hello, World!";    }}
复制代码


**@Aspect:**标记一个类为切面类。


@Aspect@Component
public class MyAspect { // 切面逻辑}
复制代码


**@Before:**定义一个方法,在目标方法执行之前执行。


@Aspect@Componentpublic class MyAspect {    @Before("execution(* com.example.service.*.*(..))")
复制代码


public void beforeMethod(JoinPoint joinPoint) {    // 前置逻辑}
复制代码


}**@After:**定义一个方法,在目标方法执行之后执行。


@Aspect@Componentpublic class MyAspect {    @After("execution(* com.example.service.*.*(..))")    public void afterMethod(JoinPoint joinPoint) {        // 后置逻辑    }}
复制代码


**@Around:**定义一个方法,包围目标方法的执行


@Aspect@Componentpublic class MyAspect {    @Around("execution(* com.example.service.*.*(..))")    public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {        // 环绕逻辑        return joinPoint.proceed();    }}
复制代码


**@Transactional:**标记一个方法或类,表示该方法或类中的所有方法都需要事务管理。


@Servicepublic class MyService {    @Transactional    public void performTransaction() {        // 事务逻辑    }}
复制代码


就业陪跑训练营学员投稿

欢迎关注 ❤

我们搞了一个免费的面试真题共享群,互通有无,一起刷题进步。


没准能让你能刷到自己意向公司的最新面试题呢。


感兴趣的朋友们可以加我微信:wangzhongyang1993,备注:infoq 面试群。

用户头像

王中阳Go

关注

靠敲代码在北京买房的程序员 2022-10-09 加入

【微信】wangzhongyang1993【公众号】程序员升职加薪之旅【成就】InfoQ专家博主👍掘金签约作者👍B站&掘金&CSDN&思否等全平台账号:王中阳Go

评论

发布
暂无评论
高阶面经:Spring框架全析_Java_王中阳Go_InfoQ写作社区