Spring面试题

目录

1、@RestController vs @Controller?

2、Spring IOC & AOP?

3、Spring 中的 bean 的作用域有哪些?

4、@Component 和 @Bean 的区别是什么?

5、将一个类声明为Spring的 bean 的注解有哪些?

6、对于 Spring MVC 的了解?

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

8、@Transactional(rollbackFor = Exception.class)注解?

9、常见的 HTTP 请求类型?

10、@PathVariable 和 @RequestParam?

11、常用的字段验证的注解?

12、@Autowired 和 @Resource关键字的区别?

13、SpringMVC常用的注解有哪些?

14、Spring支持的事务管理类型?


1、@RestController vs @Controller?

@Controller 返回一个页面。单独使用 @Controller 不加 @ResponseBody 的话一般使用在要返回一个视图的情况,这种情况属于比较传统的Spring MVC 的应用,对应于前后端不分离的情况

@RestController 返回JSON 或 XML 形式数据。但 @RestController 只返回对象,对象数据直接以 JSON 或 XML 形式写入 HTTP 响应(Response)中, 这种情况属于 RESTful Web服务,这也是目前日常开发所接触的最常用的情况 (前后端分离)

@ResponseBody 注解的作用是将 Controller 的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到HTTP 响应(Response)对象的 body 中,通常用来返回 JSON 或者 XML 数据,返回 JSON 数据的情况比较多,一个请求方法只可以有一个 @RequestBody,但是可以有多个 @RequestParam 和 @PathVariable。

@Controller + @ResponseBody 返回JSON 或 XML 形式数据,也就是说 @Controller + @ResponseBody = @RestController

2、Spring IOC & AOP?

IoC (Inverse of Control:控制反转)是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。IoC 在其他语言中也有应用,并非 Spring 特有。IoC 容器是 Spring 用来实现 IoC 的载体,IoC 容器实际上就是个Map (key,value),Map 中存放的是各种对象。将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。 IoC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的

AOP (Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任 (例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。Spring AOP就是基于动态代理的,如果要代理的对象,实现了某个接口,那么Spring AOP会使用JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP会使用Cglib ,这时候Spring AOP会使用 Cglib 生成一个被代理对象的子类来作为代理

3、Spring 中的 bean 的作用域有哪些?

  • singleton:唯一 bean 实例,Spring 中的 bean 默认都是单例的
  • prototype:每次请求都会创建一个新的 bean 实例
  • request:每一次HTTP请求都会产生一个新的 bean,该bean仅在当前HTTP request内有效
  • session:每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效
  • global-session:全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了

4、@Component 和 @Bean 的区别是什么?

作用对象不同:@Component 注解作用于类,而 @Bean 注解作用于方法

@Component 通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中 (可以使用 @ComponentScan 注解定义要扫描的路径从中找出标识了需要装配的类自动装配到 Spring 的 bean 容器中),@Bean 注解通常是在标有该注解的方法中定义产生这个 bean,@Bean告诉了Spring这是某个类的示例,当我需要用它的时候还给我

@Bean 注解比 @Component 注解的自定义性更强,而且很多地方只能通过 @Bean 注解来注册 bean。比如引用第三方库中的类需要装配到 Spring 容器时,则只能通过 @Bean 来实现

@Bean 注解使用示例:

@Configuration
public class AppConfig {
    @Bean
    public TransferService transferService() {
        return new TransferServiceImpl();
    }
}

上面的代码相当于下面的 xml 配置:

<beans>
    <bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>

下面这个例子是通过 @Component 无法实现的:

@Bean
public OneService getService(status) {
    case (status) {
        when 1:
            return new serviceImpl1();
        when 2:
            return new serviceImpl2();
        when 3:
            return new serviceImpl3();
    }
}

5、将一个类声明为Spring的 bean 的注解有哪些?

一般使用 @Autowired 注解自动装配 bean,要想把类标识成可用于 @Autowired 注解自动装配的 bean 的类,采用以下注解可实现:

  • @Component:通用的注解,可标注任意类为 Spring组件,如果一个Bean不知道属于哪个层,可以使用 @Component 注解
  • @Repository:对应持久层即 Dao 层,主要用于数据库相关操作
  • @Service:对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao层
  • @Controller:对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面

6、对于 Spring MVC 的了解?

MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring MVC 可以帮助我们进行更简洁的Web层的开发,并且它天生与 Spring 框架集成。Spring MVC 下一般把后端项目分为 Service层 (处理业务)、Dao层 (数据库操作)、Entity层 (实体类)、Controller层 (控制层,返回数据给前台页面)

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

  • 工厂设计模式:Spring使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean对象
  • 代理设计模式:Spring AOP 功能的实现
  • 单例设计模式:Spring 中的 Bean 默认都是单例的
  • 模板方法模式:Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类
  • 观察者模式:Spring 事件驱动模型就是观察者模式很经典的一个应用
  • 适配器模式:Spring AOP 的增强或通知 (Advice)使用到了适配器模式、Spring MVC 中也是用到了适配器模式适配 Controller

8、@Transactional(rollbackFor = Exception.class)注解?

当 @Transactional 注解作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时也可以在方法级别使用该标注来覆盖类级别的定义。如果类或者方法加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库里面的数据也会回滚

在 @Transactional 注解中如果不配置 rollbackFor 属性,那么事物只会在遇到 RuntimeException 的时候才会回滚,加上 rollbackFor=Exception.class,可以让事物在遇到非运行时异常时也回滚

9、常见的 HTTP 请求类型?

GET:请求从服务器获取特定资源。举例:GET /users (获取所有学生)

  • @GetMapping("users") 等价于 @RequestMapping(value="/users", method=RequestMethod.GET)

POST:在服务器上创建一个新的资源。举例:POST /users (创建学生)

  • @PostMapping("users") 等价于 @RequestMapping(value="/users", method=RequestMethod.POST)

PUT:更新服务器上的资源 (客户端提供更新后的整个资源)。举例:PUT /users/12 (更新编号为 12 的学生)

  • @PutMapping("/users/{userId}") 等价于 @RequestMapping(value="/users/{userId}", method=RequestMethod.PUT)

DELETE:从服务器删除特定的资源。举例:DELETE /users/12 (删除编号为 12 的学生)

  • @DeleteMapping("/users/{userId}") 等价于 @RequestMapping(value="/users/{userId}", method=RequestMethod.DELETE)

PATCH:更新服务器上的资源 (客户端提供更改的属性,可以看做作是部分更新),使用的比较少

10、@PathVariable 和 @RequestParam?

@PathVariable 用于获取路径参数, @RequestParam 用于获取查询参数,例如:

@GetMapping("/klasses/{klassId}/teachers")
public List<Teacher> getKlassRelatedTeachers(
    @PathVariable("klassId") Long klassId,
    @RequestParam(value = "type", required = false) String type) {
    ...
}

如果请求的 url 是:/klasses/{123456}/teachers?type=web;那么服务获取到的数据就是:klassId=123456,type=web

11、常用的字段验证的注解?

  • @NotEmpty 被注释的字符串的不能为 null 也不能为空
  • @NotBlank 被注释的字符串非 null,并且必须包含一个非空白字符
  • @Null 被注释的元素必须为 null
  • @NotNull 被注释的元素必须不为 null
  • @AssertTrue 被注释的元素必须为 true
  • @AssertFalse 被注释的元素必须为 false
  • @Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
  • @Email 被注释的元素必须是 Email 格式
  • @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @Size(max=, min=) 被注释的元素的大小必须在指定的范围内
  • @Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
  • @Past 被注释的元素必须是一个过去的日期
  • @Future 被注释的元素必须是一个将来的日期

12、@Autowired 和 @Resource关键字的区别?

@Resource和@Autowired都是做 bean的注入时使用,两者都可以写在字段和setter方法上,如果都写在字段上,那么就不需要再写setter方法

@Autowired注解是按照类型 (byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的 required属性为false。如果使用按照名称 (byName)来装配,可以结合@Qualifier注解一起使用

public class TestServiceImpl {
    @Autowired
    @Qualifier("userDao")
    private UserDao userDao;
}

@Resource默认按照 ByName自动注入,由J2EE提供,需要导入包 javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将 @Resource注解的 name属性解析为 bean的名字,而 type属性则解析为 bean的类型。如果使用 name属性,则使用 byName的自动注入策 略,而使用 type属性时则使用 byType自动注入策略。如果既不指定 name也不指定 type属性,这时将通过反射机制使用 byName自动注入策略

public class TestServiceImpl {
    // 下面两种 @Resource只要使用一种即可

    // 用于字段上
    @Resource(name="userDao")
    private UserDao userDao; 

    // 用于属性的setter方法上
    @Resource(name="userDao")
    public void setUserDao(UserDao userDao) { 
        this.userDao = userDao;
    }
}

最好是将@Resource放在setter方法上,因为这样更符合面向对象的思想,通过set、get去操作属性,而不是直接去操作属性

13、SpringMVC常用的注解有哪些?

  • @RequestMapping:用于处理请求 url映射的注解,可用于类或方法上。用于类上表示类中的所有响应请求的方法都是以该地址作为父路径
  • @RequestBody:注解实现接收 http请求的 json数据,将 json转换为 java对象
  • @ResponseBody:注解实现将 Controller方法返回对象转化为 json对象响应给客户

14、Spring支持的事务管理类型?

  • 编程式事务管理:通过编程的方式管理事务,给你带来极大的灵活性,但是难维护
  • 声明式事务管理:可以将业务代码和事务管理分离,你只需用注解和 XML 配置来管理事务


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

South.return

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值