java获取类包名

Posted

技术标签:

【中文标题】java获取类包名【英文标题】:java get name of package of class 【发布时间】:2016-09-20 08:10:08 【问题描述】:

我有一堆小服务,方便地称为微服务 ;-),它们都有相同的启动行为。它们被安排在包装中 - 每一种都用于一项服务。包命名是这样的:

com.foo.bar.Application

com.foo 是域部分,bar 是实际的服务名称,Application 是我的主要实例类和 main 方法。

现在我想做的是在它们启动时打印出标准化的日志消息,显示用户可以查询的 URL 以获取有关服务的一些信息。根据定义,获取服务信息的 URL 应构造如下:

   IP:PORT/bar/admin/info 

我尝试使用 getClass()... 等获取此 bar.name,但这不起作用。所以我尝试了这个:

LOG.info("Access URLs:\n----------------------------------------------------------\n" +
            "\tLocal: \t\thttp://127.0.0.1:/" + getMyClass() + "/info\n" +
            "\tExternal: \thttp://:/" + getMyClass() + "/info\n----------------------------------------------------------",
                env.getProperty("server.port"),
                InetAddress.getLocalHost().getHostAddress(),
                env.getProperty("server.port")
        );

 /**
     * Get the name of the application class as a static value, so we can show it in the log
     */
    public static final Class[] getClassContext() 
        return new SecurityManager() 
            protected Class[] getClassContext()return super.getClassContext();
        .getClassContext();
    ;
    public static final Class getMyClass()  return getClassContext()[2];

但正如您可能已经猜到的那样,这打印出来的东西太多了:

class com.foo.bar.Application

我最想得到的是

bar

我怎样才能做到这一点???

顺便说一句,我正在使用 Java 8 和 Spring boot - 如果有帮助的话

最好的问候,

克里斯

【问题讨论】:

【参考方案1】:

类似这样的:

String pack = getClass().getPackage().getName();
String[] split = pack.split("\\.");
pack = split[split.length-1];

【讨论】:

Class.getPackage 可以返回 null。在这种情况下,您只需要解析完全限定的类名。【参考方案2】:

您可以尝试先从类中检索包对象,然后读取其名称。以下代码将在packageName 变量中为您提供完整的包含包名称(例如“com.foo.bar”),以及在directParent 变量中的直接父名称(例如bar):

    String packageName = getMyClass().getPackage().getName();

    String directParent;
    if(packageName.contains(".")) 
        directParent = packageName.substring(1 + packageName.lastIndexOf("."));
     else 
        directParent = packageName;
    

所以,如果你把它放在这个 sn-p 之后,你的日志语句可以只使用这些变量之一。

【讨论】:

@ernest_k 完美答案!【参考方案3】:

感谢欧内斯特的提示,它完美无缺。 对于可能有相同要求的所有其他人,我将在下面发布我的代码:

@ComponentScan(basePackages = "com.foo.fileexportservice")
@EnableAutoConfiguration(exclude = MetricFilterAutoConfiguration.class, MetricRepositoryAutoConfiguration.class, LiquibaseAutoConfiguration.class)
@EnableEurekaClient
@EnableCircuitBreaker
@EnableFeignClients(basePackages = "com.foo.fileexportservice")
public class Application 

    private static final Logger LOG = LoggerFactory.getLogger(Application.class);
    private static final String ERROR_MSG = "You have misconfigured your application! ";

    @Inject
    private Environment env;

    /**
     * Main method, used to run the application.
     */
    public static void main(String[] args) throws UnknownHostException 
        SpringApplication app = new SpringApplication(Application.class);
        app.setShowBanner(true);
        SimpleCommandLinePropertySource source = new SimpleCommandLinePropertySource(args);
        addDefaultProfile(app, source);
        Environment env = app.run(args).getEnvironment();
        LOG.info("Access URLs:\n----------------------------------------------------------\n" +
            "\tLocal: \t\thttp://127.0.0.1:/" + getPackageName() + "/admin/info\n" +
            "\tExternal: \thttp://:/" + getPackageName() + "/admin/info\n----------------------------------------------------------",
                env.getProperty("server.port"),
                InetAddress.getLocalHost().getHostAddress(),
                env.getProperty("server.port")
        );

    

    /**
     * Get the name of the application class as a static value, so we can show it in the log
     */
    private static final String getPackageName() 
        String packageName = getMyClass().getPackage().getName();

        String directParent;
        if(packageName.contains(".")) 
            directParent = packageName.substring(1 + packageName.lastIndexOf("."));
         else 
            directParent = packageName;
        
        return directParent;
    ;
    private static final Class[] getClassContext() 
        return new SecurityManager() 
            protected Class[] getClassContext()return super.getClassContext();
        .getClassContext();
    ;
    private static final Class getMyClass()  return getClassContext()[2];


    /**
     * If no profile has been configured, set by default the "dev" profile.
     */
    private static void addDefaultProfile(SpringApplication app, SimpleCommandLinePropertySource source) 
        if (!source.containsProperty("spring.profiles.active") &&
                !System.getenv().containsKey("SPRING_PROFILES_ACTIVE")) 

            app.setAdditionalProfiles(Constants.SPRING_PROFILE_DEVELOPMENT);
        
    

【讨论】:

以上是关于java获取类包名的主要内容,如果未能解决你的问题,请参考以下文章

11.1 Java类包

java类包第十一章

20165222第一周查漏补缺

20165222第一周课上测试补做

PHP读取APK的包信息,包括包名,应用名,权限,LOGO等

如何在Java中获取当前类名,包括包名?