SpringBoot-基础

1.IOC控制反转

Spring的核心是IoC(Inversion of Control,控制反转)容器,它可以管理容器内的普通Java对象以及对象之间关系的绑定(Dependency Injection依赖注入)。容器中被管理的对象称为Bean。

Spring是通过元数据和POJO来定义和管理Bean的。
◎POJO:简单的Java对象。
◎元数据:描述如何管理POJO的数据。

2.注解配置(@Compoent)

当使用了@Compoent,@Service,@Controller,@Repository时,Spring容器(@CompoentScan实现)会自动扫描,并将他们注册成被容器管理的Bean.

@Service、@Repository和@Controller这三个注解组合了@Component注解,它们是@Component语义上的特例。

3.JAVA配置(@Configuration和@Bean)

在类上注解@Configuration(@Component的特例,会被容器自动扫描),可使类成为配置类。如果使用@Bean标注在类的方法上,则方法的返回值即为Bean的实例。

4.依赖注入(DI)

1.注解注入-直接注入类:在类的属性上添加@Autowired注解,即可获取容器中的Bean对象.

@Component
public class SpringTestDI {
    public void di(){
        System.out.println("已注入Bean的方法");
    }
}
@SpringBootTest
@Component
public class SpringAuto {
    @Autowired
    private SpringTestDI springTestDI;

    @Test
    public void autoPoint(){
        this.springTestDI.di();
    }
}

2.注解注入-注入方法:加在方法上,注册Bean的时候会自动依赖注入

@Component
public class SpringTestDI {
    public void di(){
        System.out.println("已注入Bean的方法");
    }
}
@Component
@Data
public class SpringAuto {

    private SpringTestDI springTestDI;

    @Autowired
    public void autoPoint(SpringTestDI springTestDI){
        this.springTestDI = springTestDI;
    }
}
@SpringBootTest
public class SpringTest {
    @Autowired
    private SpringAuto springAuto;

    @Test
    public void xxx(){
        SpringTestDI springTestDI = springAuto.getSpringTestDI();
        springTestDI.di();
    }
}

3.注解注入-构造方法:加在构造方法上依赖注入,只有一个构造方法可以默认不写@Autowired

@SpringBootTest
@Component
@Data
public class SpringAuto {

    private SpringTestDI springTestDI;

    public SpringAuto(SpringTestDI springTestDI){
        this.springTestDI = springTestDI;
    }

}
5.@Primary

使用@Autowired注解是根据类型自动注入的,当两个类型相同时,无法正确注入,可以使用@Primary注解来确定注入哪一个Bean

@Configuration
public class SpringPrimary {
    @Bean
    public SpringAuto a(){
        System.out.println("a");
        return new SpringAuto("a");
    }

    @Primary
    @Bean
    public SpringAuto b(){
        System.out.println("b");
        return new SpringAuto("b");
    }
}
6.@Qualifier

通过指定名称来确定依赖注入的bean

@Configuration
public class SpringPrimary {
    @Bean("a")
    public SpringAuto a(){
        System.out.println("a");
        return new SpringAuto("a");
    }

    @Bean("b")
    public SpringAuto b(){
        System.out.println("b");
        return new SpringAuto("b");
    }
}
@Autowired
@Qualifier("a")
private SpringAuto springAuto;
7.运行校验CommandLineRunner

是Spring Boot框架提供的一个接口,主要用于应用启动后立即执行特定的业务逻辑。当一个类实现了 CommandLineRunner 接口,Spring Boot将会自动检测并运行该类的 run 方法。这对于一些初始化任务或者一次性执行的任务非常有用,比如读取配置文件、数据预加载、初始化缓存等。

@Component
public class SpringCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("SpringBoot项目启动完成,我来前面探探路");
    }
}
8.@Scpoe

指定Bean的作用域,默认是单例模式,整个容器只有一个相同类型的bean

  1. Singleton(单例)
    • 默认作用域,Spring容器中每个Bean定义对应一个单一实例。
    • 整个容器中,无论何时何处请求该Bean,都会返回相同的实例。
  2. Prototype(原型)
    • 每次请求都会创建一个新的Bean实例。
    • 适用于需要独立状态和生命周期的对象,比如临时性的操作对象。
  3. Request
    • 仅在Web应用上下文中适用,每次HTTP请求都会创建一个新实例,仅在当前请求的生命周期内有效。
  4. Session
    • 同样在Web应用上下文中,每个HTTP Session拥有一个Bean实例,该实例在会话期间持续有效。
  5. GlobalSession(Application Session):
    • 仅在支持portlet的Web应用中使用,每种全局会话(如PortletSession或ServletContext)对应一个Bean实例。
  6. WebSocket
    • 在WebSocket相关的Spring应用上下文中,每个WebSocket连接对应一个Bean实例,仅在该连接生命周期内有效。
/**
 * 原型Prototype 每次都会创建一个新的实例
 */
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class SpringScope {
}
@SpringBootTest
public class SpringTest {
    @Autowired
    private SpringScope springScope1;

    @Autowired
    private SpringScope springScope2;

    @Test
    public void xxx(){
        // 结果:false;  默认不使用Scope注解,结果为true
        System.out.println(springScope1 == springScope2);
    }
}
9.Bean的生命周期

先了解简单的生命周期,以下是顺序执行

@Component
public class SpringLife {
    public SpringLife() {
        System.out.println("bean的构造方法");
    }
    @PostConstruct
    public void init(){
        System.out.println("bean的初始化方法");
    }

    @PreDestroy
    public void destroy(){
        System.out.println("bean的销毁方法");
    }
}
10.@Lazy

延迟初始化:再被调用的时候才会初始化,需要已常见四大组件注解搭配使用

11.@DependsOn

可以控制依赖注入的先后顺序

12.@Enable*

@Enable* 注解系列: Spring框架提供了一系列以 @Enable 开头的注解,这些注解用于启用特定的功能模块或框架特性。例如:

  • @EnableAspectJAutoProxy:启用Spring AOP代理和AspectJ切面自动代理功能。
  • @EnableCaching:启用Spring的缓存支持。
  • @EnableScheduling:启用定时任务调度功能。
  • @EnableTransactionManagement:启用Spring的事务管理支持。
  • @EnableWebMvc:在Spring MVC应用中启用注解驱动的Web MVC配置。
  • @EnableAsync : 用于启用异步方法执行的支持

这些注解通常放在一个配置类上,Spring在扫描和解析配置时会识别到这些注解,并加载相应的配置处理器来处理它们。

13.@Import

@Import 注解用于将其他配置类或配置类的全限定名导入到当前配置类中。当Spring容器加载包含 @Import 注解的配置类时,也会加载并处理被导入的配置类。这样可以实现多个配置类的整合和复用。

@Configuration
@Import({DatabaseConfig.class, ServiceConfig.class, WebConfig.class})
public class AppConfig {
    // ...
}
14.BeanPostProcessor接口

可以通过实现BeanPostProcessor接口,在构造时对容器内所有或者部分指定Bean进行处理。和@PostConstruct与@PreDestroy不同的是,它针对的是IoC容器里的所有的Bean。

  1. postProcessBeforeInitialization(Object bean, String beanName): 这个方法会在Spring容器对Bean实例化并设置好所有属性后,但在调用该Bean的初始化方法(如InitializingBean.afterPropertiesSet() 或者带有 @PostConstruct 注解的方法)之前调用。在该方法中,开发者可以对刚实例化的Bean进行进一步的加工或修改。
  2. postProcessAfterInitialization(Object bean, String beanName): 这个方法会在Bean的初始化方法调用完毕后,但在Bean正式交付给Spring容器使用之前调用。开发者可以在该方法中对已经初始化完成的Bean做进一步的处理,例如AOP代理增强、日志记录等。
public class PostProcessorTest implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("属性设置之后,Bean初始化之前:" + beanName + "]");
        // 可以对bean进行某些操作,例如AOP代理、属性修改等
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Bean初始化之后: [" + beanName + "]");
        // 同样可以对bean进行更多后期处理
        return bean;
    }
}
15.Spring Aware

Spring Aware 是Spring框架中一系列接口的总称,这些接口允许Spring容器在实例化和初始化Bean的过程中向Bean注入特定的资源或信息。实现这些Aware接口的类能够感知Spring容器的存在,并通过Spring容器获取相应的服务或上下文。

◎BeanNameAware:可获得beanName,即Bean的名称。
◎ResourceLoaderAware:可获得ResourceLoader,即用来加载资源的Bean。

◎BeanFactoryAware:可获得BeanFactory,即容器的父接口,用于管理Bean的相关操作。
◎EnvironmentAware:可获得Environment,即当前应用的运行环境。
◎MessageSourceAware:可获得MessageSource,即用来解析文本信息的Bean。
◎ApplicationEventPublisherAware:可获得ApplicationEventPublisher,即用来发布系统时间的Bean。
◎ApplicationContextAware:可自动注入ApplicationContext,即容器本身。

16.Spring 事件通信

如果Bean之间需要通信,比如说BeanA完成了处理后需要告知BeanB,通知BeanB继续处理,那么我们称BeanA为Publisher,称BeanB为Listener。

/**
 * 事件类
 * @Author : MengYansong
 * @create 2024/1/29 15:53
 */
public class MyEvent extends ApplicationEvent {
    public MyEvent(Object source) {
        super(source);
    }
}
/**
 * 发布事件
 */
@Component
public class EventPublisher {
    private final ApplicationContext context;

    @Autowired
    public EventPublisher(ApplicationContext context) {
        this.context = context;
    }

    public void fireEvent() {
        System.out.println("1.发布事件");
        context.publishEvent(new MyEvent(this));
    }
}
/**
 * 事件监听
 */
@Component
public class MyEventListener implements ApplicationListener<MyEvent> {

    @Override
    public void onApplicationEvent(MyEvent event) {
        // 在这里处理事件逻辑
        System.out.println("2.监听事件: " + event);
    }
}
17Spring EL

Spring EL(Spring Expression Language,Spring表达式语言)是Spring生态下的通用语言,在运行时使用表达式查询属性信息(使用符号$)或操作Java对象(使用符号#),主要用在XML或注解上。

@SpringBootTest
public class SpringTest {
    @Autowired
    private EventPublisher eventPublisher;

    @Value("${yyds.y1}")
    private String name;

    @Test
    public void xxx(){
        System.out.println(name);
    }
}
yyds:
  y1: 666
  y2: 777
02-01 00:39