当前位置: 首页 > news >正文

SSM-----Spring

1.Spring 的两大核心是什么?谈一谈你对 IOC 的理解? 谈一谈你对 DI 的理解? 谈一谈你对 AOP的理解?(必会)

Spring 的两大核心是 IoC(Inversion of Control,控制反转) 和 AOP(Aspect-Oriented Programming,面向切面编程)。它们共同支撑了 Spring 框架 “简化开发、解耦代码” 的核心目标。

  • 先说说 IoC,它本质是‘把对象的创建、依赖管理权从业务代码交给 Spring 容器’。具体来说,容器会先解析我们的配置(注解或 XML)生成 BeanDefinition(描述 Bean 的元信息,比如类型、依赖关系),再根据这个信息创建和管理 Bean。比如以前写 UserService,得手动 new UserDao;现在不用了,容器会按 BeanDefinition 自动创建 UserDao 实例,再关联到 UserService 里 —— 这不仅省了 new 的代码,更重要的是,如果 UserDao 换了实现类(比如从 JdbcDao 换成 MybatisDao),只需改配置,UserService 完全不用动,解耦效果很明显。而且容器还会管理 Bean 的生命周期,比如用 @PostConstruct 标注初始化逻辑,容器会在 Bean 创建后自动执行。

  • DI 是 IoC 的具体实现,就是‘容器创建对象时,自动把它依赖的东西注进去’。常用的构造器注入和 Setter 注入各有侧重:构造器注入适合‘必须依赖’(比如 Service 一定需要 Dao),能通过 final 关键字保证依赖不可变,还能避免循环依赖(容器会提前检测);Setter 注入更适合‘可选依赖’(比如给对象设置超时时间)。另外要注意,字段注入(直接 @Autowired 在字段上)虽然方便,但没法注入 final 字段,还可能隐藏循环依赖问题,所以我们团队一般禁用。

  • AOP 则是‘把日志、事务这些横切逻辑抽出来,和业务代码分开’。它的核心是通过动态代理在运行时织入逻辑:如果目标类有接口,用 JDK 动态代理(生成接口实现类作为代理);没接口就用 CGLIB(生成目标类的子类)。比如给 Service 加事务时,我们定义的 @Transactional 其实就是一个切面,里面的‘事务开启’是前置通知,‘提交 / 回滚’是后置通知,而‘哪些方法需要事务’是通过切入点表达式(比如 execution (* com.xxx.service…(…)))指定的。这样一来,业务方法里完全看不到事务代码,既减少重复,又方便统一修改(比如改事务隔离级别,只需改切面配置)。”

2.Spring 支持 bean 的作用域有几种吗? 每种作用域是什么样的?(必会)

Spring 支持多种 bean 作用域,主要分为通用环境(所有应用场景)Web 环境特有两类,每种作用域控制着 bean 实例的创建时机和生命周期:

  1. singleton(单例)
    这是默认作用域,指在整个 Spring 容器中,该 bean 只创建一个实例,所有请求(比如依赖注入或 getBean ())都会拿到同一个对象。它的生命周期和容器一致 —— 容器启动时创建(可配置懒加载),容器销毁时才销毁。
    适合无状态的 bean,比如 Service 层组件、工具类,因为单例共享实例,若有可变状态可能引发线程安全问题。
  2. prototype(原型)
    每次请求该 bean 时(比如注入或获取),容器都会新建一个实例。容器只负责创建,不管理销毁,实例由开发者或 GC 处理。
    适合有状态的 bean,比如用户的购物车对象,每个实例需要独立维护自己的数据。
  3. request(请求,Web 环境)
    每个 HTTP 请求会对应一个新的 bean 实例,仅在当前请求范围内有效,请求处理完就销毁。
    比如封装单次请求参数的对象,每次请求的数据互不干扰。
  4. session(会话,Web 环境)
    每个用户会话(HTTP Session)共享一个 bean 实例,会话有效期内可用,会话失效(超时或退出)时销毁。
    适合存储用户登录信息、会话级购物车等,比如用户在会话内操作的临时数据。
  5. application(应用,Web 环境)
    整个 Web 应用(ServletContext)中只创建一个实例,所有用户共享,生命周期和应用一致(应用启动创建,关闭销毁)。
    区别于 singleton:singleton 是 Spring 容器级单例(多容器可能多个),application 是应用级单例,比如全局系统配置参数。
  6. websocket(WebSocket 会话,Web 环境)
    每个 WebSocket 连接对应一个独立实例,仅在连接存续期间有效,连接关闭后销毁。
    适合实时通信场景,比如维护单个聊天连接的上下文信息。

实际开发中,singleton 和 prototype 最常用,Web 场景会根据需求选择 request 或 session 等作用域。


3.Spring 框架中都用到了哪些设计模式?(必会)

Spring 里用到很多经典设计模式,核心的有几种:

  1. 首先是工厂模式,比如 BeanFactory 和 ApplicationContext,负责创建管理 Bean,不用我们手动 new;
  2. 然后是单例模式,默认的 singleton Bean 就是靠它实现的,容器里只存一个实例;
  3. 还有代理模式,这是 AOP 的核心,JDK 动态代理(针对接口)和 CGLIB(针对无接口类)用来织入日志、事务这些增强逻辑;
  4. 另外像模板方法模式,比如 JdbcTemplate,定义了 JDBC 的流程,把 SQL 执行、结果映射这些可变部分留给我们;
  5. 还有观察者模式,比如 ApplicationEvent 和 ApplicationListener,用来做事件通信,比如容器初始化完成后触发缓存加载。这些模式本质上都是为了解耦和简化开发

4.Spring 事务的实现方式和实现原理(必会)

  1. 先说实现方式:
  • 编程式:手动写代码控制事务,比如用 TransactionTemplate,把业务逻辑丢进它的 execute 回调里,它会自动管开启、提交,异常了就回滚。但这种侵入业务代码,实际开发里很少用,除非需要特别定制事务逻辑。
  • 声明式:这是平时用得最多的,靠 @Transactional 注解,加在方法或类上就行。比如转账的 service 方法,加个 @Transactional,扣钱和加钱就会在一个事务里,任一失败都回滚,完全不用改业务代码。
  1. 原理的话,核心就三点:
  • 一是靠事务管理器对接数据库,比如用 MyBatis 时,用 DataSourceTransactionManager,它底层是拿数据库连接,设 autoCommit=false 来控制事务;
  • 二是AOP 动态代理,加了 @Transactional 的方法,Spring 会生成代理对象,在方法执行前开启事务,执行完正常就提交,抛了 RuntimeException(默认)就回滚;
  • 三是靠事务定义控规则,比如注解里配 propagation=REQUIRED(默认),意思是如果当前有事务就加入,没有就新建,像调用多个 service 方法时,能保证在一个事务里。

实际项目里,基本都是用声明式,就注意下 @Transactional 的生效条件(比如非 private 方法、没抛检查异常


5.Spring 的对象默认是单例的还是多例的? 单例 bean 存不存在线程安全问题呢?(必会)

  1. Spring 中 bean 的默认作用域是 单例(singleton)—— 也就是说,默认情况下,Spring 容器中只会创建一个 bean 实例,所有请求都会共享这个实例。

  2. 关于单例 bean 的线程安全问题,要分情况看

  • 如果是 无状态的 bean(比如大部分 Service 层组件、工具类,没有可修改的成员变量,或成员变量是常量 / 不可变对象),不存在线程安全问题。因为多线程访问时,仅调用方法,不会修改共享状态,比如一个只做查询的 Service 类。
  • 如果是 有状态的 bean(存在可修改的成员变量,比如在 bean 中定义了 userName 这样的变量,且有方法会修改它),多线程并发访问并修改这些变量时,就可能出现线程安全问题(比如数据错乱)。
  1. 实际开发中,我们通常会避免在单例 bean 中定义可变状态,所以大部分场景下(比如 Service、Repository 层)单例 bean 是线程安全的。如果确实需要维护状态,可通过以下方式解决:
  • 用 ThreadLocal 存储线程私有状态;
  • 将有状态的部分抽离为 prototype 作用域的 bean;
  • 对共享变量加锁(需谨慎,可能影响性能)。

简单说:单例是默认值,无状态则安全,有状态需额外处理。


6.Spring 的常用注解(必会)

  1. Bean 定义相关
  • @Component:通用注解,标注类为 Spring 管理的 Bean(组件),适用于不确定具体层的类。
    衍生注解(更语义化):
  • @Service:标注在业务逻辑层(Service) 类上,比如UserService,明确这是处理业务的 Bean。
  • @Controller:标注在Web 层(Controller) 类上,比如UserController,用于接收和处理请求。
  • @Repository:标注在数据访问层(Dao/Mapper) 类上,比如UserMapper,还能自动转换数据库操作异常。
  1. 依赖注入相关
  • @Autowired:自动按类型注入依赖(默认要求依赖必须存在,可加required=false允许为 null)。比如 Service 层注入 Mapper:@Autowired private UserMapper userMapper。
  • @Qualifier("beanName"):配合@Autowired使用,当同一类型有多个 Bean 时,按名称指定注入哪个,比如- @Qualifier(“userServiceImpl”)。
  • @Resource:JDK 自带注解,默认按名称注入,找不到再按类型,比如@Resource(name = “userMapper”)。
  1. 配置类相关
  • @Configuration:标注类为配置类(替代 XML 配置),类中用@Bean定义 Bean。
  • @Bean:标注在配置类的方法上,方法返回值会被注册为 Spring 的 Bean,比如定义数据源:@Bean public DataSource dataSource() { … }。
  1. AOP 相关
  • @Aspect:标注类为切面类,用于定义横切逻辑(如日志、权限)。
  • @Pointcut("execution(...)"):定义切入点,指定哪些方法需要被增强,比如@Pointcut(“execution(* com.xxx.service..(…))”)表示匹配所有 Service 的方法。
  • 通知注解:@Before(方法执行前)、@AfterReturning(方法正常返回后)、@Around(环绕方法执行,最常用),比如用@Around实现接口耗时统计。
  1. 事务相关
  • @Transactional:标注在 Service 方法或类上,声明事务控制,比如转账方法加此注解,保证扣钱和加钱操作原子性。可配置传播行为(如propagation=REQUIRED)、隔离级别等。
  1. Spring MVC 相关
  • 映射请求:@RequestMapping(“/user”)(通用)、@GetMapping(“/{id}”)(GET 请求)、@PostMapping(POST 请求),用于 Controller 方法上,指定请求路径。
  • 接收参数:@RequestParam(获取请求参数,如@RequestParam(“name”))、@PathVariable(获取 URL 路径参数,如@PathVariable(“id”))、@RequestBody(接收 JSON 请求体)。
  • 响应数据:@ResponseBody(将返回值转为 JSON,Controller 类加@RestController可省略此类注解)。

文章转载自:

http://C4nrKK8M.jpzcq.cn
http://8AEPVpiG.jpzcq.cn
http://5sEjDlFb.jpzcq.cn
http://bhAYBLUX.jpzcq.cn
http://wFgI3L3W.jpzcq.cn
http://BdPczYct.jpzcq.cn
http://PphVvsEQ.jpzcq.cn
http://09QQCtOX.jpzcq.cn
http://4xnRqUbS.jpzcq.cn
http://RGpahcCg.jpzcq.cn
http://rWfgxIaf.jpzcq.cn
http://Wx51rgjb.jpzcq.cn
http://pidih4KI.jpzcq.cn
http://rHmK6biL.jpzcq.cn
http://nTYVj4Cb.jpzcq.cn
http://fdyfzKlO.jpzcq.cn
http://Qv5RjQyx.jpzcq.cn
http://M7JxFXQc.jpzcq.cn
http://4aR3FjOP.jpzcq.cn
http://w8RLVDp3.jpzcq.cn
http://3YOztnrn.jpzcq.cn
http://LXeKQGx1.jpzcq.cn
http://X2uONJPI.jpzcq.cn
http://nSMhCdRx.jpzcq.cn
http://iAqE1kDC.jpzcq.cn
http://cg8rmyF3.jpzcq.cn
http://Ah3440AC.jpzcq.cn
http://b62sG5Ru.jpzcq.cn
http://bqmHcBOm.jpzcq.cn
http://yXYIBLFE.jpzcq.cn
http://www.dtcms.com/a/387384.html

相关文章:

  • ubuntu 24.04.02安装android-studio
  • WebRTC 定时任务Process Module
  • 【服务器挂掉了】A40和A800:“性能不足”和“系统崩溃”
  • EJS(Embedded JavaScript)(一个基于JavaScript的模板引擎,用于在HTML中嵌入动态内容)
  • 前端路由模式:Vue Router的hash模式和history模式详解
  • 信创电脑采购指南:选型要点与避坑攻略
  • 前端高级开发工程师面试准备一
  • window下Qt设置生成exe应用程序的图标
  • Linux(三) | Vim 编辑器的模式化架构与核心操作机制研究
  • Kubernetes 安全与资源管理:Secrets、资源配额与访问控制实战
  • Java基础知识总结(超详细)持续更新中~
  • 原生js过滤出对象数组中重复id的元素,并将其放置于一个同一个数组中
  • 《Python 对象创建的秘密:从 __new__ 到单例模式的实战演绎》
  • k8s 与 docker 的相同点和区别是什么?
  • Linux《线程(下)》
  • 第二部分:VTK核心类详解(第20章 vtkCamera相机类)
  • 线性回归与 Softmax 回归:深度学习入门核心模型解析
  • K8s配置管理:ConfigMap与Secret核心区别
  • 【Qt开发】显示类控件(四)-> QCalendarWidget
  • 【K8S系列】Kubernetes 调度与资源管理深度剖析:Requests、Limits、QoS 与 OOM
  • 小程序地图以及讲解的使用
  • 单分类线性逻辑回归
  • 使用POSTMAN 创建泛微OA流程
  • vscode中配置pytest
  • 液氮低温恒温器的应用领域
  • [Yolo遇到的问题] 使用VScode进行ultralytics训练 启动后在scanning阶段意外中断 导致训练无法正常启动
  • 微算法科技(NASDAQ:MLGO)研究分布式量子计算,释放量子计算潜能
  • 使用EasyExcel读不到数据的低级问题
  • 万象EXCEL开发(一)表头标尺搭建—东方仙盟筑基期
  • Redis 发展趋势与 Redis 7.x 新特性:从缓存到实时数据平台的演进