每日速记10道java面试题22-Spring篇

其他资料:

每日速记10道java面试题01-CSDN博客

每日速记10道java面试题02-CSDN博客

每日速记10道java面试题03-CSDN博客

每日速记10道java面试题04-CSDN博客

每日速记10道java面试题05-CSDN博客

每日速记10道java面试题06-CSDN博客

每日速记10道java面试题07-CSDN博客

每日速记10道java面试题08-CSDN博客

每日速记10道java面试题09-CSDN博客

每日速记10道java面试题10-CSDN博客

每日速记10道java面试题11-CSDN博客

每日速记10道java面试题12-CSDN博客

每日速记10道java面试题13-CSDN博客

每日速记10道java面试题14-CSDN博客

每日速记10道java面试题15-CSDN博客

每日速记10道java面试题16-CSDN博客

每日速记10道java面试题17-CSDN博客

每日速记10道java面试题18-CSDN博客

每日速记10道java面试题19-CSDN博客

每日速记10道java面试题20-CSDN博客

每日速记10道java面试题21-CSDN博客

目录

1.Spring有什么优点?

2.Spring loc 容器初始化过程?

3.Spring Bean 注册到容器有哪些方式? 

4.Spring 自动装配的方式有哪些?

5.@Bean和@Component有什么区别?

6.@Component、@Controller、@Repository和@Service的区别? 

7.Spring的事务在什么时候会失效?

 8.说一说Spring的启动过程?

9.Spring 的单例 Bean 是否有并发安全问题?

10.你知道xxx注解的作用吗?

(1)@Primary

(2)@Value

(3)@Profile

 (4)@PostConstruct 和 @PreDestroy

(5)@RequestBody和@ResponseBody

(6)@Pathvariable

(7)@ExceptionHandler

(8)@Responsestatus

(9) @RequestHeader和@CookieValue

(10)@Schedule

 (11)@Cacheable和@cacheEvict

(12)@Conditional

(13)@lazy

(14)@PropertySourse

(15) @EventListener


1.Spring有什么优点?

主要有以下几点(基本上答出 ioc、aop、生态和社区就差不多了):
1)轻量级和非侵入性,不需要引入大量的依赖和配置。
2)面向切面编程(AOP),Spring 提供了强大的面向切面编程的支持,允许用户定义横切关注点,并将其与核心业务逻辑分离,提高了灵活性。
3)依赖注入(DI)和控制反转(IOC)容器,Spring 的核心是 IOC 容器,它实现了依赖注入模式,通过配置文件或注解来管理对象之间的依赖关系,降低了耦合度,提高了代码的可维护性和可测试性。
4)拥有大量的生态,几乎集成市面所有 Java 技术栈的一切框架和类库。
5)Spring 拥有非常活跃的社区,官方文档丰富,网上大把教学资源,遇到问题比较容易找到对应的解决方案。

2.Spring loc 容器初始化过程?

启动、Bean 定义注册、实例化和依赖注入、初始化
1)启动阶段:

  • 配置加载:加载配置文件或配置类,IOC容器首先需要加载应用程序的配置信息,这些配置信息可以是 XML 配置文件、Java 配置类或注解配置等方式。
  • 创建容器:Spring 创建 IOC容器(BeanFactory、ApplicationContext),准备加载和管理 Bean。

2)Bean 定义注册阶段:

  • 解析和注册:BeanDefinitionReader 读取解析配置中的 Bean 定义,并将其注册到容器中,形成 BeanDefinition 对象。

3)实例化和依赖注入:

  • 实例化:根据 BeanDefinition 创建 Bean 的实例。
  • 依赖注入:根据 BeanDefinition 中的依赖关系,可以通过构造函数注入、Setter 注入或字段注入,将依赖注入到 Bean 中。

4)初始化:

  • BeanPostProcessor 处理:这些处理器会在 Bean 初始化生命周期中加入定义的处理逻辑,postProcessBeforelnitialization 和postProcessAfterlnitialization 分别在 Bean 初始化前后被调用。
  • Aware 接口调用:如果 Bean 实现了 Aware 接口(如 BeanNameAware、BeanFactoryAware),Spring 会回调这些接口,传递容器相关信息。
  • 初始化方法调用:调用 Bean 的初始化方法(如通过 @Postconstruct 注解标注的方法,或实现 InitializingBean 接口的 bean 会被调用afterPropertiesSet 方法)

3.Spring Bean 注册到容器有哪些方式? 

Spring Bean 注册到容器的方式主要包括以下几种:
1)基于 XML的配置
使用 XML 文件配置 Bean,并定义 Bean 的依赖关系,
2)基于 @component 注解及其衍生注解
使用注解如 @component等进行配置。@Service@Controller@Repository注解
3)基于 @Configuration 和 @Bean
使用 @Configuration注解声明配置类,并使用@Bean注解定义 Bean。
4)基于 @Import 注解
@Import可以将普通类导入到 Spring 容器中,这些类会自动被注册为 Bean。

4.Spring 自动装配的方式有哪些?

自动装配指的是 Spring 可以根据一些特定的规则比如注解或者配置,自动在各个组件之间建立关联,完成依赖注入自动装配主要有以下四类:
1)no(默认):不自动装配,需要显式地定义依赖。
2)byName:通过 Bean 名称进行自动装配。
3)byType:通过 Bean 类型进行自动装配。
4)constructor:通过构造函数进行自动装配

5.@Bean和@Component有什么区别?

特性@Bean@Component
使用位置方法级别(在@Configuration类中)类级别
扫描机制不支持自动扫描,需手动注册支持自动扫描,通过@ComponentScan自动发现
主要用途用于配置第三方库或复杂对象用于自动发现并注册自定义类
常见场景手动配置复杂对象、第三方库类自定义服务、DAO层、控制器等类的自动注册
灵活性更灵活,适合复杂初始化自动化更强,适合类的简单注册

6.@Component、@Controller、@Repository和@Service的区别?
 

它们本质上没区别,并且其它三个都是 @component 的行生注解,之所以做了这些划分主要是为了更好地组织和管理应用的各个层次,提高代码的可读性和可维护性。
1)@Component:这是一个通用的注解,用于将任意类注册为 Spring 容器中的 Bean。它没有特定的语义,适用于任何需要 Spring 管理的类。
2)@Controller:这是一个专门用于 Spring MVC 中的控制器(Controller)层的注解。用于处理 HTTP 请求,并将结果返回给客户端。
3)@Service:用于标识业务逻辑层的类。它具有明确的语义,表明该类承担业务操作,主要用于编写服务类
4)@Repository:用于数据访问层(DAO)的类,与数据库交互。
区别总结:
@Component:通用注解,用于将任何类标记为 Spring Bean.
@Controller:特定于 Spring MVC,处理 Web 层请求。
@Service:特定于业务逻辑层,用于处理服务逻辑。
@Repository:特定于持久层,通常用于数据访问对象(DAO)。

7.Spring的事务在什么时候会失效?

1.方法是static修饰的静态方法。静态方法不属于任何实例,而是类级别的方法.
2.方法或者类被 final修饰。动态代理本质是继承你这个类,你都final了人家咋继承?
3.方法不是被public修饰的。你一个private的方法人家咋走代理。
4.这个类没被spring管理或者是自己new出来的。
5.类内方法自己调用。自己调用自己类的方法是不会走代理的。
6.rollbackFor使用默认的,默认的只会回滚RuntimeException和Error的异常,那些什么!0异常都不会回滚。
7.你的异常被自己try catch捕获了。你不抛出来人家咋知道报异常了
8.事务传播机制错了,比如你被调用的方法事务机制是REQUIRES NEW,会新起一个事务,两个事务没啥关联,第一个报错了第二个不回滚。
9.你用的数据库有问题,当你表用不支持事务的引擎时,比如说MyISAM,这时候当然事务不生效。 

 8.说一说Spring的启动过程?

1)加载配置文件,初始化容器:
Spring 启动时首先会读取配置文件(如 XML 配置文件、JavaConfig 类等),包括配置数据库连接、事务管理、AOP 配置等
2)实例化容器:
Spring 根据配置文件中的信息创建容器 ApplicationContext,在容器启动阶段实例化BeanFactory,并加载容器中的 BeanDefinitions.
3)解析 BeanDefinitions:
Spring 容器会解析配置文件中的 BeanDefinitions,即声明的 Bean 元数据,包括 Bean 的作用域、依赖关系等信息.
4)实例化 Bean:
Spring 根据 BeanDefinitions 实例化 Bean 对象,将其放入容器管理。
5)注入依赖:
Spring 进行依赖注入,将 Bean 之间的依赖关系进行注入,包括构造函数注入、属性注入等。
6)处理 Bean 生命周期初始化方法:
Spring 调用 Bean 初始化方法(如果有定义的话),对 Bean 进行初始化。
如果 Bean 实现了 InitializingBean 接囗,Spring 会调用其 afterPropertiesset 方法。
7)处理 BeanPostProcessors:
容器定义了很多 BeanPostProcessor,处理其中的自定义逻辑,例如 postProcessBeforelnitialization 会在 Bean 初始化前调用postProcessAfterlnitialization 则在之后调用。
Spring AOP 代理也在这个阶段生成。
8)发布事件:
Spring 可能会在启动过程中发布一些事件,比如容器启动事件
9)完成启动:
当所有 Bean 初始化完毕、依赖注入完成、AOP 配置生效等都准备就绪时,Spring 容器启动完成.。 

9.Spring 的单例 Bean 是否有并发安全问题?

存在线程安全问题,单例模式下Bean在应用程序中只有一个,如果多线程情况下,访问的都是一个Bean,如果Bean中存在实例变量和非线程安全资源,会引发线程安全问题。
解决方案:
1.避免在单例Bean中使用可变状态,确保单例Bean是无状态的,或者使用线程安全的数据结构
2.使用@Scope(“prototype”),保证每个线程访问的时候都是创建了一个新的Bean
3.加锁,如使用Synchornized关键字
4.使用ThreadLocal保存变量

10.你知道xxx注解的作用吗?

(1)@Primary

当容器中存在多个相同类型的Bean时,优先注入标记了Primary注解的Bean

(2)@Value

@Value用于将外部化的配置值注入到到Bean中,例如:

app.name = MyApp
app.version = 1.0.0
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class AppConfig {

    @Value("${app.name}")
    private String appName;

    @Value("${app.version}")
    private String appVersion;

    public String getAppName() {
        return appName;
    }

    public String getAppVersion() {
        return appVersion;
    }
}

(3)@Profile

在 Spring 框架中,@Profile 注解用于定义一组 Bean 的配置文件所属的环境,比如 dev 通常表示开发环境,prod 表示生产环境.例如:

@Configuration
@Profile("dev") // 这个配置类只在 "dev" profile激活时加载
public class DevConfig {
    @Bean
    public DataSource dataSource() {
        // 返回开发环境的DataSource
        return new EmbeddedDatabaseDataSource();
    }
}

@Configuration
@Profile("prod") // 这个配置类只在 "prod" profile激活时加载
public class ProdConfig {
    @Bean
    public DataSource dataSource() {
        // 返回生产环境的DataSource
        return new SomeProductionDataSource();
    }
}

 (4)@PostConstruct 和 @PreDestroy

@Postconstruct 和 @PreDestroy 是Java 标准(JSR-250)中的注解,Spring 通过它们来管理 Bean 的生命周期。

  • @Postconstruct:用于标记方法,当依赖注入完成后,在 Bean 初始化完成后调用,这个方法会自动被调用。常用于进行初始化逻辑
  • @Prepestroy :用于标记方法,在 Bean 即将被销毁时调用。常用于进行资源的释放、清理工作。

(5)@RequestBody和@ResponseBody

 @RequestBody:用于将从请求体中接受的json数据转换为java对象
@ResponseBody:用于将java对象转换为json数据并写入响应体中

(6)@Pathvariable

@Pathvariable用于从请求路径中捕获变量,例:/user/{id}

(7)@ExceptionHandler

@ExceptionHandler 是 Spring MVC 中用于处理控制器方法中抛出的异常的注解。它允许开发者定义一个专门用于处理特定异常类型的方法,避免将异常信息直接暴露给客户端,进而返回更加友好或定制的响应。

(8)@Responsestatus

@Responsestatus 注解用于定义一个方法或者异常类所对应的 HTTP 状态码和原因短语。当你使用这个注解时,Spring 会将该注解指定的状态码和原因设置到响应的 HTTP 状态行中。

例如:

@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "网页未找到")
public class UserNotFoundException extends RuntimeException {
    // 异常类实现
}

(9) @RequestHeader和@CookieValue

@RequestHeader注解用于获取请求头中的参数,并将其注入到controller方法参数中

@GetMapping("/header-info")
public String getHeaderInfo(@RequestHeader("User-Agent") String userAgent) {
    // 使用 userAgent 进行业务处理
    return "headerInfoView";
}

@CookieValue则是用于获取cookie的值
 

@GetMapping("/cookie-info")
public String getCookieInfo(@CookieValue("sessionId") String sessionId) {
    // 使用 sessionId 进行业务处理
    return "cookieInfoView";
}

(10)@Schedule

这个注解用于在 Spring 应用中定时执行方法。它可以将某个方法标记为一个定时任务,并根据设定的时间间隔、固定速率、或 Cron 表达式来定时触发该方法的执行。 

 (11)@Cacheable和@cacheEvict

1.@Cacheable:用于将方法的返回结果缓存起来。下次再调用相同参数的方法时,直接从缓存中获取结果,而不是重新执行该方法。
2.@cacheEvict :用于从缓存中移除一项或多项数据,通常在更新或删除操作时使用,确保缓存中的数据保持一致性。

(12)@Conditional

作用于有条件地装配 Bean。可以根据特定的条件来决定某个 Bean 是否应该被加载到 Spring 容器中。例如可以根据环境 (如开发、测试.生产)或特定上下文条件动态装配 Bean,实现动态加载。

(13)@lazy

 @Lazy 的两种用法:
1.和注解 @Component 或 @Bean 一起使用,可以延迟 Bean 的创建时机,当用到这个 Bean 的时候(依赖注入、从 Beanfactory 直接获取),才进行创建。
2.和注解 @Autowire 一起使用,Spring 将注入一个代理类。

(14)@PropertySourse

@propertySourse主要用于从外部读取配置,加载到spring环境。

@Configuration
@PropertySource("classpath:${config.location:application.properties}")
public class AppConfig {
}

(15) @EventListener

@EventListener主要用于监听和处理事件,其标注在方法上,可以使方法监听特定类型的事件,并在发布事件时执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值