spring boot 的 ApplicationContext 及 getbean

在spring中,我们通过如下代码取得一个spring托管类:

  1. ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");  
  2. ac.getBean("beanId"); 

在spring boot中,我参考了如下三篇文章:


让非Spring管理的类获得一个Bean

http://blog.sina.com.cn/s/blog_72ef7bea0102wcvk.htmlblog.sina.com.cn/s/blog_72ef7bea0102wcvk.html


Spring Boot普通类调用bean

http://blog.csdn.net/u014695188/article/details/52396880


SpringBoot-获取上下文

http://www.2cto.com/kf/201701/582935.html


做了一些实践。


首先,我们需要一个媒介,来取得AppicationContext——SpringUtil

这个类有两种方式:

1. 实现ApplicationContextAware接口

@Component
public class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext = null;
// 非@import显式注入,@Component是必须的,且该类必须与main同包或子包
    // 若非同包或子包,则需手动import 注入,有没有@Component都一样
    // 可复制到Test同包测试

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if(SpringUtil.applicationContext == null){
            SpringUtil.applicationContext  = applicationContext;
        }
        System.out.println("---------------com.ilex.jiutou.util.Test.Main.SubPackage.SpringUtil---------------");
    }

    //获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //通过name获取 Bean.
    public static Object getBean(String name){
        return getApplicationContext().getBean(name);

    }

    //通过class获取Bean.
    public static <T> T getBean(Class<T> clazz){
        return getApplicationContext().getBean(clazz);
    }

    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name,Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }

}


需要被spring注入,覆写setApplicationContext

2. 普通类


//@Component  在不可扫描区域,且不需要注入,作为一个普通的util类
public class SpringUtil{

    private static ApplicationContext applicationContext = null;

    public static void setApplicationContext(ApplicationContext applicationContext){
        if(SpringUtil.applicationContext == null){
            SpringUtil.applicationContext  = applicationContext;
        }

    }

    //获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //通过name获取 Bean.
    public static Object getBean(String name){
        return getApplicationContext().getBean(name);

    }

    //通过class获取Bean.
    public static <T> T getBean(Class<T> clazz){
        return getApplicationContext().getBean(clazz);
    }

    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name,Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }

}


不需要被注入,但需要手动调用

主函数

@SpringBootApplication
@Import(value={UserFooterService.class})
public class Test {
    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Test.class, args);

    //    SpringUtil.setApplicationContext(ctx);  这个对应于AnoStatic

        String[] beanNames =  ctx.getBeanDefinitionNames();
        System.out.println("beanNames个数:"+beanNames.length);
        for(String bn:beanNames){
            System.out.println(bn);
        }

        // 测试加载UserFooterService
        UserFooterService userFooterService = (UserFooterService) SpringUtil.getBean(UserFooterService.class);
        List<Map<String,Object>> list = userFooterService.hotTopic("0", "5");
        System.out.println(list.toString());

        // 测试加载SpringUtil
        SpringUtil springUtil = (SpringUtil)SpringUtil.getBean(SpringUtil.class);
        System.out.println(springUtil);
    }

//    @Bean
//    public SpringUtil springUtil() {
//        return new SpringUtil();
//    }
}


UserFooterService是一个业务类,这里不榕树


建立如下的测试结构:


Main/Test 主函数

AnoStatic/SpringUtil  普通类

Main/SubPackage/SpringUtil 实现ApplicationContextAware,但为主函数子包

NonSubPackage/SpringUtil 实现ApplicationContextAware,但非主函数子包和同包



SpringUtil注入方式有三种,在参考的三篇博客均有说明,在此仅总结:

1. 类与SpringBootApplication同包或子包,此在ComponentScan的扫描范围之内,在类上@Component注解即可,会被自动注入;

2. 无论位置,都可通过在主函数用@import或@bean来手动注入。


第一种SpringUtil方式必须被spring注入,否则会报

Exception in thread "main" java.lang.NullPointerException

at com.ilex.jiutou.util.Test.NonSubPackage.SpringUtil.getBean(SpringUtil.java:40)

at com.ilex.jiutou.util.Test.Main.Test.main(Test.java:34)


表示applicationContext获取失败


第二种方式,SpringUtil可被注入可不被注入

当不注入时,主函数这一段:

        // 测试加载SpringUtil
        SpringUtil springUtil = (SpringUtil)SpringUtil.getBean(SpringUtil.class);
        System.out.println(springUtil);

报错:

No qualifying bean of type [**.Test.AnoStatic.SpringUtil


posted on 2017-04-26 22:07  silyvin  阅读(497)  评论(0编辑  收藏  举报