目录
1.什么是IOC、DI
2.什么是AOP
3.spring框架的作用
4.spring的常用注解
5.@Component和@Controller和@Repository和@Service有什么区别
6.@Autowired和Resource两个注解的区别
7.bean的生命周期
8.spring事务的实现方式
9.spring事务的失效场景
10.spring事务的传播特性
11.springboot怎么实现定时任务
12.springboot需要独立的容器运行吗
13.@Import注解的理解
14.@Import注解与其他注解的区别
控制反转(IOC)是一种设计思想,就是原本在程序中需要手动创建对象,现在交由Spring管理创建。比如说,原本我们要在A类中调用B类的方法,就要直接在A中new出B类对象,然后调用B类中的方法,虽然能实现效果,不过存在一个问题,更改需求会对源代码进行修改,这不是好的解决方法。现在创建B对象就交给了Spring,在Spring中,B类对象被看成Bean对象(Spring中类就是Bean),这个Bean对象由spring容器进行创建和管理,这样的话A对象获取B对象中的方法,由主动new,变成被动等Spring创建。主动变被动,就可以理解成控制反转,这样大大降低了耦合,Spring中全都用这种思想,即依赖类不由程序员实例化,而是通过Spring容器帮我们new指定的实例并且将实例注入到需要该对象的类中,而 依赖注入(DI) 是实现这种思想的具体手段,Spring通过DI(依赖注入)实现IOC(控制反转)。
面向切片编程(AOP—Aspect Oriented Programming)可以说是对OOP(面向对象编程)的补充和完善,面向对象就是将事物的特性和行为抽象为一个对象,如people类有身高、体重、年龄等属性,也有吃饭、睡觉等行为。把这些特性和行为封装成一个类,然后可以统一调用。面向切片也可以,比如people类有自己的属性和行为,但是有小一部分人生病要去医院看病,看病这个业务逻辑就不属于哪一个类,因为people泛指所有人,所有人不会都看病。AOP就是把医院看病这一个业务逻辑功能抽取出来,然后动态把这个功能切入到需要的方法(或行为)中,需要的才切入,这样便于减少系统的重复代码,降低模块间的耦合度。常用到AOP的就是安全校验、日志操作、事务操作等,给你先定义好,然后在想用的地方用,这样不会影响已经在服务器运行的项目,然后又能注入新功能,灵活。我们开发dao->service->controller是纵向的,这个AOP就是横向切入,如横向切入一个日志Log,打印执行过程。
Spring 框架是一个开源的 Java 应用框架,主要作用是简化企业级应用程序的开发。它通过提供 IOC(控制反转)和 AOP(面向切面编程)等核心特性,帮助开发者轻松管理对象的创建与依赖关系,支持声明式事务管理、数据访问、消息传递、以及集成各种其他技术框架,使得开发效率更高、代码更易于维护。
1. @Component
2. @Controller
3. @Service
4. @Repository
5. @Autowired
@Autowired
就会自动找到锤子并交给你使用,而你不需要自己去找。6. @Configuration
7. @Bean
@Configuration
类中。8. @RequestMapping
/home
就会触发相应的控制器方法。9. @GetMapping
和 @PostMapping
@RequestMapping
,分别用来处理 GET 和 POST 请求。@GetMapping
是处理查询信息的请求。@PostMapping
是处理提交数据的请求。10. @RequestParam
?name=Tom
,@RequestParam("name")
就会把 Tom
传递到你方法的参数中。11. @PathVariable
url: /user/123
,@PathVariable("id")
就会把 123
作为方法的参数使用。12. @RestController
@Controller
和 @ResponseBody
,返回 JSON 格式的数据,而不是页面视图。13. @ResponseBody
1. @Component
@Component
就像一个“万能标记”,可以用在任何类上。它是一个泛用的注解,其他三个注解其实都是从 @Component
扩展出来的,专门针对不同的应用场景。2. @Controller
@Component
的特殊化,专门负责处理网页请求和响应。你可以理解为这是一个专门用来跟用户打交道的“接待员”,用户点击网页时会触发 @Controller
里的方法。3. @Service
@Service
也是 @Component
的扩展,专门用于业务逻辑处理。你可以理解为“业务经理”,它负责拿到用户的需求(请求),然后执行具体的业务操作,比如计算、处理数据等。4. @Repository
@Component
的另一个扩展,专门负责数据库操作。你可以把它想象成一个“数据助手”,专门帮助你存储、读取和更新数据库里的数据。1)@Autowired是spring框架提供的注解,而@Resource是JDK提供的注解。
2)@Autowired默认是按照类型注入,而@Resource默认是按照名称注入。
3)@Autowired可以用于字段、构造方法和方法上,@Resource可以用于字段和set方法上
4)@Autowired在有多个相同类型的bean时,需要结合@Qualifier注解来精确注入,@Resource在有多个相同类型的bean时,会根据名称进行匹配,如果找不到对应的bean则会报错。
实例化(Instantiation)
new
关键字创建对象。属性填充(Populate Properties)
@Autowired
)。调用 BeanNameAware
接口的 setBeanName
方法
BeanNameAware
接口,Spring 会调用它的 setBeanName
方法,传递当前 Bean 的名字。调用 BeanFactoryAware
、ApplicationContextAware
等接口的方法
BeanPostProcessor
的 postProcessBeforeInitialization
方法
BeanPostProcessor
的 postProcessBeforeInitialization
方法。初始化(Initialization)
InitializingBean
接口,则会调用它的 afterPropertiesSet
方法。或者,如果在配置文件中指定了 init-method
,也会调用该方法。BeanPostProcessor
的 postProcessAfterInitialization
方法
BeanPostProcessor
的 postProcessAfterInitialization
方法。Bean 就绪(Ready to Use)
销毁(Destruction)
DisposableBean
接口,会调用它的 destroy
方法。或者,如果在配置文件中指定了 destroy-method
,也会调用这个方法。Spring 提供了两种主要的事务管理方式:编程式事务管理 和 声明式事务管理。
1. 编程式事务管理
解释:编程式事务管理是指在代码中通过显式的方式来管理事务的生命周期。你需要在代码里手动定义事务的开始、提交和回滚。它的优势是灵活,可以精确控制事务的边界,但缺点是代码会变得冗长复杂,增加了维护成本。
适用场景:这种方式通常适用于需要非常细粒度的事务控制,或者是在少数情况下需要程序逻辑特别复杂的场景。
2. 声明式事务管理
解释:声明式事务管理是 Spring 中最常用的事务管理方式。通过配置(例如注解或 XML 配置),你可以声明哪些方法或类需要事务支持。Spring 会自动处理这些事务的开始、提交和回滚,基于 AOP(面向切面编程)机制。
优点:声明式事务管理不需要在代码中手动管理事务,简化了代码,并且更容易维护。开发者只需关注业务逻辑本身,Spring 框架会自动处理事务相关的细节。
适用场景:适合大多数业务场景,特别是当事务逻辑比较简单或典型时,比如常规的数据库操作(增、删、改)。
1. 事务方法是 private
或 final或者
事务注解 @Transactional
没有被应用在 public
方法上
Spring 声明式事务基于 AOP(面向切面编程)实现,AOP 通过代理对象来处理事务。如果方法是 private
或 final
,Spring 无法代理这些方法,从而导致事务失效。
原因:Spring AOP 需要通过代理类调用目标对象的方法。如果是 private
方法,Spring 无法从代理类外部访问它;如果是 final
方法,代理类无法重写它,从而不能应用事务。
解决方案:将方法的访问修饰符改为 public
或 protected
,并避免将事务方法声明为 final
。
2. 事务方法内部调用(self-invocation)
如果一个类中的方法 A 调用了同一类中的另一个带有 @Transactional
的方法 B,由于调用是内部的,Spring AOP 不会生成代理对象,因此事务不会生效。
原因:Spring AOP 是通过代理来管理事务的,代理只能拦截外部的调用。如果是类内部的自我调用,代理不会被使用,事务拦截器也无法生效。
解决方案:将事务方法放到另一个类中,或者使用 AspectJ 这种基于字节码增强的 AOP 来替代 Spring AOP。
3. 事务方法抛出的异常不是 RuntimeException
默认情况下,Spring 只在捕获到 RuntimeException
或 Error
时才会触发事务回滚。如果事务方法抛出的异常是 CheckedException
,则不会回滚。
原因:Spring 的事务管理默认遵循 unchecked exceptions
(如 RuntimeException
)导致回滚,而 checked exceptions
(如 Exception
)默认不会导致回滚。
解决方案:
@Transactional
注解中配置 rollbackFor
来指定哪些 checked exceptions
也会触发回滚。@Transactional(rollbackFor = Exception.class)
4. 代理模式导致的失效(CGLIB 和 JDK 动态代理)
Spring 使用两种代理方式:JDK 动态代理和 CGLIB。JDK 动态代理只代理接口,如果你的类没有实现接口,Spring 会使用 CGLIB 代理类。如果在项目中使用的代理模式不匹配,事务可能不会生效。
proxyTargetClass = true
)。1. PROPAGATION_REQUIRED (默认)
2. PROPAGATION_REQUIRES_NEW
3. PROPAGATION_SUPPORTS
4. PROPAGATION_NOT_SUPPORTED
5. PROPAGATION_NEVER
6. PROPAGATION_MANDATORY
启用定时任务
启用定时任务:在主程序类或配置类中,通过添加 @EnableScheduling
注解来启用定时任务功能。
使用 @Scheduled
注解:将 @Scheduled
注解加到需要执行定时任务的方法上。它支持以下几种常见的使用方式:
cron
表达式来控制任务执行的时间。它可以精确到秒、分钟、小时、天等,非常灵活。Spring Boot 不需要独立的容器来运行。它可以直接通过内嵌的 Web 服务器(如 Tomcat、Jetty 或 Undertow)在 Java 应用程序内部运行。这意味着 Spring Boot 应用是自包含的,可以像普通的 Java 应用程序一样运行,而不需要在外部的应用服务器或容器中部署。
Spring Boot 的默认行为是打包成可执行的 JAR 文件,其中包含内嵌的 Web 服务器。你只需运行 JAR 文件即可启动应用,无需提前配置和部署应用服务器。
如果有需要,Spring Boot 也可以打包为 WAR 文件并部署到传统的 Web 容器中。
@Import
注解在 Spring 中用于将其他配置类或组件引入到当前的应用程序中,简化了配置管理。它的主要作用是帮助开发者将多个配置类或组件集中管理,便于模块化开发。当你有很多配置文件时,可以用 @Import
把它们组合在一起。
1. @Import
vs @ComponentScan
@Import
:手动指定需要导入的配置类或组件类,将其直接加载到 Spring 容器中。适合在明确知道某些类时使用,可以一次导入多个类或配置文件。
@ComponentScan
:自动扫描指定包及其子包下的类,并将标注了 @Component
、@Service
、@Controller
等注解的类自动注册为 Spring Bean。
区别:
@Import
是手动指定要引入的类或配置,而 @ComponentScan
是自动扫描某个包路径下的类。2. @Import
vs @Autowired
@Import
:用于将其他类或配置类导入到 Spring 容器中,让 Spring 容器管理这些类,通常用于模块化或跨配置文件引用类。
@Autowired
:用于自动注入依赖对象,将一个类的实例自动注入到另一个类中,解决类与类之间的依赖关系。
区别:
@Import
处理的是类或配置的引入,@Autowired
处理的是对象的依赖注入。3. @Import
vs @Bean
@Import
:可以导入多个配置类或普通类到 Spring 容器中,并让 Spring 管理它们。
@Bean
:用于在配置类中定义一个单独的 Bean,告诉 Spring 容器手动管理这个 Bean 的创建。每个 @Bean
方法定义一个 Spring 管理的对象。
区别:
@Import
是批量引入类,@Bean
是定义单个 Bean 对象。4. @Import
vs @Configuration
@Import
:用于引入其他配置类,确保这些类的 Bean 被加载到 Spring 容器中。
@Configuration
:声明一个类是配置类,用于定义 Bean。@Configuration
类本身是通过 @Import
来集成到应用中的。
区别:
@Configuration
声明类为配置类,@Import
则用于加载这些配置类