Java之Spring Boot入门到精通【IDEA版】SpringBoot原理分析

在这里插入图片描述

  • 编写配置类

在这里插入图片描述

在这里插入图片描述

package cn.itbluebox.config;

import cn.itbluebox.domain.User;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class UserConfig {

@Bean

public User user(){

return new User();

}

}

(2)获取第三方jar
1)第一种实现使用第三方的jar(使用@ComponentScan扫描cn.itbluebox.config)

springboot-enable当的pom.xml添加springboot-enable-other的对应的User的依赖

在这里插入图片描述

cn.itbluebox

springboot-enable-other

0.0.1-SNAPSHOT

  • 运行测试springboot-enable当中的SpringbootEnableApplication

在这里插入图片描述

无法获取到user

在这里插入图片描述

所以光是引入其他工程的依赖是无法获取到其他工程的Bean

SpringbootEnableApplication上使用@ComponentScan("cn.itbluebox.config")需要扫描对应配置类所在的包

  • 修改springboot-enable当中的SpringbootEnableApplication

在这里插入图片描述

package cn.itbluebox.springbootenable;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

/*

@ComponentScan 扫描范围:是当前引导类所在包,及其子包

cn.itbluebox.springbootenable

User在cn.itbluebox.config当中

上述两个包直接没有任何包含关系

//1、使用@ComponentScan扫描cn.itbluebox.config

*/

@SpringBootApplication

@ComponentScan(“cn.itbluebox.config”)

public class SpringbootEnableApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

//获取Bean

Object user = context.getBean(“user”);

System.out.println(user);

}

}

运行测试

在这里插入图片描述

运行成功

在这里插入图片描述

2)第二种实现使用第三方的jar(使用@Import注解,加载类)
  • 修改SpringbootEnableApplication

在这里插入图片描述

package cn.itbluebox.springbootenable;

import cn.itbluebox.config.UserConfig;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Import;

/*

@ComponentScan 扫描范围:是当前引导类所在包,及其子包

cn.itbluebox.springbootenable

User在cn.itbluebox.config当中

上述两个包直接没有任何包含关系

//1、使用@ComponentScan扫描cn.itbluebox.config

//2、使用@Import注解,加载类,这些类都会被Spring创建,并放入IOC容器

*/

@SpringBootApplication

//@ComponentScan(“cn.itbluebox.config”)

@Import(UserConfig.class)

public class SpringbootEnableApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

//获取Bean

Object user = context.getBean(“user”);

System.out.println(user);

}

}

  • 运行测试

在这里插入图片描述

在这里插入图片描述

3)第三种实现使用第三方的jar(可以对Import注解进行封装)

在第三的springboot-enable-other当中提供对应的功能

  • 创建EnableUser

在这里插入图片描述

在这里插入图片描述

package cn.itbluebox.config;

import org.springframework.context.annotation.Import;

import java.lang.annotation.*;

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Import(UserConfig.class)

public @interface EnableUser {

}

  • 修改springboot-enable当中的SpringbootEnableApplication

在这里插入图片描述

package cn.itbluebox.springbootenable;

import cn.itbluebox.config.EnableUser;

import cn.itbluebox.config.UserConfig;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Import;

/*

@ComponentScan 扫描范围:是当前引导类所在包,及其子包

cn.itbluebox.springbootenable

User在cn.itbluebox.config当中

上述两个包直接没有任何包含关系

//1、使用@ComponentScan扫描cn.itbluebox.config

//2、使用@Import注解,加载类,这些类都会被Spring创建,并放入IOC容器

//3、可以对Import注解进行封装

*/

@SpringBootApplication

//@ComponentScan(“cn.itbluebox.config”)

//@Import(UserConfig.class)

@EnableUser

public class SpringbootEnableApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

//获取Bean

Object user = context.getBean(“user”);

System.out.println(user);

}

}

  • 运行测试

在这里插入图片描述

在这里插入图片描述

5、@lmport注解

@Enable*底层依赖于@lmport注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器中。而@lmport提供4中用法:

(1)导入Bean
  • 修改SpringbootEnableApplication

在这里插入图片描述

package cn.itbluebox.springbootenable;

import cn.itbluebox.config.EnableUser;

import cn.itbluebox.config.UserConfig;

import cn.itbluebox.domain.User;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Import;

/*

@ComponentScan 扫描范围:是当前引导类所在包,及其子包

cn.itbluebox.springbootenable

User在cn.itbluebox.config当中

上述两个包直接没有任何包含关系

//1、使用@ComponentScan扫描cn.itbluebox.config

//2、使用@Import注解,加载类,这些类都会被Spring创建,并放入IOC容器

//3、可以对Import注解进行封装

*/

/*

Import的4种用法:

1、导入Bean

*/

@SpringBootApplication

//@ComponentScan(“cn.itbluebox.config”)

//@Import(UserConfig.class)

//@EnableUser

@Import(User.class)

public class SpringbootEnableApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

//获取Bean

Object user = context.getBean(“user”);

System.out.println(user);

}

}

  • 运行测试

在这里插入图片描述

无法获取到

在这里插入图片描述

虽然通过@Import(User.class)引入创建了User的对象但是并不一定是getBean的时候叫user,通过User字节码获取

  • 修改springboot-enable当中的SpringbootEnableApplication

在这里插入图片描述

package cn.itbluebox.springbootenable;

import cn.itbluebox.config.EnableUser;

import cn.itbluebox.config.UserConfig;

import cn.itbluebox.domain.User;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Import;

/*

@ComponentScan 扫描范围:是当前引导类所在包,及其子包

cn.itbluebox.springbootenable

User在cn.itbluebox.config当中

上述两个包直接没有任何包含关系

//1、使用@ComponentScan扫描cn.itbluebox.config

//2、使用@Import注解,加载类,这些类都会被Spring创建,并放入IOC容器

//3、可以对Import注解进行封装

*/

/*

Import的4种用法:

1、导入Bean

*/

@SpringBootApplication

//@ComponentScan(“cn.itbluebox.config”)

//@Import(UserConfig.class)

//@EnableUser

@Import(User.class)

public class SpringbootEnableApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

//获取Bean

/* Object user = context.getBean(“user”);

System.out.println(user);*/

User user = context.getBean(User.class);

System.out.println(user);

}

}

在这里插入图片描述

在这里插入图片描述

  • 获取一些其他属性

在这里插入图片描述

package cn.itbluebox.springbootenable;

import cn.itbluebox.config.EnableUser;

import cn.itbluebox.config.UserConfig;

import cn.itbluebox.domain.User;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Import;

import java.util.Map;

/*

@ComponentScan 扫描范围:是当前引导类所在包,及其子包

cn.itbluebox.springbootenable

User在cn.itbluebox.config当中

上述两个包直接没有任何包含关系

//1、使用@ComponentScan扫描cn.itbluebox.config

//2、使用@Import注解,加载类,这些类都会被Spring创建,并放入IOC容器

//3、可以对Import注解进行封装

*/

/*

Import的4种用法:

1、导入Bean

*/

@SpringBootApplication

//@ComponentScan(“cn.itbluebox.config”)

//@Import(UserConfig.class)

//@EnableUser

@Import(User.class)

public class SpringbootEnableApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

//获取Bean

/* Object user = context.getBean(“user”);

System.out.println(user);*/

User user = context.getBean(User.class);

System.out.println(user);

Map<String, User> map = context.getBeansOfType(User.class);

System.out.println(map);

}

}

  • 运行测试

在这里插入图片描述

在这里插入图片描述

(2)导入配置类
  • 修改springboot-enable当中的SpringbootEnableApplication

在这里插入图片描述

package cn.itbluebox.springbootenable;

import cn.itbluebox.config.EnableUser;

import cn.itbluebox.config.UserConfig;

import cn.itbluebox.domain.User;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Import;

import java.util.Map;

/*

@ComponentScan 扫描范围:是当前引导类所在包,及其子包

cn.itbluebox.springbootenable

User在cn.itbluebox.config当中

上述两个包直接没有任何包含关系

//1、使用@ComponentScan扫描cn.itbluebox.config

//2、使用@Import注解,加载类,这些类都会被Spring创建,并放入IOC容器

//3、可以对Import注解进行封装

*/

/*

Import的4种用法:

1、导入Bean

2、导入配置类

*/

@SpringBootApplication

//@ComponentScan(“cn.itbluebox.config”)

//@Import(UserConfig.class)

//@EnableUser

//@Import(User.class)

@Import(UserConfig.class)

public class SpringbootEnableApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

//获取Bean

/* Object user = context.getBean(“user”);

System.out.println(user);*/

User user = context.getBean(User.class);

System.out.println(user);

Map<String, User> map = context.getBeansOfType(User.class);

System.out.println(map);

}

}

  • 在springboot-enable-other当中创建Role对象

在这里插入图片描述

在这里插入图片描述

  • 修改springboot-enable-other当中的UserConfig

在这里插入图片描述

  • Role也会创建到Spring的IOC容器当中

package cn.itbluebox.config;

import cn.itbluebox.domain.Role;

import cn.itbluebox.domain.User;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class UserConfig {

@Bean

public User user(){

return new User();

}

@Bean

public Role role(){

return new Role();

}

}

  • 完善springboot-enable当中的SpringbootEnableApplication

在这里插入图片描述

package cn.itbluebox.springbootenable;

import cn.itbluebox.config.EnableUser;

import cn.itbluebox.config.UserConfig;

import cn.itbluebox.domain.Role;

import cn.itbluebox.domain.User;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Import;

import java.util.Map;

/*

@ComponentScan 扫描范围:是当前引导类所在包,及其子包

cn.itbluebox.springbootenable

User在cn.itbluebox.config当中

上述两个包直接没有任何包含关系

//1、使用@ComponentScan扫描cn.itbluebox.config

//2、使用@Import注解,加载类,这些类都会被Spring创建,并放入IOC容器

//3、可以对Import注解进行封装

*/

/*

Import的4种用法:

1、导入Bean

2、导入配置类

*/

@SpringBootApplication

//@ComponentScan(“cn.itbluebox.config”)

//@Import(UserConfig.class)

//@EnableUser

//@Import(User.class)

@Import(UserConfig.class)

public class SpringbootEnableApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

//获取Bean

/* Object user = context.getBean(“user”);

System.out.println(user);*/

User user = context.getBean(User.class);

System.out.println(user);

Role role = context.getBean(Role.class);

System.out.println(role);

/*

Map<String, User> map = context.getBeansOfType(User.class);

System.out.println(map);

*/

}

}

  • 运行测试

在这里插入图片描述

在这里插入图片描述

  • springboot-enable当中的SpringbootEnableApplication上使用@Import注解的时候在springboot-enable-other当中的UserConfig上可以不使用 @Configuration注解

在这里插入图片描述

在这里插入图片描述

  • 运行测试

在这里插入图片描述

在这里插入图片描述

(3)导入ImportSelector实现类。一般用于加载配置文件中的类
  • 源代码

public interface ImportSelector {

String[] selectImports(AnnotationMetadata importingClassMetadata);

@Nullable

default Predicate getExclusionFilter() {

return null;

}

}

  • 在springboot-enable-other当中创建MyImportSelector,去实现ImportSelector接口

在这里插入图片描述

在这里插入图片描述

package cn.itbluebox.config;

import org.springframework.context.annotation.ImportSelector;

import org.springframework.core.type.AnnotationMetadata;

public class MyImportSelector implements ImportSelector {

@Override

public String[] selectImports(AnnotationMetadata importingClassMetadata) {

return new String[]{“cn.itbluebox.domain.User”,“cn.itbluebox.domain.Role”};

}

}

  • 修改springboot-enable当中的SpringbootEnableApplication

在这里插入图片描述

package cn.itbluebox.springbootenable;

import cn.itbluebox.config.EnableUser;

import cn.itbluebox.config.MyImportSelector;

import cn.itbluebox.config.UserConfig;

import cn.itbluebox.domain.Role;

import cn.itbluebox.domain.User;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Import;

import org.springframework.context.annotation.ImportSelector;

import java.util.Map;

/*

@ComponentScan 扫描范围:是当前引导类所在包,及其子包

cn.itbluebox.springbootenable

User在cn.itbluebox.config当中

上述两个包直接没有任何包含关系

//1、使用@ComponentScan扫描cn.itbluebox.config

//2、使用@Import注解,加载类,这些类都会被Spring创建,并放入IOC容器

//3、可以对Import注解进行封装

*/

/*

Import的4种用法:

1、导入Bean

2、导入配置类

3、导入ImportSelector的实现类。

*/

@SpringBootApplication

//@ComponentScan(“cn.itbluebox.config”)

//@Import(UserConfig.class)

//@EnableUser

//@Import(User.class)

//@Import(UserConfig.class)

@Import(MyImportSelector.class)

public class SpringbootEnableApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

//获取Bean

/* Object user = context.getBean(“user”);

System.out.println(user);*/

User user = context.getBean(User.class);

System.out.println(user);

Role role = context.getBean(Role.class);

System.out.println(role);

/*

Map<String, User> map = context.getBeansOfType(User.class);

System.out.println(map);

*/

}

}

  • 运行测试

在这里插入图片描述

在这里插入图片描述

(4)导入ImportBeanDefinitionRegistrar实现类。
  • 在springboot-enable-other当中创建

在这里插入图片描述

在这里插入图片描述

package cn.itbluebox.config;

import cn.itbluebox.domain.User;

import org.springframework.beans.factory.support.AbstractBeanDefinition;

import org.springframework.beans.factory.support.BeanDefinitionBuilder;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;

import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;

import org.springframework.core.type.AnnotationMetadata;

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

@Override

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry ) {

AbstractBeanDefinition beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();

registry.registerBeanDefinition(“user”,beanDefinitionBuilder);

}

}

  • 完善springboot-enable当中的SpringbootEnableApplication

在这里插入图片描述

package cn.itbluebox.springbootenable;

import cn.itbluebox.config.EnableUser;

import cn.itbluebox.config.MyImportBeanDefinitionRegistrar;

import cn.itbluebox.config.MyImportSelector;

import cn.itbluebox.config.UserConfig;

import cn.itbluebox.domain.Role;

import cn.itbluebox.domain.User;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Import;

import org.springframework.context.annotation.ImportSelector;

import java.util.Map;

/*

@ComponentScan 扫描范围:是当前引导类所在包,及其子包

cn.itbluebox.springbootenable

User在cn.itbluebox.config当中

上述两个包直接没有任何包含关系

//1、使用@ComponentScan扫描cn.itbluebox.config

//2、使用@Import注解,加载类,这些类都会被Spring创建,并放入IOC容器

//3、可以对Import注解进行封装

//4、导入ImportBeanDefinitionRegistrar的实现类

*/

/*

Import的4种用法:

1、导入Bean

2、导入配置类

3、导入ImportSelector的实现类。

*/

@SpringBootApplication

//@ComponentScan(“cn.itbluebox.config”)

//@Import(UserConfig.class)

//@EnableUser

//@Import(User.class)

//@Import(UserConfig.class)

//@Import(MyImportSelector.class)

@Import({MyImportBeanDefinitionRegistrar.class})

public class SpringbootEnableApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

//获取Bean

/* Object user = context.getBean(“user”);

System.out.println(user);*/

User user = context.getBean(User.class);

System.out.println(user);

Role role = context.getBean(Role.class);

System.out.println(role);

/*

Map<String, User> map = context.getBeansOfType(User.class);

System.out.println(map);

*/

}

}

  • 运行测试

在这里插入图片描述

user获取成功,但是Role没有获取成功(因为在MyImportBeanDefinitionRegistrar没有导入Role的)

在这里插入图片描述

6、@EnableAutoConfiguration注解

  • 源代码

@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

@AutoConfigurationPackage

@Import({AutoConfigurationImportSelector.class})

public @interface EnableAutoConfiguration {

String ENABLED_OVERRIDE_PROPERTY = “spring.boot.enableautoconfiguration”;

Class<?>[] exclude() default {};

String[] excludeName() default {};

}

  • @EnableAutoConfiauration注解内部使用@Import (AutoConficurationImportSelector.class)来加载配置类。

  • 配置文件位置: META-INF/spring.factories,该配置文件中定义了大量的配置类,当SpringBoot应用启动时,会自动加载这些配置类,初始化Bean

  • 并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足条件的Bean

(注意spring.factories当中的配置类在Spring启动的时候并不会全部创建在每一个类上都有ConditionalOnClass判断是否需要加载当前对象)

7、自定义starter步骤分析

案例:

需求:自定义redis-starter。要求当导入redis坐标时,SpringBoot自动创建Jedis的Bean。

实现上述需求,我们可以参考MyBatis

(1)创建redis-spring-boot-autoconfigure模块

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

(2)创建redis-spring-boot-starter模块,依赖redis-spring-boot-autoconfigure的模块

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

(3)修改创建好的两个模块对其进行瘦身
1)修改redis-spring-boot-starter当中的内容对其进行瘦身
  • 删除一些文件

在这里插入图片描述

  • 修改pom.xml文件

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns=“http://maven.apache.org/POM/4.0.0” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd”>

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.5.6

cn.itbluebox

redis-spring-boot-starter

0.0.1-SNAPSHOT

redis-spring-boot-starter

Demo project for Spring Boot

<java.version>1.8</java.version>

org.springframework.boot

spring-boot-starter

cn.itbluebox

redis-spring-boot-autoconfigure

0.0.1-SNAPSHOT

  • 删除启动类和测试类

在这里插入图片描述

2)修改redis-spring-boot-autoconfigure对其进行瘦身
  • 删除一些文件

在这里插入图片描述

  • 修改pom.xml文件

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns=“http://maven.apache.org/POM/4.0.0” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd”>

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.5.6

cn.itbluebox

redis-spring-boot-autoconfigure

0.0.1-SNAPSHOT

redis-spring-boot-autoconfigure

Demo project for Spring Boot

<java.version>1.8</java.version>

org.springframework.boot

spring-boot-starter

redis.clients

jedis

  • 删除启动类和测试类

在这里插入图片描述

(3)在redis-spring-boot-autoconfigure模块中初始化Jedis的Bean。并定义META-INF/spring.factories文件
1)创建RedisAutoConfiguration

在这里插入图片描述

在这里插入图片描述

package cn.itbluebox.redis.config;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import redis.clients.jedis.Jedis;

@Configuration

public class RedisAutoConfiguration {

/*

提供Jedis的Bean

*/

@Bean

public Jedis jedis(){

return new Jedis();

}

}

2)创建RedisProperties

在这里插入图片描述

在这里插入图片描述

package cn.itbluebox.redis.config;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = “redis”)

public class RedisProperties {

private String host = “localhost”;//设置默认值

private int port = 6379;//设置默认值

public String getHost() {

return host;

}

public void setHost(String host) {

this.host = host;

}

public int getPort() {

return port;

}

public void setPort(int port) {

this.port = port;

}

}

3)完善RedisAutoConfiguration

在这里插入图片描述

package cn.itbluebox.redis.config;

import org.springframework.boot.context.properties.EnableConfigurationProperties;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import redis.clients.jedis.Jedis;

@Configuration

@EnableConfigurationProperties(RedisProperties.class)//设置完之后RedisProperties会被Spring所识别

public class RedisAutoConfiguration {

/*

提供Jedis的Bean

*/

@Bean

public Jedis jedis(RedisProperties redisProperties){

return new Jedis(redisProperties.getHost(),redisProperties.getPort());

}

}

4)创建spring.factories

在这里插入图片描述

在这里插入图片描述

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

cn.itbluebox.redis.config.RedisAutoConfiguration

(4)在测试模块中引入自定义的redis-starter依赖,测试获取Jedis的Bean,操作redis。
  • 修改springboot-enable当中pom.xml

在这里插入图片描述

cn.itbluebox

redis-spring-boot-starter

0.0.1-SNAPSHOT

  • 继续完善springboot-enable当中的SpringbootEnableApplication

在这里插入图片描述

package cn.itbluebox.springbootenable;

import cn.itbluebox.config.MyImportBeanDefinitionRegistrar;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.context.annotation.Import;

import redis.clients.jedis.Jedis;

@SpringBootApplication

@Import({MyImportBeanDefinitionRegistrar.class})

public class SpringbootEnableApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

Jedis jedis = context.getBean(Jedis.class);

System.out.println(jedis);

}

}

  • 运行测试

在这里插入图片描述

在这里插入图片描述

(5)操作上述获取到的Jedis
  • 启动本机的redis

在这里插入图片描述

在SpringbootEnableApplication操作redis存入数据,并获取数据

在这里插入图片描述

package cn.itbluebox.springbootenable;

import cn.itbluebox.config.MyImportBeanDefinitionRegistrar;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.context.annotation.Import;

import redis.clients.jedis.Jedis;

@SpringBootApplication

@Import({MyImportBeanDefinitionRegistrar.class})

public class SpringbootEnableApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

Jedis jedis = context.getBean(Jedis.class);

System.out.println(jedis);

jedis.set(“name”,“itbluebox”);

String name = jedis.get(“name”);

System.out.println(name);

}

}

  • 运行测试

在这里插入图片描述

在这里插入图片描述

(6)编写配置文件设置redis的属性
1)设置端口号

RedisProperties会绑定到对应的配置文件读取配置文件当中的信息

在这里插入图片描述

  • 在springboot-enable当中的application.properties设置端口号

在这里插入图片描述

redis.port=6666

更改端口号后一定报错,但是证明配置修改成功

  • 运行测试

在这里插入图片描述

在这里插入图片描述

2)在RedisAutoConfiguration上设置一些条件
  • 修改redis-spring-boot-autoconfigure当中的RedisAutoConfiguration

在这里插入图片描述

package cn.itbluebox.redis.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

import org.springframework.boot.context.properties.EnableConfigurationProperties;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import redis.clients.jedis.Jedis;

@Configuration

@EnableConfigurationProperties(RedisProperties.class)//设置完之后RedisProperties会被Spring所识别

@ConditionalOnClass(Jedis.class)//设置Jedis存在的时候才去加载

public class RedisAutoConfiguration {

/*

提供Jedis的Bean

*/

@Bean

@ConditionalOnMissingBean(name = “jedis”)//如果用户定义了自己的Jedis就使用用户自定义的Jedis,没有没有定义使用当前的

public Jedis jedis(RedisProperties redisProperties){

System.out.println(“RedisAutoConfiguration…”);

return new Jedis(redisProperties.getHost(),redisProperties.getPort());

}

}

  • 运行测试

设置正确的端口号

在这里插入图片描述

运行

在这里插入图片描述

在这里插入图片描述

  • 修改springboot-enable当中的SpringbootEnableApplication

在这里插入图片描述

package cn.itbluebox.springbootenable;

import cn.itbluebox.config.MyImportBeanDefinitionRegistrar;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Import;

import redis.clients.jedis.Jedis;

@SpringBootApplication

@Import({MyImportBeanDefinitionRegistrar.class})

public class SpringbootEnableApplication {

public static void main(String[] args) {

ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

Jedis jedis = context.getBean(Jedis.class);

System.out.println(jedis);

jedis.set(“name”,“itbluebox2”);

String name = jedis.get(“name”);

System.out.println(name);

}

@Bean

public Jedis jedis(){

return new Jedis(“localhost”,6379);

}

}

  • 运行测试

在这里插入图片描述

在这里插入图片描述

没有输出RedisAutoConfiguration.....证明RedisAutoConfiguration@ConditionalOnMissingBean(name = "jedis")生效的

二、SpringBoot监听机制


1、Java的监听机制

SpringBoot的监听机制,其实是对Java提供的事件监听机制的封装。Java中的事件监听机制定义了以下几个角色:

  • 事件: Event,继承java.util.EventObject类的对象

  • 事件源:Source,任意对象Object

  • 监听器:Listener,实现java.util.EventListener接口的对象

2、SpringBoot 监听机制

SpringBoot在项目启动时,会对几个监听器进行回调,我们可以实现这些监听器接口,在项目启动时完成—些操作。

ApplicationContextInitializerSpringApplicationRunListenerCommandLineRunnerApplicationRunner

3、代码演示

(1)创建模块

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 创建包结构

在这里插入图片描述

(2)创建对应的监听对象
  • 创建MyApplicationContextInitializer

在这里插入图片描述

在这里插入图片描述

package cn.itbluebox.springbootlistener.listener;

import org.springframework.context.ApplicationContextInitializer;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.stereotype.Component;

public class MyApplicationContextInitializer implements ApplicationContextInitializer {

@Override

public void initialize(ConfigurableApplicationContext applicationContext) {

System.out.println(“ApplicationContextInitializer…initialize”);

}

}

  • 创建MySpringApplicationRunListener

在这里插入图片描述

在这里插入图片描述

package cn.itbluebox.springbootlistener.listener;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.SpringApplicationRunListener;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.core.env.ConfigurableEnvironment;

import org.springframework.stereotype.Component;

public class MySpringApplicationRunListener implements SpringApplicationRunListener {

public MySpringApplicationRunListener(SpringApplication application, String[] args) {

}

@Override

public void starting() {

System.out.println(“starting…项目启动中”);

}

@Override

public void environmentPrepared(ConfigurableEnvironment environment) {

System.out.println(“environmentPrepared…环境对象开始准备”);

}

@Override

public void contextPrepared(ConfigurableApplicationContext context) {

System.out.println(“contextPrepared…上下文对象开始准备”);

}

@Override

public void contextLoaded(ConfigurableApplicationContext context) {

System.out.println(“contextLoaded…上下文对象开始加载”);

}

@Override

public void started(ConfigurableApplicationContext context) {

System.out.println(“started…上下文对象加载完成”);

}

@Override

public void running(ConfigurableApplicationContext context) {

System.out.println(“running…项目启动完成,开始运行”);

}

@Override

public void failed(ConfigurableApplicationContext context, Throwable exception) {

System.out.println(“failed…项目启动失败”);

}

}

  • 创建MyCommandLineRunner

在这里插入图片描述

在这里插入图片描述

package cn.itbluebox.springbootlistener.listener;

import org.springframework.boot.CommandLineRunner;

import org.springframework.stereotype.Component;

import java.util.Arrays;

public class MyCommandLineRunner implements CommandLineRunner {

@Override

public void run(String… args) throws Exception {

System.out.println(“CommandLineRunner…run”);

}

}

  • 创建MyApplicationRunner

在这里插入图片描述

在这里插入图片描述

package cn.itbluebox.springbootlistener.listener;

import org.springframework.boot.ApplicationArguments;

import org.springframework.boot.ApplicationRunner;

import org.springframework.stereotype.Component;

import java.util.Arrays;

/**

  • 当项目启动后执行run方法。

*/

public class MyApplicationRunner implements ApplicationRunner {

@Override

public void run(ApplicationArguments args) throws Exception {

System.out.println(“ApplicationRunner…run”);

}

}

  • 完善上述四个并将其注册到Spring容器当中

MyApplicationContextInitializer

在这里插入图片描述

package cn.itbluebox.springbootlistener.listener;

import org.springframework.context.ApplicationContextInitializer;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.stereotype.Component;

@Component

public class MyApplicationContextInitializer implements ApplicationContextInitializer {

@Override

public void initialize(ConfigurableApplicationContext applicationContext) {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

文末

我将这三次阿里面试的题目全部分专题整理出来,并附带上详细的答案解析,生成了一份PDF文档

  • 第一个要分享给大家的就是算法和数据结构

网易严选Java开发三面面经:HashMap+JVM+索引+消息队列

  • 第二个就是数据库的高频知识点与性能优化

网易严选Java开发三面面经:HashMap+JVM+索引+消息队列

  • 第三个则是并发编程(72个知识点学习)

网易严选Java开发三面面经:HashMap+JVM+索引+消息队列

  • 最后一个是各大JAVA架构专题的面试点+解析+我的一些学习的书籍资料

网易严选Java开发三面面经:HashMap+JVM+索引+消息队列

还有更多的Redis、MySQL、JVM、Kafka、微服务、Spring全家桶等学习笔记这里就不一一列举出来

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
b728711a.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6JOd55uS5a2QaXRibHVlYm94,size_20,color_FFFFFF,t_70,g_se,x_16)

package cn.itbluebox.springbootlistener.listener;

import org.springframework.boot.ApplicationArguments;

import org.springframework.boot.ApplicationRunner;

import org.springframework.stereotype.Component;

import java.util.Arrays;

/**

  • 当项目启动后执行run方法。

*/

public class MyApplicationRunner implements ApplicationRunner {

@Override

public void run(ApplicationArguments args) throws Exception {

System.out.println(“ApplicationRunner…run”);

}

}

  • 完善上述四个并将其注册到Spring容器当中

MyApplicationContextInitializer

在这里插入图片描述

package cn.itbluebox.springbootlistener.listener;

import org.springframework.context.ApplicationContextInitializer;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.stereotype.Component;

@Component

public class MyApplicationContextInitializer implements ApplicationContextInitializer {

@Override

public void initialize(ConfigurableApplicationContext applicationContext) {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-EX3PfNNc-1712602862674)]

[外链图片转存中…(img-lpOghJ2G-1712602862674)]

[外链图片转存中…(img-xPkBo8TH-1712602862675)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

文末

我将这三次阿里面试的题目全部分专题整理出来,并附带上详细的答案解析,生成了一份PDF文档

  • 第一个要分享给大家的就是算法和数据结构

[外链图片转存中…(img-sLjBQ7u9-1712602862675)]

  • 第二个就是数据库的高频知识点与性能优化

[外链图片转存中…(img-E5ryHndy-1712602862675)]

  • 第三个则是并发编程(72个知识点学习)

[外链图片转存中…(img-rSZsLXbk-1712602862675)]

  • 最后一个是各大JAVA架构专题的面试点+解析+我的一些学习的书籍资料

[外链图片转存中…(img-EhO9MIDH-1712602862675)]

还有更多的Redis、MySQL、JVM、Kafka、微服务、Spring全家桶等学习笔记这里就不一一列举出来

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值