2016-05-23 1 views
0

J'ai un tas de petits services, commodément appelés Microservices ;-), qui ont tous le même comportement de démarrage. Ils sont disposés en paquets - chacun pour un service. La désignation du paquet est comme ceci:Java obtenir le nom du paquet de la classe

com.foo.bar.Application 

où com.foo est la partie de domaine, un bar est le nom du service et l'application réelle est ma classe principale instance avec la principale méthode.

Maintenant, ce que je voudrais faire est d'imprimer un message de journal standardisé quand ils sont démarrés, montrant l'URL qu'un utilisateur peut demander pour obtenir des informations sur le service. Par définition, l'URL pour obtenir d'infos pour le service doivent être construits comme ceci:

IP:PORT/bar/admin/info 

J'ai essayé d'obtenir ce bar.name avec getClass() ... etc., mais cela ne fonctionne pas. J'ai donc essayé ceci:

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];} 

Mais comme vous avez déjà deviné, ce imprime beaucoup trop:

class com.foo.bar.Application 

Où tout ce que je voudrais faire est

bar 

Comment puis-je atteindre cet objectif???

Soit dit en passant, j'utilise Java 8 et démarrage de printemps - si cela aide

Meilleures salutations,

Quelque chose comme Chris

Répondre

1

Vous pourriez essayez d'extraire l'objet package de la classe en premier, puis lisez son nom. Le code suivant vous donnera le plein contenant le nom du paquet (tel que « com.foo.bar ») dans la variable packageName, et le nom du parent direct (comme bar) dans la variable directParent:

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

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

Alors , votre instruction de journal pourrait juste utiliser une de ces variables si vous le mettez après cet extrait.

+0

Salut Ernest, merci. Cela a résolu! – siliconchris

1

ceci:

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

[Class.getPackage] (https://docs.oracle.com/javase/8/docs/api/java /lang/Class.html#getPackage--) peut retourner null. Dans ce cas, il vous suffit d'analyser le nom de classe complet. – jmehrens

0

Merci à Ernest pour son conseil, il fonctionne parfaitement. Pour tous les autres qui peuvent avoir la même exigence, je posterai mon code ci-dessous:

@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); 
     } 
    } 
}