Spring面试题整理

Spring的核心容器模块

Spring 的核心容器模块是 Spring Framework 的基础,为其他模块提供了支撑。它主要负责管理 Spring 应用程序中的对象生命周期和依赖关系

Spring 的核心容器模块是 Spring Framework 的基础,为其他模块提供了支撑。它主要负责管理 Spring 应用程序中的对象生命周期和依赖关系。核心容器模块主要包括以下几个重要的部分:

*1. BeanFactory*

BeanFactory 是 Spring 核心容器的基础接口。它负责配置和管理 bean 的生命周期,支持依赖注入。BeanFactory 提供了以下一些特性:

*获取 bean:* 提供根据 bean 名称或类型查找 bean 的方法。

*依赖注入:* 支持通过构造函数、setter 方法和接口注入依赖对象。

*延迟加载:* 只有在请求 bean 时才会创建实例,这样可以减少启动时的内存开销。

*2. ApplicationContext*

ApplicationContext 是 BeanFactory 的一个扩展,提供了更丰富的功能。它是更高级的容器,通常情况下优先使用它。与 BeanFactory 相比,ApplicationContext 增加了以下功能:

*国际化支持:* 提供 MessageSource 接口,可以方便地管理国际化信息。

*事件传播:* 支持事件机制,允许 beans 之间进行事件发布和监听。

*AOP(面向切面编程)😗 可以配置事务管理、日志记录等横切关注点。

*与 Spring MVC 库的整合:* 提供了更便利的支持。

*3. 主要实现类*

*1. XmlApplicationContext*

通过 XML 配置文件加载 bean 定义,适合大多数场景。

*2. AnnotationConfigApplicationContext*

用于基于注解的配置,允许使用 Java 注解(如 @Configuration 和 @Component)来定义 bean。

*3. WebApplicationContext*

是 ApplicationContext 的一个子接口,专门针对 web 应用程序的环境,提供了更多的功能,适用于 Spring MVC。

*4**. Beans 定义*

Spring 核心容器允许通过不同方式定义 bean:

*XML 配置:* 传统的方式,通过 beans.xml 文件定义 bean。

*注解:* 使用 @Component, @Service, @Repository, @Controller 等注解来标识类为 Spring 管理的组件。

*Java Config:* 使用 @Configuration 和 @Bean 注解来定义和配置 bean。

*5. 依赖注入*

Spring 核心容器支持多种依赖注入方式:

*构造器注入:* 在构造函数中传递依赖的 bean 实例。

*Setter 方法注入:* 通过 setter 方法设置依赖的 bean。

*接口注入:* 通过实现特定接口来注入依赖。

*6. 生命周期管理*

Spring 核心容器提供了对 bean 生命周期的管理,包括:

(不只有这两点)

*初始化:* 在 Spring 创建 bean 之后,可以指定初始化方法,进行自定义的初始化操作。

*销毁:* 在容器关闭时,可以指定销毁方法,执行清理操作

IoC容器

IOC容器: 指代那些支持控制反转的框架或组件,它负责管理程序中的对象及其依赖关系。

BeanFactory和ApplicationContext都是

ApplicationContext:

预先初始化: 默认情况下,会在启动时创建所有单例 bean

JDK动态代理和CGLIB(动态代理)字节码生成技术

  1. JDK 动态代理

JDK 动态代理是 Java 语言中提供的动态代理机制,它只支持接口(即被代理对象必须实现至少一个接口)。

特点

只代理接口: 代理对象必须实现一个或多个接口。

性能较高: 由于使用 Java 本身的反射机制,相比 CGLIB,开销较小。

简洁: 代理对象与目标对象通过接口进行交互,增强模块的解耦性。

  1. CGLIB(Code Generation Library)

CGLIB 是一个功能强大的、高性能的 Java 字节码生成库,可以在运行时动态创建类和代理。

特点

支持类的代理: CGLIB 可以对没有接口的类进行代理,支持对普通类的增强。

生成子类: CGLIB 通过创建目标类的子类以实现代理,因此不能对 final 类和 final 方法进行代理(因为不能被继承)。

相对较慢: 所有代理类在运行时生成,开销相对较大,但仍然具有较好的性能。

JDK 动态代理:通过接口实现(轻量、高性能)。

CGLIB:通过生成子类实现(支持没有接口的类,功能更强大,但性能相对较低)

IOC实现机制

*依赖注入*

*IOC 容器:*

Spring 提供了 IoC 容器(如 ApplicationContext 和 BeanFactory),用于管理对象的生命周期和依赖关系。

BeanFactory:是 Spring IOC 的最基本的容器,负责创建和管理 bean 的生命周期,Lazy Loading。

ApplicationContext:在功能上更为强大,它扩展了 BeanFactory,提供了更多的功能,例如国际化支持、事件传播等。

*Bean 的定义和配置:*

Spring 中的对象称为 “bean”,它们的定义通常通过 XML 配置、Java 注解或 Java 配置类。

Bean 定义包括 Bean 的类、作用域(如 singleton、prototype)、生命周期回调等。

*反射机制:*

Spring IOC 实现的核心之一是利用 Java 的反射机制。在实例化对象时,Spring 可以动态地创建对象并注入依赖。

反射允许 Spring 在运行时获取类的信息,从而创建对象、调用方法和设置字段。

*自动装配:*

Spring 支持自动装配,以便根据类型或名称自动找到并注入依赖。可以通过注解(如 @Autowired)或 XML 配置实现。

BeanFactory和ApplicationContext的区别

*BeanFactory:*

是 Spring IoC 容器的最基本形式,主要用于创建和管理 Bean。

在内存使用上的效率较高,提供了延迟加载(Lazy Initialization)功能,即只有在需要使用 Bean 时才会创建它。

提供的功能相对简单,缺少许多高级特性。

*ApplicationContext:*

是 BeanFactory 的扩展,提供了更多的功能和特性,例如国际化支持、事件传播、对 AOP 的支持等。

支持更多的功能,例如注解支持(如 @Autowired)、消息资源处理、应用事件等。

默认情况下,ApplicationContext 会在创建容器时实例化所有 singleton Bean,而不是等到第一次访问时再创建(除非使用 @Lazy 注解)。

*Spring框架中的Bean线程非安全,因为Spring框架没有对单例Bean进行多线程封装处理*

哪些是重要的bean****生命周期方法? 你能重载它们吗?

初始化和销毁

bean 标签有两个重要的属性(init-method和destroy-method)。用它们你可以自己定制初始化和注销方法。它们也有相应的注解(@PostConstruct和@PreDestroy)。

什么是Spring的内部bean?什么是Spring inner beans?

在Spring框架中,当一个bean仅被用作另一个bean的属性时,它能被声明为一个内部bean。内部bean可以用setter注入“属性”和构造方法注入“构造参数”的方式来实现,内部bean通常是匿名的

<bean id="outerBean" class="com.example.OuterBean">

 <property name="innerBean">

   <bean class="com.example.InnerBean">

     <property name="someProperty" value="someValue"/>

   </bean>

 </property>

</bean>

Bean装配

Bean 的装配(Bean Wiring)是指将不同的 Bean 组合在一起,以便它们能够相互协作和使用。通过装配,可以将一个 Bean 的实例注入到另一个 Bean 中

自动装配

自动装配(Autowiring)是 Spring 框架中的一个特性,它允许 Spring 容器在不显式地定义 Bean 依赖关系的情况下,自动处理和注入 Bean 的依赖。

自动装配方式

*按类型自动装配(byType):*

Spring 根据 Bean 的类型来查找依赖。

如果容器中有多个同类型的 Bean,会抛出异常,除非使用 @Qualifier 指定具体的 Bean。

<bean id="myBean" class="com.example.MyBean" autowire="byType"/>

*按名称自动装配(byName):*

Spring 根据 Bean 的名称查找依赖。

如果找到了与属性名称相同的 Bean,则自动装配。

<bean id="myBean" class="com.example.MyBean" autowire="byName"/>

*构造函数自动装配(constructor):*

Spring 使用 Bean 的构造函数参数的类型来查找依赖。

根据构造函数的参数类型进行匹配和注入。

<bean id="myBean" class="com.example.MyBean" autowire="constructor"/>

*使用注解:*

在 Java 类中使用 @Autowired 注解来标记要自动装配的字段、构造函数或方法。

结合 @Qualifier 指定具体的 Bean。

public class MyBean {

  @Autowired

  private DependencyBean dependency;

}

@Autowired注解自动装配的过程

在使用@Autowired时,首先在容器中查询对应类型的bean:

如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据;

如果查询的结果不止一个,那么@Autowired会根据名称来查找;

@Component、@Controller、@Repository、@Service有何区别

*1. @Component*

用途:这是一个泛用的注解,用于将一个类标识为 Spring 的组件,意味着这个类可以被 Spring 容器识别和管理。

应用场景:当一个类不适合特别的角色(如控制器、服务或数据访问对象)时,可以使用 @Component。

import org.springframework.stereotype.Component;

@Component

public class MyGenericComponent {

 // ...

}

*2. @Controller*

用途:专门用于标识处理请求的控制器类,通常与 MVC(模型-视图-控制器)架构一起使用。

应用场景:当类负责接收用户请求,并且返回视图或数据时,应该使用 @Controller。Spring 会将该类中的方法映射到 HTTP 请求。

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

@Controller

public class MyController {

 @RequestMapping("/home")

 public String home() {

   return "home"; // 返回视图名

 }

}

*3. @Service*

用途:用于标识服务层组件,通常用于业务逻辑和服务处理。

应用场景:当类提供与业务逻辑相关的功能,并且一般涉及多个 DAO(数据访问对象)时,使用 @Service。

import org.springframework.stereotype.Service;

@Service

public class MyService {

 public void performService() {

   // 业务逻辑

 }

}

*4. @Repository*

用途:用于标识数据访问层组件,负责与数据库或数据源进行交互。

应用场景:当类中包含了对数据层的访问逻辑时,使用 @Repository。Spring 会自动处理数据访问异常的转换(如将技术异常转换为 Spring 的统一异常)。

import org.springframework.stereotype.Repository;

@Repository

public class MyRepository {

 public void save(Object obj) {

   // 数据库保存逻辑

 }

}

@Autowired和@Resource的区别

*@Autowired:*

这是 Spring 框架提供的注解,属于 Spring 的构件。

默认情况下,使用按类型注入。如果容器中有多个同类型的 Bean,将会抛出异常。可以通过 @Qualifier 注解来指定具体的 Bean。

例如:

@Autowired

private MyService myService; //按类型注入

*@Resource:*

这是 Java EE 的标准注解,属于 JDK,它主要用于资源的注入,可以按名称或按类型进行依赖注入。

默认情况下,先按名称查找 Bean,如果找不到再按类型查找。

如果有同名的 Bean,且希望按名称注入,可以直接使用同名属性来注入。

例如:

@Resource

private MyService myService; //按名称注入

@Qualifier作用

用于在依赖注入时指明具体要注入哪一个 Bean。当有多个同类型的 Bean 存在时,Spring 需要明确知道哪个 Bean 应该被注入,而 @Qualifier 提供了这种能力。

@RequestMapper作用

是 Spring MVC 中用于处理 HTTP 请求的一个注解,它可以应用于类和方法上。@RequestMapping 的主要作用是将 HTTP 请求映射到对应的处理方法,以便于处理器能够响应特定的 URL。

Spring支持的事务管理类型

*编程式事务管理*

概述:编程式事务管理是直接在代码中通过编程的方式来控制事务的行为。开发者需要手动开启、提交或回滚事务。

使用场景:适合需要高度灵活性或自定义事务边界的场景。

*声明式事务管理*

概述:声明式事务管理允许开发者通过配置的方式来声明事务的边界。通常使用 AOP(面向切面编程)来实现,开发者不需要修改业务代码。

使用场景:适合大多数应用场景,特别是在进行简单的 CRUD 操作时。

示例:

使用注解:

import org.springframework.transaction.annotation.Transactional;

@Service

public class MyService {

  @Transactional

  public void performTransaction() {

    // 执行数据库操作

  }

}

使用 XML 配置:

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="*" propagation="REQUIRED" />
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="pointcut" expression="execution(* com.example.service..*.*(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
</aop:config>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值