# spring_boot_study **Repository Path**: LLBlood/spring_boot_study ## Basic Information - **Project Name**: spring_boot_study - **Description**: SpringBoot2.x学习 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-10-21 - **Last Updated**: 2021-11-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # spring_boot_study SpringBoot2.x学习 ### 第一章 Spring注解 #### 1.ioc容器 Spring IoC容器是一个管理Bean的容器,在Spring的定义中,它要求所有的IoC容器都需要实现接口BeanFactory,它是一个顶级容器接口 ```java @Configuration 用于配置类,可以当作XML的注解类型 @Bean 用来装载bean,若未传name参数,则默认使用方法的首字母小写名,只要装载的bean名称不一样即可,类型无所谓一不一样 @ComponentScan 用来加载扫描的包路径 如果未传参数,则默认该扫描类的当前包及子包 如果自己写入了ComponentScan想要扫描的路径,那么代码会按照指定路径去加载包 @ComponentScan(basePackages = "cn.liulin.spring_boot_study.pojo", //此处@ComponentScan.Filter必须要过滤注解类型数据(Service指代@Service) excludeFilters = {@ComponentScan.Filter(classes = Service.class)}) @Component 用来表明该类是否可以被扫描 若未传name参数,则默认使用方法的首字母小写名 @Value 用来注入属性值 ``` #### 2.加载配置类属性 ```java ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppTestConfig.class); ``` #### 3.@Autowired的使用 首先它会根据类型找到对应的Bean,如果对应类型的Bean不是唯一的,那么它会根据其属性名称和Bean的名称进行匹配。如果匹配得上,就会使用该Bean;如果还无法匹配,就会抛出异常。这里还要注意的是@Autowired是一个默认必须找到对应Bean的注解,如果不能确定其标注属性一定会存在并且允许这个被标注的属性为null,那么你可以配置@Autowired属性required为false ```java @Autowired用于依赖注入 @Autowired private Animal animal; 按照类型注入数据 @Autowired private Animal cat; 按照名为cat注入数据 @Autowired public void setAnimal(Animal animal) { this.animal = animal; } autowired可以用于setAnimal上 public BussinessPerson(@Autowired Animal animal) { this.animal = animal; } 构造函数直接使用 @Autowired(required = false) ``` ```java @Primary @Primary是一个修改优先权的注解,默认优先使用该类,比如同时存在animal的实现类cat,dog,对于@Autowired的注入来说,存在primary的情况下,优先使用该注解的类 @Autowired @Qualifier("cat") @Qualifier与@Autowired联合使用,以Qualifier内的名为准 还可以直接在构造函数直接使用@Autowired @Qualifier("dog") public BussinessPerson(@Autowired @Qualifier("dog") Animal animal) { this.animal = animal; } ``` #### 4.生命周期 ##### 4.1 SpringBean的初始化流程 1. 资源定位:例如@ComponentScan所定义的扫描包 2. Bean定义:将Bean的定义保存到BeanDefinition的实例中 3. 发布Bean定义:IoC容器装载Bean定义 4. 实例化:创建Bean的实例对象 5. 依赖注入(DI):例如@Autowired注入的各类资源 ##### 4.2 ComponentScan 配置延迟初始化 lazyInit = true,Spring并不会在发布Bean定义后马上为我们完成实例化和依赖注入,而是在使用的时候完成实例化和依赖注入。 ```java @ComponentScan(basePackages = "cn.liulin.spring_boot_study.pojo", lazyInit = true) ``` ##### 4.3 @PostConstruct ```java 该注解的方法在整个Bean初始化中的执行顺序: Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法) ``` ##### 4.4 @PreDestroy ``` @PreDestroy -> destroy()方法 -> ->彻底销毁 ``` ##### 4.5 Bean的完整初始化流程 Spring IOC容器最低的要求是实现BeanFactory接口 1. 初始化 2. 依赖注入 3. BeanNameAware的setBeanName方法 4. BeanFactoryAware的setBeanFactory方法 5. ApplicationContextAware的setApplicationContext方法(需要容器实现ApplicationContext接口才会被调用) 6. 后置Bean初始化器BeanPostProcessor调用postProcessBeforeInitialization方法(针对全部Bean生效) 7. @PostConstruct定义的自定义初始化方法 8. InitializingBean的afterPropertiesSet方法 9. 后置Bean初始化器BeanPostProcessor调用postProcessAfterInitialization方法(针对全部Bean生效) 10. 生存期 11. @PreDestroy定义的自定义销毁方法 12. DisposableBean的destroy方法 ##### 4.6 @Bean自定义初始化和销毁方法 ```java @Bean(name = "useSelf", initMethod = "initMethod", destroyMethod = "destroyMethod") public UseSelf getUseSelf() { UseSelf useSelf = new UseSelf(); useSelf.setMsg("这"); return useSelf; } ``` #### 5.属性配置 ##### 5.1 @Value和${...}占位符 ```java //直接在属性上配置 @Value("${database.driverName}") private String driverName; //在方法上配置 @Value("${database.password}") public void setPassword(String password) { System.out.println(password); this.password = password; } ``` ##### 5.2 @ConfigurationProperties ```java //配置在类上,可以简化配置,无需再使用@Value和${...}占位符,只需要属性名和配置名一致即可 @ConfigurationProperties("database") public class DataBasePropertiesTwo { private String driverName; } ``` ##### 5.3 @PropertySource ```java /* * 配置在类上,可以指定配置文件读取路径,从对应配置文件获取配置信息 * ignoreResourceNotFound,默认为false。找不到对应路径文件就会报错,为true找不到会忽略掉,不会报错 */ @PropertySource("classpath:jdbc.properties", ignoreResourceNotFound = true) public class DataBasePropertiesTwo { @Value("${database.driverName}") private String driverName; } ``` #### 6.条件装配bean ```java @Bean(name = "dataSource") @Conditional(DatabaseConditional.class) public DataSource getDataSource(@Value("${database.driverName}")String driver, @Value("${database.url}")String url, @Value("${database.username}")String username, @Value("${database.password}")String password) { } public class DatabaseConditional implements Condition { /** * 数据库装配条件 * @author ll * @date 2021-11-01 17:35:36 * @param context 条件上下文 * @param metadata 注释类型的元数据 * @return boolean true装配Bean,否则不装配 **/ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //取出环境配置 Environment environment = context.getEnvironment(); //判断属性文件是否存在对应的数据库配置 return environment.containsProperty("database.driverName") && environment.containsProperty("database.url") && environment.containsProperty("database.username") && environment.containsProperty("database.password"); } } ``` #### 7.Bean的作用域 ```java @Component //多例 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class BeanScope { } /* * ConfigurableBeanFactory.SCOPE_SINGLETON 单例 所有Spring应用 默认值,ioc容器只存在单例 * ConfigurableBeanFactory.SCOPE_PROTOTYPE 多例 所有Spring应用 每当从ioc容器中取出一个bean,就创建一个新的bean * ConfigurableBeanFactory.SCOPE_REQUEST 请求 SpringWeb应用 Web工程单次请求 * ConfigurableBeanFactory.SCOPE_SESSION 会话 SpringWeb应用 HTTP会话 * ConfigurableBeanFactory.SCOPE_APPLICATION 应用 SpringWeb应用 Web工程生命周期 * globalSession 全局session SpringWeb应用 一个全局的Http Session中,一个Bean定义对应一个实例。 */ ```