1.Spring是什么?特性?有哪些模块?
Spring是一个轻量级、非入侵式的控制反转Ioc和面向切面AOP的框架。
特性:
1.Ioc和DI
Spring的核心就是一个大的工厂容器,可以维护所有对象的创建和依赖关系,Spring工厂用于生成Bean,并且管理Bean的生命周期,实现高内聚低耦合的设计理念。
2.AOP编程
Spring提供面向切面编程,可以方便实现对程序进行权限拦截、运行监控等切面功能。
3.声明式事务的支持
支持通过配置来完成对事务的管理,而不需要通过硬编码的方式,以前重复的一些事务提交、回滚的JDBC代码,都可以不用自己写了。
主要的七大模块:
1.Spring Core:Spring的核心,它是框架最基础的部分,提供Ioc和依赖注入DI特性。
2.Spring Context:Spring上下文容器,它是BeanFactory功能加强的一个子接口。
3.Spring Web:提供Web应用开发的支持。
4.Spring MVC:针对Web应用中MVC思想的实现。
5.Spring DAO:提供JDBC抽象层,简化了JDBC编码,同时,编码更具有健壮性。
6.Spring ORM:支持用于流行的ORM框架的整合,比如:Spring + Hibernate、Spring + iBatis、Spring + JDO的整合等。
7.Spring AOP:即面向切面编程,提供了与AOP兼容的编程实现。
2.Spring常用的注解
Spring 提供了大量的注解来简化 Java 应用的开发和配置,主要用于 Web 开发、往容器注入 Bean、AOP、事务控制等。
Web开发方面注解:
- @Controller:用于标注控制层的组件
- @RestController:是@Controller和@ResponseBody的结合体,返回JSON数据时使用。
- @RequestMapping:用于映射请求URL到具体的方法上,还可以细分为:
- @GetMapping:只能用于请求处理GET请求
- @PostMapping:只能用于处理POST请求
- @DeleteMapping:只能用于处理DELETE请求
- @ResponseBody:直接将返回的数据放入HTTP响应正文中,一般用于返回JSON数据。
- @RequestBody:表示一个方法参数应该绑定到Web请求体。
- @PathVariable:用于接收路径参数,比如@RequestMapping("/hello/{name}") ,这里的 name 就是路径参数。
- @RequestParam:用于接收请求参数。比如@RequestParam(name = "key") String key,这里的 key 就是请求参数。
容器类注解:
- @Compont:标识一个类为Spring组件,使其能够被Spring容器自动扫描和管理。
- @Service:标识一个业务逻辑组件(服务层)。比如@Service("userService"),这里的userService就是Bean的名称。
- @Repository:标识一个数据访问组件(持久层)。
- @Configuration:用于定义配置类,可替换 XML 配置文件。
- @Value:用于将 Spring Boot 中 application.properties 配置的属性值赋值给变量。
AOP方面注解:
-
@Aspect 用于声明一个切面,可以配合其他注解一起使用,比如:
-
@After:在方法执行之后执行。
-
@Before:在方法执行之前执行。
-
@Around:方法前后均执行。
-
@PointCut:定义切点,指定需要拦截的方法。
3.@Autowired的实现原理
实现@Autowired的关键是:AutowiredAnnotationBeanPostProcessor
在Bean的初始化阶段,会通过Bean后置处理器来进行一些前置和后置的处理。
实现@Autowired的功能,也是通过后置处理器来完成的。这个后置处理器就是AutowiredAnnotationBeanPostProcessor。
- Spring在创建bean的过程中,最终会调用到doCreateBean()方法,在doCreateBean()方法中会调用populateBean()方法,来为bean进行属性填充,完成自动装配等工作。
- 在populateBean()方法中一共调用了两次后置处理器,第一次是为了判断是否需要属性填充,如果不需要进行属性填充,那么就会直接进行return,如果需要进行属性填充,那么方法就会继续向下执行,后面会继续第二次后置处理器的调用,这个时候,就会调用到AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues()方法,在该方法中就会进行@Autowired注解的解析,然后实现自动装配。
4.JDK动态代理和CGLIB动态代理
Spring的AOP是通过动态代理来实现的,动态代理主要有两种方式:JDK动态代理和CGLIB动态代理。
- JDK动态代理是基于接口的代理,只能代理实现了接口的类。使用JDK动态代理时,Spring AOP会创建一个代理对象,该代理对象实现了目标对象所实现的接口,并在方法调用前后插入横切逻辑。 优点:只需要依赖JDK自带的java.lang.reflect.Proxy类,不需要额外的库;缺点:只能代理接口,不能代理类本身。
- CGLIB动态代理是基于继承的代理,可以代理没有实现接口的类。使用CGLIB动态代理时,Spring AOP会生成目标类的子类,并在方法调用前后插入横切逻辑。优点:可以代理没有实现接口的类,灵活性更高;缺点:需要依赖CGLIB库,创建代理对象的开销相对较大。
5.选择CGLIB还是JDK动态代理?
- 如果目标对象没有实现任何接口,则只能使用 CGLIB 代理。如果目标对象实现了接口,通常首选 JDK 动态代理。
- 虽然 CGLIB 在代理类的生成过程中可能消耗更多资源,但在运行时具有较高的性能。对于性能敏感且代理对象创建频率不高的场景,可以考虑使用 CGLIB。
- JDK 动态代理是 Java 原生支持的,不需要额外引入库。而 CGLIB 需要将 CGLIB 库作为依赖加入项目中。
6.SpringMVC的工作流程
- 发起请求:客户端通过 HTTP 协议向服务器发起请求。
- 前端控制器:这个请求会先到前端控制器DispatcherServlet,它是整个流程的入口点,
- 处理器映射:DispatcherServlet 调用 HandlerMapping 来确定哪个 Controller 应该处理这个请求。通常会根据请求的 URL 来确定。
- 处理器适配器:一旦找到目标 Controller,DispatcherServlet 会使用 HandlerAdapter 来调用 Controller 的处理方法。
- 执行处理器:Controller 处理请求,处理完后返回一个 ModelAndView 对象,其中包含模型数据和逻辑视图名。
- 视图解析器:DispatcherServlet 接收到 ModelAndView 后,会使用 ViewResolver 来解析视图名称,找到具体的视图页面。
- 渲染视图:视图使用模型数据渲染页面,生成最终的页面内容。
- 响应结果:DispatcherServlet 将视图结果返回给客户端。
在前后端分离的情况下,步骤6,7,8会略有不同,后端通常只需要处理数据,并将JSON格式的数据返回给前端就可以了,而不是返回完整的视图页面。
7.Spring Boot
Spring Boot 是一个开源的、用于简化 Spring 应用初始化和开发过程的框架。提供了一套默认配置,约定优于配置,来帮助我们快速搭建 Spring 项目骨架,极大地提高了我们的生产效率,再也不用为 Spring 的繁琐配置而烦恼了。
8.Spring的自动配置原理
在 Spring 中,自动装配是指容器利用反射技术,根据 Bean 的类型、名称等自动注入所需的依赖。在SpringBoot中,开启自动装配的注解是@EnableAutoConfiguration,Spring Boot 为了进一步简化,直接通过@SpringBootApplication注解一步搞定,它是一个组合注解,包含了@SpringBootConfiguration(声明配置类)、@EnableAutoConfiguration(开启自动配置)、@ComponentScan(扫描指定组件包)三个注解。
@EnableAutoConfiguration:这是开启自动配置的核心注解,它通过@Import(AutoConfigurationImportSelector.class)导入自动配置类。在Spring Boot启动时,这个注解会触发自动配置流程。
9.@SpringBootApplication注解
@SpringBootApplication是 Spring Boot 的核心注解,经常用于主类上,作为项目启动入口的标识。它是一个组合注解:
- @SpringBootConfiguration:继承自@Configuration,标注该类是一个配置类,相当于一个 Spring 配置文件。
- @EnableAutoConfiguration:告诉 Spring Boot 根据 pom.xml 中添加的依赖自动配置项目。例如,如果 spring-boot-starter-web 依赖被添加到项目中,Spring Boot 会自动配置 Tomcat 和 Spring MVC。
- @ComponentScan:扫描当前包及其子包下被@Component、@Service、@Controller、@Repository 注解标记的类,并注册为 Spring Bean。