1、自定义Condition条件装配
- 自定义条件:
- 1、自定义类实现 Condition 接口
- 2、从写Condition接口中的matches方法
- 返回值 true 表示 注入到容器
- 返回值 false 表示 不注入到容器
- 自定义条件的使用:
- 在配置类或者@Bean方法上------ @Conditional(自定义类.class)
- 或者 直接使用自定义的注解
- 优化:
- 自定义一个注解,还能传入参数的形式
- 案例:
- 当存在某一个注解的时候,才把user注入
public class MyCondition implements Condition {
/**
* @param conditionContext 上下文对象。用于获取环境,IOC容器,ClassLoader对象
* @param annotatedTypeMetadata 注解元对象。 可以用于获取注解定义的属性值
* @return 该方法的返回值为 turn 则把Bean放入容器 false则不放入容器
*/
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//需求:导入jedis坐标的时候,创建bean
//思路:判断redis.clients.jedis.Jedis.class文件是否存在
boolean flag = true;
//获得注解属性值
Map<String, Object> map = annotatedTypeMetadata.getAnnotationAttributes(ConditionOnClass.class.getName());
String[] value = (String[]) map.get("value");
try {
for (String s : value) {
Class<?> cls = Class.forName(s);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
flag=false;
}
return flag;
}
}
ElementType.TYPE, ElementType.METHOD})
(RetentionPolicy.RUNTIME)
(MyCondition.class)
public @interface ConditionOnClass {
String[] value();
}
({
public class MyConfig {
//使用自定义的条件----当存在redis的class的时候,会在容器中创建一个User对象
// @Conditional(MyCondition.class)
("org.springframework.data.redis.RedisSystemException")
public User user(){
return new User();
}
}
//会发现 当容器中有该指定的类的字节码文件的时候,才把user注入
2、切换内置服务器
- 默认是使用Tomcat
- springboot内部集合了很多服务器: tomcat、jetty、netty、undertow
- 切换内置服务器的步骤:
- 1、在spring-boot-starter-web 依赖中排出Tomcat 场景启动器(可以在继承关系图中排除 tomcat依赖)
- 2、引入其他 服务器的 starter
- 案例:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!--排除tomcat依赖-->
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!--引入jetty的依赖-->
<dependency>
<artifactId>spring-boot-starter-jetty</artifactId>
<groupId>org.springframework.boot</groupId>
</dependency>
3、把bean导入spring容器
4、@Import注解的4种使用方式
- 方法一:@Import(User.class)
- 方法二:@Import(UserConfig.class) 直接导入一个配置文件
- 方法三:@Import(XxxxImportSelector.class)
- XxxxImportSelector需要实现ImportSelector接口
- 实现里面selectImports方法,该方法中存放要注入容器的类的全限定类名 的一个数组
public class MyImportSelector implements ImportSelector {
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.example.springbootcondition.pojo.User"};
}
}
- 方法四:@Import(XxxxImportBeanDefinitionRegistrar.class)
- XxxxImportBeanDefinitionRegistrar需要实现ImportBeanDefinitionRegistrar接口
- 实现里面的registerBeanDefinitions方法,在里面指定注入的Bean
- 两个参数:
- AnnotationMetadata 注解元数据,获得注解中传递的参数
- BeanDefinitionRegistry Bean定义注册器,把指定的Bean注册到容器
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
registry.registerBeanDefinition("user", beanDefinition);
}
}
5、@EnbaleAutoConfiguration详解
- 该注解是springboot实现自动配置的核心注解,是组成入口注解的 的其中一个
- 该注解是由 @AutoConfigurationPackage +@Import({AutoConfigurationImportSelector.class})两个注解组成
- @AutoConfigurationPackage 指定了默认扫描包的规则
- @Import({AutoConfigurationImportSelector.class}) 指定自动装配哪些类
- AutoConfigurationImportSelector类返回一个string[] ,指定要自动配置的类
- string[] 中的值 在当前系统下所有的 META-INF/spring.factories 文件中读取
6、自定义starter 案例
自定义一个Redis的starter
1、Redis-spring-boot-starter 模块 引入Redis-spring-boot-starter-autoconfigure
-------Redis-spring-boot-starter 模块的配置文件------------------
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.zy</groupId>
<artifactId>Redis-spring-boot-starter-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
2、Redis-spring-boot-starter-autoconfigure 模块
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
配置封装
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;
}
}
(
RerdisAutoConfiguration
(RedisProperties.class)
public class RerdisAutoConfiguration {
public Jedis jedis(RedisProperties redisProperties){
return new Jedis(redisProperties.getHost(), redisProperties.getPort());
}
}
开源网站上很多自定义的starter
7、SpringBoot监听接口
- 在监听接口做一些我们常用的预热的事情---在启动springboot启动的各个阶段要做什么事情
- SpringBoot 在项目启动时,会对几个监听器进行回调,我们可以实现这些监听器接口,在项目启动时完成一些操作。
- ApplicationContextInitializer 监听器
- SpringApplicationRunListener 监听器
- CommandLineRunner 监听器
- ApplicationRunner 监听器
作用:springboot对外暴露了一些监听接口,围绕springBoot工程启动生命周期,做自定义的业务处理
具体监控接口:
ApplicationContextInitializer、SpringApplicationRunListener
特点:
spring容器创建过程中执行
需要配置才能生效META-INF/spring.factories
CommandLineRunner、ApplicationRunner
特点:
spring容器创建后执行;
不需要配置(只需要在类上添加注解即可),实现后项目启动直接执行
8、SpringBoot Banner
把图标文件banner.txt放入resources目录下即可
注意:图标名称必须为“banner.txt”
9、springboot的部署--jar|war
- 注意:这里的jar和war并不是 是不是web项目
- 打war的原因:
- 可以使用自己的tomcat,可以对自己的服务器进行各种的调优设置
- 使用springboot内部的tomcat,只能通过配置文件进行简单的优
- jar包(官方推荐)---使用内置的tomcat
- 1、写好的springboot项目 ,使用maven插件进行打包
- 2、找到打包后的jar文件
- 3、使用 java -jar xxx 就可以运行打好的jar包
- war---使用自己的tomcat
- 打包方式为war后,要想被Tomcat识别到,
- 1、启动类extends SpringBootServletInitializer
- 2、启动类 重写configure方法
- 3、进行打包
public class SpringbootDeployApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(SpringbootDeployApplication.class, args);
}
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(SpringbootDeployApplication.class);
}
}
- 4、使用:放我我们本地的tomcat上的webapps文件夹中,启动服务器,访问就可以(注意访问路径)