【面试题】Spring面试题整理

Spring aop ioc

  • AOP(面向切面)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
    实现AOP的主要设计模式就是动态代理。
    Spring的动态代理有两种:一是JDK的动态代理;另一个是cglib动态代理。
  • IOC(控制反转)就是依赖倒置原则的一种代码设计思路。就是把原先在代码里面需要实现的对象创建、对象之间的依赖,反转给容器来帮忙实现。
    Spring IOC容器通过xml,注解等其它方式配置类及类之间的依赖关系,完成了对象的创建和依赖的管理注入。实现IOC的主要设计模式是工厂模式。
    通过依赖注入DI实现ioc,DI底层使用的是反射机制来实现的。把java中对象的创建,赋值,依赖转交给spring容器管理。
    IOC优点:集中管理,实现类的可配置和易管理。降低了类与类之间的耦合度。

springboot配置文件 bootstrap与application 到底有什么区别?

bootstrap 由父ApplicationContext加载,比application优先加载;
bootstrap里面的属性不能被覆盖
application 配置文件主要用于 Spring Boot 项目的自动化配置。
bootstrap 是应用程序的父上下文,也就是说 bootstrap 加载优先于 applicaton。

什么是循环依赖,怎么解决?

循环依赖(对象之间相互依赖),spring已经帮我们解决了。
使用setter注入不使用构造器注入的方式可以解决循环依赖的问题。

Spring 框架中都用到了哪些设计模式?

工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
单例模式:Bean默认为单例模式。
代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。

Spring框架中的单例bean是线程安全的吗?

不是,Spring框架中的单例bean不是线程安全的。
spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。
实际上大部分时候 spring bean 无状态的(比如 dao 类),所有某种程度上来说 bean 也是安全的,但如果 bean 有状态的话(比如 view model 对象),那就要开发者自己去保证线程安全了,最简单的就是改变 bean 的作用域,把“singleton”变更为“prototype”,这样请求 bean 相当于 new Bean()了,所以就可以保证线程安全了。

aop常用注解

@Aspect:声明当前类为切面类
@Around:指定环绕通知
@Pointcut:指定切入点表达式
@Before:在切入点方法执行前执行前置通知
@After:最终通知,终通知于切入点方法执行完成之后执行,无论切入点方法是否产生异常最终通知都会执行
@AfterReturning:在切入点方法正常执行后执行
@AfterThrowing:在切入点方法执行产生异常后执行

spring常用注解

@Controller:使用@Controller 注解的类会被Spring管理,使得该类能够通过 getBean() 或者 @Autowired 的方式从Spring容器中获取Bean实例。
@ResponseBody:@ResponseBody的作用其实是将java对象转为json格式的数据
@RestController:它结合了 @Controller 和 @ResponseBody 两个注解的功能
@Service:是业务逻辑层注解,这个注解只是标注该类处于业务逻辑层。
@Repository:注解在持久层中,具有将数据库操作抛出的原生异常翻译转化为spring的持久层异常的功能。
@Component: @Component注解的主要作用是标识一个类作为组件,使其可以被Spring框架管理。
@Configuration: @Configuration 的作用包括定义Bean、组织配置、替代XML配置、支持自动装配以及集成外部配置。
@Bean作用在方法上,用于生成bean的方法,并且交给Spring容器管理。
@SpringBootApplication:@SpringBootApplication 标注的类为 Spring Boot 的主配置类,Spring Boot会运行这个类的main方法来启动 Spring Boot 应用。
@ControllerAdvice作用是给Controller控制器添加统一的操作或处理,1.结合@ExceptionHandler用于全局异常的处理。2.搭配@ModelAttribute注解可以做全局数据绑定。3.全局数据预处理

@Autowired和@Resource之间的区别

  1. @Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。如果需要按名称装配,可以结合@Qualifier注解使用。
    @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。
  2. 依赖注入框架不同。@Autowired与Spring强耦合,如果使用非Spring框架,如JFinal,其功能将失效。而@Resource是Java标准,几乎所有支持JSR-250的框架都支持。

@RestController和@Controller有什么区别?

  1. @Controller 注解:使用@Controller 注解,在对应的方法上,视图解析器可以解析return 的jsp.html页面,并且跳转到相应页面若返回json等内容到页面,则需要加@ResponseBody注解
  2. @RestController注解:相当于@Controller+@ResponseBody两个注解的结合,返回json数据不需要在方法前面加@ResponseBody注解了

@component和@Bean的区别

如果想将第三方的类变成组件,你又没有没有源代码,也就没办法使用@Component进行自动配置,这种时候使用@Bean就比较合适了。不过同样的也可以通过xml方式来定义。
另外@Bean注解的方法返回值是对象,可以在方法中为对象设置属性。
Spring的Starter机制,就是通过@Bean注解来定义bean。
避免在某个项目中定义或者通过congfig注解来声明大量重复的bean。
@Bean则常和@Configuration注解搭配使用

@Configuration
public class WebSocketConfig {
    @Bean
    public Student student(){
        return new Student();
    }
}

@Controller怎么直接返回数据

  1. 在方法上加@ResponseBody
  2. 将@Controller换成@RestController

如何给Spring 容器提供配置元数据?Spring有几种配置方式

这里有三种重要的方法给Spring 容器提供配置元数据。

  1. XML配置文件。
  2. 基于注解的配置。
  3. 基于java的配置。

Spring事务的实现方式和实现原理

Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。

Springboot事务不生效的几种情况

  1. mysql存储引擎不支持事务。
    MyISAM 引擎是不支持事务操作的,InnoDB 才是支持事务的引擎
  2. 没有被 Spring 管理
    如果@Service 注解注释掉,这个类就不会被加载成一个 Bean,那这个类就不会被 Spring 管理了,事务自然就失效了
  3. 方法不是 public 的
    @Transactional 只能用于 public 的方法上,否则事务不会失效,如果要用在非 public 方法上,可以开启 AspectJ 代理模式
  4. 异常被抓住了
    try catch
  5. 自身调用问题
    来看两个示例:
@Service
public class OrderServiceImpl implements OrderService {
    public void update(Order order) {
        updateOrder(order);
    }
    @Transactional
    public void updateOrder(Order order) {
        // update order
    }
}

update方法上面没有加 @Transactional 注解,调用有 @Transactional 注解的 updateOrder 方法,updateOrder 方法上的事务管用吗?
再来看下面这个例子:

@Service
public class OrderServiceImpl implements OrderService {
    @Transactional
    public void update(Order order) {
        updateOrder(order);
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateOrder(Order order) {
        // update order
    }
}

这次在 update 方法上加了 @Transactional,updateOrder 加了 REQUIRES_NEW 新开启一个事务,那么新开的事务管用么?
这两个例子的答案是:不管用!
因为它们发生了自身调用,就调该类自己的方法,而没有经过 Spring 的代理类,默认只有在外部调用事务才会生效,这也是老生常谈的经典问题了。
这个的解决方案之一就是在的类中注入自己,用注入的对象再调用另外一个方法,这个不太优雅。
6. 异常类型错误
上面的例子再抛出一个异常:

@Service
public class OrderServiceImpl implements OrderService {
    @Transactional
    public void updateOrder(Order order) {
        try {
            // update order
        } catch {
            throw new Exception("更新错误");
        }
}}

这样事务也是不生效的,因为默认回滚的是:RuntimeException(运行时异常),如果你想触发其他异常的回滚,需要在注解上配置一下,如:
@Transactional(rollbackFor = Exception.class)
这个配置仅限于 Throwable 异常类及其子类。

Spring事务隔离级别有五种

读未提交,读已提交 ,可重复,串行化,DEFAULT(使用数据库默认的事务隔离级别)

Springboot的优点

  1. 创建独立Spring应用
  2. 内嵌Tomcat服务器
  3. 自动starter依赖,简化构建配置
  4. 自动配置Spring以及第三方功能
  5. 提供生产级别的监控、健康检查以及外部优化配置
  6. 无代码生成、无需编写XML

Springcloud的优点

  1. 服务拆分粒度更细,有利于资源重复利用,有利于提高开发效率(按业务划分的微服务单元独立部署,运行在独立的进程中,服务与服务之间没有任何耦合,有很好的扩展性和复用性)
  2. 可以更精准的制定优化服务方案,提高系统的可维护性
  3. 微服务架构采用去中心化思想,服务之间采用Restful等轻量级通讯,比ESB更轻量
  4. 适于互联网时代,产品迭代周期更短
    项目面临高并发,高性能,高可用

springcloud与springcloud alibaba对应的组件

springcloudspringcloud alibaba
注册中心eurekanacos
配置中心springcloudconfignacos
网关zuulgateway
熔断降级HystrixSentinel
服务调用openfeigndubbo

那如果现在微服务A远程调用B,B想获取请求头参数该怎么办?

每一次远程请求的时候都创建了一个新的Request Template对象,在该对象中不包含之前的请求头数据。默认情况下feign远程调用的时候不会传递请求头!
方案一:在feign接口上添加对应的形式参数即可
弊端:每一个接口想要获取参数都需要在接口方法上添加对应的形式参数.影响代码效率
方案二:使用OpenFeign中的拦截器(RequestInterceptor)来拦截请求,添加请求头。

Nacos修改配置文件如何使其立即生效

实现nacos配置更新不重启微服务生效,但需要两种配置实现。

  1. 在引用(如@Value)nacos配置的类上添加@RefreshScope。(此注解能刷新配置文件,但只对添加了此注解的类有效,并非全局有效)
    application.yml
test:
  value: nacos
public class TestConfig {
    @Value("${test.value}")
    private String applicationValue;
}
  1. 使用@ConfigurationProperties注解,在其注解后添加配置文件的前缀,前缀和属性名拼接等于nacos配置中的名字即可生效。
    application.yml
test:
  value: nacos
@ConfigurationProperties(prefix = "test")
public class TestConfig {
    private String value;
}

注意事项:
不是所有的配置都适合放到配置中心,否则维护起来比较繁锁;
建议将一些关键参数、需要运行时调整的参数放到nacos配置中心,一般是自定义配置;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值