Springboot在调用获取容器路径名称applicationContext.getApplicationName()的时候,返回为空问题解决

最近由于公司项目抽出一个钉钉提醒的功能,上面需要添加某个模块的路径名字以及对应的方法名字。

类似于这种:

【本地环境】-----【模块1】-----【TestController.test()】---- 订单123456,请求上游失败。

类似于这种提醒。

这个问题就出在了获取模块路径名字的时候,因为自己之前有一个获取spring容器的工具类

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
public class SpringContextUtils implements ApplicationContextAware {


    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext arg0)
            throws BeansException {
        applicationContext = arg0;
    }

    /**
     * 获取applicationContext对象
     * @return
     */
    public static ApplicationContext getApplicationContext(){
        return applicationContext;
    }

    /**
     * 根据bean的id来查找对象
     * @param id
     * @return
     */
    public static Object getBeanById(String id){
        return applicationContext.getBean(id);
    }

    /**
     * 根据bean的class来查找对象
     * @param c
     * @return
     */
    public static Object getBeanByClass(Class c){
        return applicationContext.getBean(c);
    }

    /**
     * 根据bean的class来查找所有的对象(包括子类)
     * @param c
     * @return
     */
    public static Map getBeansByClass(Class c){
        return applicationContext.getBeansOfType(c);
    }

    /**
     * 获取ApplicationName
     */
    public static String getApplicationName() {
        return getApplicationContext().getApplicationName();
    }


    /**
     * 获取spring.profiles.active
     */
    public static String getActiveProfile() {
        return getApplicationContext().getEnvironment().getActiveProfiles()[0];
    }
}

可以直接获取到容器的对象applicationContext,所以我就添加了一个公用方法getApplicationName()来获取对应的applicationName,本以为不会出什么问题,因为在我的模块里好多地方都用了,都能够获取到正常的模块路径名称,之后没有什么异常空字符串提示。但是换到其他同事的模块之后,发现获取不到他的模块路径名称,这个让我很费解,于是去查了一下这个项目模块获取路径名称的过程。

发现当同事调用

getApplicationName()

的时候会请求到

AbstractApplicationContext类里的getApplicationName()方法

而在我的项目模块里会请求到

AbstractRefreshableWebApplicationContext类里的getApplicationName()方法

大家在这里或许一眼看出来这俩请求的区别了吧?

对的!我的这里是有web容器的,而同事那里没有web容器

大家如果还不确定,可以在启动的时候,看一下setApplicationContext()方法里注入的是什么类就一目了然了

同事的注入类为:AnnotationConfigApplicationContext

我的注入类为:AnnotationConfigEmbeddedWebApplicationContext

这样更清晰了吧,AnnotationConfigEmbeddedWebApplicationContextspringboot默认的web启动容器。

所以当调用getApplicationName()时请求的目标类不一样,因为同事的模块环境不是web环境,所以获取不到对应的项目模块路径名字了,只需要将对应的项目模块添加为web环境就可以获取到对应的applicationName路径名称了。

注意:由于我们共用的pom文件里包含了web环境,同事这边把springboot的启动方式改成web方式启动以后就好了,大家没必要都这样改,可以根据自己公司的项目需求将web环境加上,就可以使用web容器获取对应的项目路径名称了(server:context-path:)

 


版权声明:本文为mr_yuxuan原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。