您的位置:首页 > 科技 > 能源 > 西安公司招聘信息_无锡企业网站制作公司_优化网站关键词排名软件_象山关键词seo排名

西安公司招聘信息_无锡企业网站制作公司_优化网站关键词排名软件_象山关键词seo排名

2025/6/23 5:56:01 来源:https://blog.csdn.net/Sweeping_Robot/article/details/147042133  浏览:    关键词:西安公司招聘信息_无锡企业网站制作公司_优化网站关键词排名软件_象山关键词seo排名
西安公司招聘信息_无锡企业网站制作公司_优化网站关键词排名软件_象山关键词seo排名

Spring

  1. Spring 和 Spring Boot 有什么区别

    • Spring
      • Spring 是一个全面的 Java 企业级应用程序开发框架,提供广泛的功能,包括依赖注入、AOP(面向切面编程)、事务管理等。
    • Spring MVC
      • Spring MVC 是 Spring 中的一个很重要的模块,主要赋予 Spring 快速构建 MVC 架构的 Web 程序的能力。MVC 是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。主要关注于处理 Web 请求、管理用户会话、控制应用程序流程等。
    • Spring Boot
      • Spring Boot 是一个微服务框架,延续了 Spring 框架的核心思想(C 和 AOP),简化了应用的开发和部署。Spring Boot 是为简化 Spring 应用的创建、运行、调试、部署等而出现的,提供约定大于配置的方式,使用它可以做到专注于 Spring 应用的开发,而无需过多关注 XML 的配置。使得构建独立的、自包含的 Spring 应用程序变得更加容易。
    • 总结
      • Spring 是一个全面的框架,Spring MVC 是 Spring 框架的一部分,专注于 Web 应用程序开发,而 Spring Boot 是基于 Spring 的微服务框架,旨在简化和加速 Spring 应用程序的开发。
  2. Spring 中有哪些常用注解

    • @Component
      • 作用:用于将一个类标识为 Spring 容器中的一个组件(Bean)。
    • @Autowired
      • 作用:用于自动装配 Bean。可以用在构造方法、Setter 方法、字段上,Spring 会自动查找匹配类型的 Bean 进行注入。
    • @Service
      • 作用:用于标识服务层的 Bean。
    • @Repository
      • 作用:用于标识持久层的 Bean。
    • @Controller
      • 作用:用于标识控制层的 Bean,将该类标记为控制器用于处理 HTTP 请求。
    • @RestController
      • 作用:与 @Controller 相同,但该注解表示返回的数据直接写入 HTTP 响应体中,常用于 RESTful 风格的控制器。
    • @Configuration
      • 作用:用于定义配置类,替代 XML 配置文件。
    • @Bean
      • 作用:在配置类中使用,用于声明一个 Bean。Spring 容器会根据配置类中的 @Bean 方法返回的实例来管理 Bean。
    • @RequestMapping
      • 作用:用于映射 HTTP 请求路径到 Controller 的处理方法上,定义请求的 URI 路径、请求方法、参数等。
    • @GetMapping
      • 作用:用于处理 GET 请求。
    • @PostMapping
      • 作用:用于处理 POST 请求。
    • @PutMapping
      • 作用:用于处理 PUT 请求。
    • @DeleteMapping
      • 作用:用于处理 DELETE 请求。
    • @PatchMapping
      • 作用:用于处理 PATCH 请求。
    • @Value
      • 作用:用于从属性文件或配置中读取值,将值注入到成员变量中。
    • @Qualifier
      • 作用:与 @Autowired 一起使用,指定注入时使用的 Bean 名称。
    • @Profile
      • 作用:用于定义不同环境下的配置,可以标识在类或方法上。
    • @Async
      • 作用:用于将方法标记为异步执行。
    • @Transactional
      • 作用:用于声明事务管理,可以指定事务的传播行为、隔离级别等。
  3. 对 Spring AOP 的理解

    • AOP(Aspect-Oriented Programming)
      • AOP 是面向切面编程,它允许开发者在不改动业务代码的情况下,横向切入添加新的功能,比如日志、事务管理等。降低各业务部分之间的耦合度。
    • AOP 的底层原理
      • AOP 的底层原理是基于 JDK 动态代理或 CGLIB 动态代理。通过反射机制,在不改变原代码的情况下,实现想要的功能。
    • OOP(Object-Oriented Programming)
      • OOP 是面向对象编程,它通过封装、继承、多态等概念来建立对象层次结构,用于模拟公共行为的一个集合。不过 OOP 允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性等,也都是如此。这种散布在各处的无关代码被称为横切(cross cutting),在 OOP 设计中,它导致了大量的代码重复,而不利于各个模块的重用。
    • AOP 的作用
      • AOP 技术恰恰相反,它利用一种称为 “横切” 的技术,剖解开封装的对象内部,并将那些影响多个类的公共行为封装到一个可重用模块,并将其命名为 “Aspect”(即切面)。所谓 “切面”,简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
    • AOP 核心概念
      • 横切关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点。
      • 切面(Aspect):类是对物体特征的抽象,切面就是对横切关注点的抽象。
      • 连接点(Joinpoint):被拦截到的点,因为 Spring 只支持方法类型的连接点,所以在 Spring 中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器。
      • 切入点(Pointcut):对连接点进行拦截的定义。
      • 通知(Advice):所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类。
      • 目标对象(Target Object):被代理的对象。
      • 织入(Weaving):将切面应用到目标对象并导致代理对象创建的过程。
      • 引入(Introduction):在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段。
    • Spring 对 AOP 的支持
      • Spring 中的 AOP 代理由 Spring 的 IOC 容器负责生成、管理,其依赖关系也由 IOC 容器负责管理。因此,AOP 代理可以直接使用容器中的其他 Bean 实例作为目标,这种关系可由 IOC 容器的依赖注入提供。
      • Spring 创建代理的规则为:
        • 默认使用 JDK 动态代理来创建 AOP 代理,这样就可以为任何接口实例创建代理。
        • 当需要代理的类不是代理接口的时候,Spring 会切换为使用 CGLIB 代理,也可强制使用 CGLIB。
    • 动态代理的方式
      • JDK 动态代理
        • JDK 动态代理只提供接口的代理,不支持类的代理。核心是 InvocationHandler 接口和 Proxy 类。
        • InvocationHandler 通过 invoke() 方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起。
        • 接着,Proxy 利用 InvocationHandler 动态创建一个符合某一接口的实例,生成目标类的代理对象。
      • CGLIB 动态代理
        • 如果代理类没有实现接口,Spring AOP 会选择使用 CGLIB 动态代理。
        • CGLIB 是一个代码生成的类库,可以在运行时动态地生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现 AOP。CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为 final,那么它是无法使用 CGLIB 做动态代理的。
    • AOP 编程的关键
      • 定义普通业务组件。
      • 定义切入点,一个切入点可能横切多个业务组件。
      • 定义增强处理,增强处理就是在 AOP 框架为普通业务组件织入的处理动作。
      • 一旦定义了合适的切入点和增强处理,AOP 框架将自动生成 AOP 代理,即代理对象的方法 = 增强处理 + 被代理对象的方法。
  4. 说说你对 Spring 中 IOC 的理解

    • IOC(Inversion of Control)
      • IOC 是一种设计思想,中文意思是 “控制反转”。在 Java 开发中,IOC 意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
      • 容器实际上就是一个 Map(key, value),Map 中存放的是各种对象。
      • 将对象之间的相互依赖关系交给 IOC 容器来管理,并由 IOC 容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。IOC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件(或注解),然后在需要的地方引用就行,完全不用考虑对象是如何被创建出来的。
      • 在实际项目中,一个 Service 类可能有几百甚至上千个类作为它的底层依赖。如果手动实例化这个 Service,可能需要搞清楚这个 Service 所有底层类的构造函数。但如果利用 IOC 的话,只需要配置好,然后在需要的地方引用即可。
      • 在 Spring 早期时代,我们一般通过 XML 文件来配置 Bean,后来开发人员觉得 XML 文件配置不太方便,于是 Spring Boot 注解配置就慢慢开始流行起来。
    • IOC 的好处
      • 使用 IOC 后,我们不需要自己去创建某个类的实例,而由 IOC 容器去创建。当需要使用某个对象时,直接到容器中去获取即可。
      • 提高了代码的可维护性和可扩展性,减少了代码之间的耦合度。
    • 实现方式
      • Spring 的 IOC 有三种注入方式:
        • 构造器注入:通过构造方法注入依赖的 Bean。
        • Setter 方法注入:通过 Setter 方法注入依赖的 Bean。
        • 注解注入:使用注解(如 @Autowired)自动注入依赖的 Bean。
  5. Bean 的作用域

    • 在 Spring 中,那些组成应用程序的主体及由 Spring IOC 容器所管理的对象,被称为 Bean。而 Bean 的作用域定义了在应用程序中创建的 Bean 实例的生命周期和可见范围。
    • 常见的作用域
      • Singleton(单例)
        • 这是默认的作用域。当一个 Bean 的作用域为 Singleton 时,Spring IOC 容器中只会存在一个共享的 Bean 实例,无论多少个 Bean 引用指向该 Bean 定义,都只会返回同一个 Bean 实例。
      • Prototype(原型)
        • 当一个 Bean 的作用域为 Prototype 时,表示一个 Bean 定义对应多个对象实例。每次对该 Bean 的请求都会创建一个新的 Bean 实例。因此,每次请求都会得到一个新的 Bean 实例。
      • Request(请求)
        • 只适用于 Web 程序。每次 HTTP 请求都会产生一个新的 Bean,该 Bean 仅在当前 HTTP request 内有效。当请求结束后,该 Bean 的生命周期即告结束。
      • Session(会话)
        • 只适用于 Web 程序。每一次 HTTP 请求都会产生一个新的 Bean,该 Bean 仅在当前 HTTP session 内有效。与 Request 作用域一样,可以根据需要放心地更改所创建实例的内部状态,而其他 HTTP session 中根据 userPreferences 创建的实例,将不会看到这些特定于某个 HTTP session 的状态变化。当 HTTP session 最终被废弃的时候,在该 HTTP session 作用域内的 Bean 也会被废弃掉。
      • Global Session(全局会话)
        • 类似于 Session 作用域,但仅在基于集群的 Web 应用程序中有意义,它指定了在整个集群中共享的 Bean 实例。
      • Application(应用范围)
        • 与 Servlet 的 ServletContext 生命周期相同,通常用于存储全局变量。
      • WebSocket(WebSocket 会话)
        • 每一次 WebSocket 会话产生一个新的 Bean。
  6. Bean 的生命周期

    • Bean 的生命周期包括以下几个阶段:
      1. 实例化
        • Spring 容器找到配置文件中 Bean 的定义。
        • Spring 容器利用 Java Reflection API 创建一个 Bean 的实例。
      2. 属性赋值
        • 如果涉及到一些属性值,利用 set() 方法设置一些属性值。
      3. 设置 Bean 的名字
        • 如果 Bean 实现了 BeanNameAware 接口,调用 setBeanName() 方法,传入 Bean 的名字。
      4. 设置 ClassLoader
        • 如果 Bean 实现了 BeanClassLoaderAware 接口,调用 setBeanClassLoader() 方法,传入 ClassLoader 对象的实例。
      5. 设置 BeanFactory
        • 如果 Bean 实现了 BeanFactoryAware 接口,调用 setBeanFactory() 方法,传入 BeanFactory 对象的实例。
      6. 设置后处理器
        • 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行 postProcessBeforeInitialization() 方法。
      7. 初始化
        • 如果 Bean 实现了 InitializingBean 接口,执行 afterPropertiesSet() 方法。
        • 如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。
      8. 设置后处理器(再次)
        • 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行 postProcessAfterInitialization() 方法。
      9. 销毁
        • 当要销毁 Bean 的时候,如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。
        • 如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法。
  7. Spring 循环依赖是怎么解决的

    • 什么是循环依赖
      • 循环依赖其实就是循环引用,也就是两个或者两个以上的 Bean 互相持有对方,最终形成闭环。例如,Bean A 依赖于 Bean B,而 Bean B 又依赖于 Bean A,形成了一个循环依赖关系。这种情况下,如果不处理,会导致 Spring 容器无法完成 Bean 的初始化,从而抛出 BeanCurrentlyInCreationException 异常。
      • 注意,这里不是函数的循环调用,是对象的相互依赖关系。循环调用其实就是一个死循环,除非有终结条件。
      • Spring 中循环依赖场景有:
        • 构造器的循环依赖
        • 字段属性的循环依赖
      • 其中,构造器的循环依赖问题无法解决,只能抛出 BeanCurrentlyInCreationException 异常。在解决属性循环依赖时,Spring 采用的是提前暴露对象的方法。
    • 怎么检测是否存在循环依赖
      • 检测循环依赖相对比较容易,Bean 在创建的时候可以给该 Bean 打标,如果递归调用回来发现正在创建中的话,即说明了循环依赖了。
    • 如何解决
      • 在 Spring 中,通过三级缓存来解决循环依赖问题,这三个缓存区被定义在 DefaultSingletonBeanRegistry 中,分别是:
        • singletonObjects:用来存储创建完毕的 Bean。
        • earlySingletonObjects:用来存储未完成依赖注入的 Bean。
        • singletonFactories:用来存储创建 Bean 的工厂。
      • 解决过程
        1. 首先调用 A 的构造方法实例化 A,当前的 A 还没有依赖注入,暂且把它称为半成品,此时会把 A 封装到一个 ObjectFactory 中,并存储到 singletonFactories 缓存区。
        2. 接下来要处理 A 的依赖注入。但由于还没有 B,所以要先实例化一个 B,同样的,半成品 B 也会被封装到 ObjectFactory 中,并存储到 singletonFactories 缓存区。
        3. 紧接着要处理 B 的依赖注入,此时会找到 singletonFactories 中 A 对应的 ObjectFactory,调用它的 getObject() 方法得到刚才实例化的半成品 A,把得到的半成品 A 注入给 B,并同时会把半成品 A 存入 earlySingletonObjects 中,将来如果还有其他的类循环依赖了 A,就可以直接从 earlySingletonObjects 中找到它了,那么此时 singletonFactories 中创建 B 的 ObjectFactory 也可以删除了。
        4. B 的依赖注入处理完之后,B 就创建完毕,就可以把 B 的对象存入到 singletonObjects 中,并删除掉 singletonFactoriesearlySingletonObjects 中的半成品 B。
        5. B 创建完毕后,就可以继续处理 A 的依赖注入:把 B 注入给 A,此时 A 也创建完毕,可以把 A 存入 singletonObjects 中,并删除掉 singletonFactoriesearlySingletonObjects 中的半成品 A。
        6. 最后,A 和 B 对象全部创建完毕,并存储到 singletonObjects 中,将来通过容器获取对象,都是从 singletonObjects 中获取。
  8. Spring 中用到哪些设计模式

    • 工厂模式
      • Spring 使用工厂模式通过 BeanFactory 创建 Bean 对象。
    • 代理模式
      • Spring AOP 功能的实现基于代理模式,通过动态代理(JDK 动态代理或 CGLIB 动态代理)来实现方法的拦截和增强。
    • 模板方法模式
      • Spring 中以 *Template 结尾的对数据库操作的类(如 JdbcTemplateHibernateTemplate 等)使用了模板模式。
    • 单例模式
      • Spring 中的 Bean 默认都是单例的。
    • 适配器模式
      • Spring AOP 的增强或通知(Advice)使用了适配器模式。同时,Spring MVC 也使用了适配器模式来适配不同的 Controller
    • 观察者模式
      • Spring 事件驱动模型是观察者模式的经典应用。
    • 包装器模式
      • 如果我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库,这种模式让我们可以根据客户的需求能够动态切换不同的数据源。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com