SpringBoot自动配置
condition-1
Condition是Spring4.0后引入的条件化配置接口,通过实现Condition接口可以完成有条件的加载相应的Bean
@Conditional要配和Condition的实现类(ClassCondition)进行使用
- ClassCondition
public class ClassCondition implements Condition {    /**     *     * @param context 上下文对象。用于获取环境,IOC容器,ClassLoader对象     * @param metadata 注解元对象。 可以用于获取注解定义的属性值     * @return     */    @Override    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {              //1.需求: 导入Jedis坐标后创建Bean        //思路:判断redis.clients.jedis.Jedis.class文件是否存在        boolean flag = true;        try {            Class> cls = Class.forName("redis.clients.jedis.Jedis");        } catch (ClassNotFoundException e) {            flag = false;        }        return flag;          }}UserConfig
@Configurationpublic class UserConfig {    @Bean    @Conditional(ClassCondition.class)    public User user(){        return new User();    }}测试
@SpringBootApplicationpublic class SpringbootConditionApplication {    public static void main(String[] args) {        //启动SpringBoot的应用,返回Spring的IOC容器        ConfigurableApplicationContext context = SpringApplication.run(SpringbootConditionApplication.class, args);        Object user = context.getBean("user");        System.out.println(user);    }}依赖
                    redis.clients            jedis        这一段是判断jedis这个依赖要有没有来决定是否生成对应的bean对象,需要实现Condition接口,重写mathes方法,返回false则不创建对象,在这个user对象上加入注解@Conditioal(xxx.class)来实现判断。
Condition-2
需求:将类的判断定义为动态的。判断哪个字节码文件存在可以动态指定。
自定义条件注解类
import org.springframework.context.annotation.Conditional;import java.lang.annotation.*;@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documented@Conditional(ClassCondition.class)public @interface ConditionOnClass {    String[] value();}**注意:**此处@ConditionOnClass为自定义注解
@Configurationpublic class UserConfig {    @Bean    //@Conditional(ClassCondition.class)    @ConditionOnClass("com.alibaba.fastjson.JSON")    public User user(){        return new User();    }    @Bean    @ConditionalOnProperty(name = "itcast",havingValue = "ii")    public User user2(){        return new User();    }}测试User对象的创建
@SpringBootApplicationpublic class SpringbootConditionApplication {    public static void main(String[] args) {        //启动SpringBoot的应用,返回Spring的IOC容器        ConfigurableApplicationContext context = SpringApplication.run(SpringbootConditionApplication.class, args);        Object user = context.getBean("user");        System.out.println(user);    }}- 自定义注解其实是对原来注解的封装
- @ConditionalOnProperty是看配置文件中是否存在一个这样的键值对,如果有则创建、
 -执行顺序:
 @ConditionOnClass的value值,找到依赖和自定义注解类,通过自定义注解类上的class找到具体要执行的代码,决定是否生成bean对象。
查看条件注解源码
SpringBoot 提供的常用条件注解:
ConditionalOnProperty:判断配置文件中是否有对应属性和值才初始化Bean
ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean
ConditionalOnMissingBean:判断环境中没有对应Bean才初始化Bean
SpringBoot自动配置-切换内置web服务器
查看继承关系图
排除Tomcat
pom文件中的排除依赖效果
             org.springframework.boot            spring-boot-starter-web                                                            spring-boot-starter-tomcat                    org.springframework.boot                                                                spring-boot-starter-jetty            org.springframework.boot        SpringBoot自动配置-Enable注解原理
SpringBoot不能直接获取在其他工程中定义的Bean
演示代码:
springboot-enable工程
/** * @ComponentScan 扫描范围:当前引导类所在包及其子包 * * com.itheima.springbootenable * com.itheima.config * //1.使用@ComponentScan扫描com.itheima.config包 * //2.可以使用@Import注解,加载类。这些类都会被Spring创建,并放入IOC容器 * //3.可以对Import注解进行封装。 *///@ComponentScan("com.itheima.config")//@Import(UserConfig.class)@EnableUser@SpringBootApplicationpublic 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); }}pom中引入springboot-enable-other
               com.itheima          springboot-enable-other            0.0.1-SNAPSHOT      springboot-enable-other工程
UserConfig
@Configurationpublic class UserConfig {    @Bean  public User user() {        return new User();  }}EnableUser注解类
import org.springframework.context.annotation.Import;import java.lang.annotation.*;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(UserConfig.class)public @interface EnableUser {myImportSelector
 public class MyImportSelector implements ImportSelector {      @Override      public String[] selectImports(AnnotationMetadata importingClassMetadata) {          return new String[]{"com.itheima.domain.User", "com.itheima.domain.Role"};      }  }ImportBeanDefinitionRegistrar 实现类
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {    @Override    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();        registry.registerBeanDefinition("user", beanDefinition);    }}
Import4中用法:
1.导入Bean
- 2.导入配置类
- 3.导入ImportSelector的实现类。
- 4.导入ImportBeanDefinitionRegistrar实现类
自定义依赖
SpringBoot事件监听
Java中的事件监听机制定义了以下几个角色:
①事件:Event,继承 java.util.EventObject 类的对象
②事件源:Source ,任意对象Object
③监听器:Listener,实现 java.util.EventListener 接口 的对象
SpringBoot 在项目启动时,会对几个监听器进行回调,我们可以实现这些监听器接口,在项目启动时完成一些操作。
- ApplicationContextInitializer、
- SpringApplicationRunListener、
- CommandLineRunner、
- ApplicationRunner自定义监听器的启动时机:MyApplicationRunner和MyCommandLineRunner都是当项目启动后执行,使用@Component放入容器即可使用
MyApplicationRunner
/** * 当项目启动后执行run方法。 */@Componentpublic class MyApplicationRunner implements ApplicationRunner {    @Override    public void run(ApplicationArguments args) throws Exception {        System.out.println("ApplicationRunner...run");        System.out.println(Arrays.asList(args.getSourceArgs()));    }} MyCommandLineRunner
@Componentpublic class MyCommandLineRunner implements CommandLineRunner {    @Override    public void run(String... args) throws Exception {        System.out.println("CommandLineRunner...run");        System.out.println(Arrays.asList(args));    }}MyApplicationContextInitializer的使用要在resource文件夹下添加META-INF/spring.factories
org.springframework.context.ApplicationContextInitializer=com.itheima.springbootlistener.listener.MyApplicationContextInitializer@Componentpublic class MyApplicationContextInitializer implements ApplicationContextInitializer {    @Override    public void initialize(ConfigurableApplicationContext applicationContext) {        System.out.println("ApplicationContextInitializer....initialize");    }}MySpringApplicationRunListener的使用要添加构造器(最屌)
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...项目启动失败");    }}Springboot Admin图形化管理平台
以后可以server打成jar包,然后其他服务通过端口去绑定注册
Springboot 部署
部署有两个方式
1.通过maven或者命令直接打成jar包,通过cmd,直接运行jar包即可
2.通过war包启动,pom.xml里加入war,主文件继承SpringBootServletInitializer,重写方法,即可
SpringBoot流程分析
初始化
- 配置启动引导类(判断是否有启动主类)
- 判断是否是Web环境
- 获取初始化类、监听器类
run
- 启动计时器
- 执行监听器
- 准备环境
- 打印banner:可以resource下粘贴自定义的banner
5.创建context
- refreshContext(context);
- 执行refreshContext方法后才真正创建Bean
最后给个banner
1
${AnsiColor.BRIGHT_GREEN}$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$${AnsiColor.BRIGHT_YELLOW}$$                                _.ooOoo._                               $$${AnsiColor.BRIGHT_RED}$$                               o888888888o                              $$${AnsiColor.BRIGHT_CYAN}$$                               88"  .  "88                              $$${AnsiColor.BRIGHT_MAGENTA}$$                               (|  ^_^  |)                              $$${AnsiColor.BRIGHT_GREEN}$$                               O   =   /O                              $$${AnsiColor.BRIGHT_RED}$$                            ____/`-----'____                           $$${AnsiColor.BRIGHT_CYAN}$$                          .'  |       |$$  `.                         $$${AnsiColor.BRIGHT_MAGENTA}$$                         /  |||   :   |||$$                          $$${AnsiColor.BRIGHT_GREEN}$$                        /  _|||||  -:-  |||||-                         $$${AnsiColor.BRIGHT_YELLOW}$$                        |   |    -   $$/ |   |                       $$${AnsiColor.BRIGHT_GREEN}$$                        | _|  ''-----/''  |   |                       $$${AnsiColor.BRIGHT_YELLOW}$$                          .-___  `-`  ____/-. /                       $$${AnsiColor.BRIGHT_CYAN}$$                      ___`. .'   /--.--   `. . ___                     $$${AnsiColor.BRIGHT_RED}$$                    ."" '_/____.'  >'"".                  $$${AnsiColor.BRIGHT_GREEN}$$                  | | :  `- `.;`. _ /``;.`/ - ` : | |                 $$${AnsiColor.BRIGHT_YELLOW}$$                     `-.   _ ___ /___ _/   .-` /  /                 $$${AnsiColor.BRIGHT_CYAN}$$            ========`-.____`-._________/____.-`____.-'========         $$${AnsiColor.BRIGHT_MAGENTA}$$                                  `=---='                               $$${AnsiColor.BRIGHT_YELLOW}$$            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        $$${AnsiColor.BRIGHT_GREEN}$$                     佛祖保佑          永无BUG         永不修改         $$${AnsiColor.BRIGHT_YELLOW}$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$${AnsiColor.BRIGHT_YELLOW}2
${AnsiColor.BRIGHT_GREEN}/***${AnsiColor.BRIGHT_YELLOW}*      ┌─┐       ┌─┐ + +${AnsiColor.BRIGHT_GREEN} *   ┌──┘ ┴───────┘ ┴──┐++${AnsiColor.BRIGHT_YELLOW} *   │                 │${AnsiColor.BRIGHT_YELLOW} *   │       ───       │++ + + +${AnsiColor.BRIGHT_BLACK} *   ███████───███████ │+${AnsiColor.BRIGHT_GREEN} *   │                 │+ *   │       ─┴─       │ *   │                 │ *   └───┐         ┌───┘ ${AnsiColor.BRIGHT_GREEN}*       │         │ *       │         │   + + *       │         │ *       │         └──────────────┐ *       │                        │ *       │                        ├─┐ *       │                        ┌─┘ *       │                        │ *       └─┐  ┐  ┌───────┬──┐  ┌──┘  + + + + *         │ ─┤ ─┤       │ ─┤ ─┤ *         └──┴──┘       └──┴──┘  + + + + *                神兽保佑 *               代码无BUG! */版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:
http://blog.csdn.net/m0_46690280/article/details/108567548