注意是隻使用了@EnableAutoConfiguration,默認是隻掃描這一個咱們自定義的類到bean中。不含子包和本包。下一篇咱們分析緣由。git
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方法。web
// 第一步 SpringApplication application = new SpringApplication(SpringBootApplication05.class); // 第二步 ConfigurableApplicationContext context = application.run(args);
建立對象後 返回SpringApplication對象,咱們來分析此對象有用的幾個方法。spring
實例化SpringApplication對象springboot
public SpringApplication(Class<?>... primarySources) { this(null, primarySources); }
經過構造方法 咱們發現是能夠傳遞多個class對象,即除了傳遞啓動類之外,咱們也能夠傳遞其餘Class對象 能夠是@configuration註解包含的對象 固然也能夠是其餘註解類型的。app
咱們能夠將UserService.class交給SpringBoot進行管理ide
SpringApplication application2=new SpringApplication(SpringBootApplication05_01.class,UserService.class);
此種方式等價於構造方法方式。可實現多個class注入。spring-boot
Set primarySources = new LinkedHashSet<>(Arrays.asList(SpringBootApplication05_01.class,UserService.class)); application.addPrimarySources(primarySources);
設置附加的Profiles,我的理解等價於Spring.profiles.active,使用方式以下post
//默認執行application-dev.yml文件中的配置 application.setAdditionalProfiles("dev");
設置Banner工做模式 可關閉,也能夠在控制檯和log中,使用方式以下ui
application.setBannerMode(Banner.Mode.CONSOLE);// 控制檯輸出 application.setBannerMode(Banner.Mode.OFF);// 關閉輸出
設置banner樣式,也能夠經過spring.banner.location=https://gitee.com/bgt0314/mix_learn/raw/master/SpringBootDemo/src/main/resources/my.txt 來配置。this
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變成上述的形式。
設置啓動日誌,默認true
/** * 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);
添加ApplicationContextInitializer類型的實例,在ConfigurableApplicationContext刷新以前初始化Spring ConfigurableApplicationContext的回調接口
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()); } });
添加監聽事件
// 能夠監聽 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後咱們能夠操做的方法。
// 默認是以下 固然也能夠轉換成其餘context好比logstart裏面打印的AnnotationConfigServletWebServerApplicationContext ConfigurableApplicationContext context = application.run(args);
@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); }
根據class獲取bean對象,是個集合
// 獲取全部的User的bean實例 System.out.println(context.getBeansOfType(User.class));
根據BeanName獲取bean對象,是單個對象
// 獲取beanName是createUser的bean對象 System.out.println("createUser-----------------"+context.getBean("createUser"));
根據class獲取bean對象,是單個對象,當有多個是須要使用@Primary
User defaultUser = context.getBean(User.class); // 此例子是獲取到的createUser2對象 System.out.println("User.class-----------------"+defaultUser);
獲取已經裝載的bean對象
String[] BeanDefinitionNames = context.getBeanDefinitionNames(); System.out.print("包含的bean對象:"); for (String name:BeanDefinitionNames){ System.out.println(name+","); }
獲取應用名稱
String applicationName = context.getApplicationName(); System.out.println("applicationName:"+applicationName);
獲取bean數量
int beannum=context.getBeanDefinitionCount(); System.out.println("bean的數量:"+beannum);
發佈ApplicationEvent 自定義的事件須要在此處發佈
// 發佈自定義事件 context.publishEvent(new MyApplicationEvent(new Object()));
添加監聽
// 等同上述 applicationListener context.addApplicationListener(applicationListener);
添加BeanFactoryPostProcessor,可是此處無效,
// bean工廠加載完畢的後置通知 可是在這裏無效 實現方式參照 createBeanDefinitionRegistryPost()方法 context.addBeanFactoryPostProcessor(new BeanFactoryPostProcessor() { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("--------------------------------"+beanFactory.getBeanDefinitionCount()); } });
有效實現方式以下
@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咱們已經演示完畢。