前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >原 SpringBoot 2.0 系列00

原 SpringBoot 2.0 系列00

作者头像
石奈子
发布2018-06-13 15:32:12
4370
发布2018-06-13 15:32:12
举报
文章被收录于专栏:石奈子的Java之路

SpringBoot 2.0 系列005 --启动实战之SpringApplication应用

注意是只使用了@EnableAutoConfiguration,默认是只扫描这一个我们自定义的类到bean中。不含子包和本包。下一篇我们分析原因。

代码语言:javascript
复制
package hello;

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;

@Controller
@EnableAutoConfiguration
public class SampleController {

    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "Hello World!";
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(SampleController.class, args);
    }
}
  • 拆分步骤

在之前的文章中我们提到,SB启动分为两步,new SpringApplication对象和执行run方法。

代码语言:javascript
复制
// 第一步
        SpringApplication application = new SpringApplication(SpringBootApplication05.class);
        // 第二步 
        ConfigurableApplicationContext context = application.run(args);

第一步

创建对象后 返回SpringApplication对象,我们来分析此对象有用的几个方法。

构造方法

实例化SpringApplication对象

代码语言:javascript
复制
public SpringApplication(Class<?>... primarySources) {
		this(null, primarySources);
	}

通过构造方法 我们发现是可以传递多个class对象,即除了传递启动类以外,我们也可以传递其他Class对象 可以是@configuration注解包含的对象 当然也可以是其他注解类型的。

  • 示例

我们可以将UserService.class交给SpringBoot进行管理

代码语言:javascript
复制
SpringApplication application2=new SpringApplication(SpringBootApplication05_01.class,UserService.class);

addPrimarySources 方法

此种方式等价于构造方法方式。可实现多个class注入。

代码语言:javascript
复制
Set primarySources = new LinkedHashSet<>(Arrays.asList(SpringBootApplication05_01.class,UserService.class));
            application.addPrimarySources(primarySources);

setAdditionalProfiles

设置附加的Profiles,个人理解等价于Spring.profiles.active,使用方式如下

代码语言:javascript
复制
//默认执行application-dev.yml文件中的配置
  application.setAdditionalProfiles("dev");

setBannerMode

设置Banner工作模式 可关闭,也可以在控制台和log中,使用方式如下

代码语言:javascript
复制
application.setBannerMode(Banner.Mode.CONSOLE);// 控制台输出
application.setBannerMode(Banner.Mode.OFF);// 关闭输出

setBanner

设置banner样式,也可以通过spring.banner.location=https://gitee.com/bgt0314/mix_learn/raw/master/SpringBootDemo/src/main/resources/my.txt 来配置。

代码语言:javascript
复制
application.setBanner(new Banner() {
                @Override
                public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {
                    out.println("////////////////////////////////////////////////////////////////////\n" +
                            "//                          _ooOoo_                               //\n" +
                            "//                         o8888888o                              //\n" +
                            "//                         88\" . \"88                              //\n" +
                            "//                         (| ^_^ |)                              //\n" +
                            "//                         O\\  =  /O                              //\n" +
                            "//                      ____/`---'\\____                           //\n" +
                            "//                    .'  \\\\|     |//  `.                         //\n" +
                            "//                   /  \\\\|||  :  |||//  \\                        //\n" +
                            "//                  /  _||||| -:- |||||-  \\                       //\n" +
                            "//                  |   | \\\\\\  -  /// |   |                       //\n" +
                            "//                  | \\_|  ''\\---/''  |   |                       //\n" +
                            "//                  \\  .-\\__  `-`  ___/-. /                       //\n" +
                            "//                ___`. .'  /--.--\\  `. . ___                     //\n" +
                            "//              .\"\" '<  `.___\\_<|>_/___.'  >'\"\".                  //\n" +
                            "//            | | :  `- \\`.;`\\ _ /`;.`/ - ` : | |                 //\n" +
                            "//            \\  \\ `-.   \\_ __\\ /__ _/   .-` /  /                 //\n" +
                            "//      ========`-.____`-.___\\_____/___.-`____.-'========         //\n" +
                            "//                           `=---='                              //\n" +
                            "//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //\n" +
                            "//         佛祖保佑       永无BUG     永不修改                    //\n" +
                            "//                                                    ricky制作   //\n" +
                            "////////////////////////////////////////////////////////////////////");
                }
            });

设置完毕后,springbootbanner变成上述的形式。

setLogStartupInfo

设置启动日志,默认true

代码语言:javascript
复制
/**
 *
 true的时候会多出下面两行日志  关闭后不打印这两行
 2018-05-17 10:24:50.585  INFO 20536 --- [           main] com.ricky01.SpringBootApplication05_01   : The following profiles are active: dev
 2018-05-17 10:24:50.697  INFO 20536 --- [           main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@cd3fee8: startup date [Thu May 17 10:24:50 CST 2018]; root of context hierarchy

 */
application.setLogStartupInfo(false);

addInitializers

添加ApplicationContextInitializer类型的实例,在ConfigurableApplicationContext刷新之前初始化Spring ConfigurableApplicationContext的回调接口

代码语言:javascript
复制
application.addInitializers(new ApplicationContextInitializer<GenericApplicationContext>() {
                @Override
                public void initialize(GenericApplicationContext ctx) {
                    // 可以根据上下文提前设置一些参数
                    ctx.registerBean("rickyDefault",User.class,User::new); // 注入默认UserBean对象
                    ConfigurableListableBeanFactory beanFactory = ctx.getBeanFactory();
                    System.out.println(ctx.getBeanDefinitionCount());
                    ConfigurableEnvironment environment = ctx.getEnvironment();
                    System.out.println("ApplicationContextInitializer::::::::::"+environment.getPropertySources());

                }
            });

addListeners

添加监听事件

代码语言:javascript
复制
// 可以监听 ApplicationEvent的子类的事件  比如context刷新和关闭等等
            // 在application.properties中配置context.listener.classes=xxx 或者
            /**
             *
             @Component
            public class XXClass{
                @EventListener
                public void onApplicationEvent(ContextRefreshedEvent event) {
                System.out.println("哎哟 等价 我监听到了呢");
                }
            }
             */

            // 跟setListeners类似

        ApplicationListener<ContextRefreshedEvent> applicationListener = new ApplicationListener<ContextRefreshedEvent>() {

            @Override
            public void onApplicationEvent(ContextRefreshedEvent event) {
                System.out.println("哎哟,我是这个时候刷新完了:" + event.getTimestamp() + ",刷新后你要干啥呢?");
            }
        };
        application.addListeners(applicationListener);

第二步

run后我们可以操作的方法。

代码语言:javascript
复制
// 默认是如下  当然也可以转换成其他context比如logstart里面打印的AnnotationConfigServletWebServerApplicationContext
 ConfigurableApplicationContext context = application.run(args);
  • 前提,我们在启动类中注入如下对象
代码语言:javascript
复制
@Bean
    public User createUser(){
        return new User("ricky",10);
    }
    @Bean
    @Primary // 当使用类获取bean实例的时候使用
    public User createUser2(){
        return new User("ricky02",10);
    }

    @Bean("rickyUser") // 指定bean的名称
    public User createUser3(){
        return new User("ricky03",10);
    }
  • context.getBeansOfType

根据class获取bean对象,是个集合

代码语言:javascript
复制
// 获取所有的User的bean实例
System.out.println(context.getBeansOfType(User.class));
  • context.getBean(String beanName)

根据BeanName获取bean对象,是单个对象

代码语言:javascript
复制
// 获取beanName是createUser的bean对象
            System.out.println("createUser-----------------"+context.getBean("createUser"));
  • context.getBean(Class requiredType)

根据class获取bean对象,是单个对象,当有多个是需要使用@Primary

代码语言:javascript
复制
User defaultUser = context.getBean(User.class);
// 此例子是获取到的createUser2对象
            System.out.println("User.class-----------------"+defaultUser);
  • context.getBeanDefinitionNames()

获取已经装载的bean对象

代码语言:javascript
复制
String[] BeanDefinitionNames = context.getBeanDefinitionNames();
            System.out.print("包含的bean对象:");
           for (String name:BeanDefinitionNames){
               System.out.println(name+",");
           }
  • context.getApplicationName()

获取应用名称

代码语言:javascript
复制
String applicationName = context.getApplicationName();
            System.out.println("applicationName:"+applicationName);
  • context.getBeanDefinitionCount()

获取bean数量

代码语言:javascript
复制
int beannum=context.getBeanDefinitionCount();
            System.out.println("bean的数量:"+beannum);
  • context.publishEvent

发布ApplicationEvent 自定义的事件需要在此处发布

代码语言:javascript
复制
// 发布自定义事件
            context.publishEvent(new MyApplicationEvent(new Object()));
  • context.addApplicationListener

添加监听

代码语言:javascript
复制
// 等同上述 applicationListener
             context.addApplicationListener(applicationListener);
  • context.addBeanFactoryPostProcessor

添加BeanFactoryPostProcessor,但是此处无效,

代码语言:javascript
复制
// bean工厂加载完毕的后置通知  但是在这里无效  实现方式参照 createBeanDefinitionRegistryPost()方法
            context.addBeanFactoryPostProcessor(new BeanFactoryPostProcessor() {
                @Override
                public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
                    System.out.println("--------------------------------"+beanFactory.getBeanDefinitionCount());
                }
            });

有效实现方式如下

代码语言:javascript
复制
@Bean
    public  BeanDefinitionRegistryPostProcessor createBeanDefinitionRegistryPost(){
        return new BeanDefinitionRegistryPostProcessor() {
            @Override
            public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
//                    BeanDefinitionBuilder builder=BeanDefinitionBuilder.rootBeanDefinition(User.class);
//                    registry.registerBeanDefinition("userBeanPost",builder.getBeanDefinition());

                System.out.println("----------#######postProcessBeanDefinitionRegistry------------------"+registry.getBeanDefinitionCount());
                RootBeanDefinition user=new RootBeanDefinition(User.class);
                registry.registerBeanDefinition("userBeanPost",user);
            }

            @Override
            public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
                System.out.println("----------#######postProcessBeanFactory------------------"+beanFactory.getBeanDefinitionCount());
            }
        };
    }
  • context.close()

关闭应用。程序结束。

至此,常用的context我们已经演示完毕。

演示项目地址,欢迎fork和star

码云:SpringBootLearn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • SpringBoot 2.0 系列005 --启动实战之SpringApplication应用
    • 第一步
      • 构造方法
      • addPrimarySources 方法
      • setAdditionalProfiles
      • setBannerMode
      • setBanner
      • setLogStartupInfo
      • addInitializers
      • addListeners
    • 第二步
      • 演示项目地址,欢迎fork和star
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档