Java获取类的包名

5
我有一堆小服务,方便地称为微服务(Microservices ;-),它们都具有相同的启动行为。它们被组织成包 - 每个包代表一个服务。包的命名方式如下:
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——如果有帮助的话。

最好的问候,

Chris

4个回答

8

您可以先从类中检索包对象,然后读取其名称。以下代码将在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;
    }

因此,如果您在此片段之后放置日志记录语句,则可以使用这些变量中的任何一个。

@ernest_k 无可挑剔的答案! - Gaurav

1
像这样的东西:
String pack = getClass().getPackage().getName();
String[] split = pack.split("\\.");
pack = split[split.length-1];

1
Class.getPackage 可以返回 null。在这种情况下,您只需要解析完全限定的类名即可。 - jmehrens

0

0
感谢Ernest的提示,它完美地运行了。 对于所有可能有相同需求的人,我将在下面发布我的代码:
@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);
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接