Printemps de démarrage des problèmes de performances
Je suis en train d'intégrer le Printemps dans une assez grande application avec des milliers de classes, et je suis en train de vivre d'énormes retards de départ de mon conteneur car de composant de balayage.
J'ai déjà réduit le nombre de répertoires spécifiés dans le "base-package", au minimum afin de réduire les pertes de temps lors de l'analyse de pertinence des répertoires, mais la classe de chemin de numérisation d'une partie de l'initialisation encore faut environ 1 à 2 minutes.
Alors, est-il un moyen d'optimiser le processus de numérisation ? J'ai pensé à stocker les candidats des classes de chemin d'accès dans un fichier et de le rendre le récipient de les obtenir à partir du fichier au lieu de les balayer le chemin de classe à chaque démarrage, mais je ne sais pas vraiment par où commencer, ou si cela est encore possible.
Tout conseils sont appréciés. Merci à l'avance.
Modifier: Chargement de la fève de définitions forme d'un fichier xml généré automatiquement, réduit le Printemps, temps de chauffe de 9~10 secondes, ce qui confirme que le reflet de l'api utilisée pour le Printemps de l'composants de chemin de classe de la numérisation est la principale source de démarrage des retards.
Comme pour la génération du fichier xml voici le code, car il pourrait être utile pour quelqu'un avec les mêmes problèmes.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
public class ConfigurationWriter {
public ArrayList<String> beanDefinitions = new ArrayList<String>();
public ConfigurationWriter() {
//the context loaded with old fashioned way (classpath scanning)
ApplicationContext context = SpringContainerServiceImpl.getInstance().getContext();
String[] tab = context.getBeanDefinitionNames();
for (int i = 0; i < tab.length - 6; i++) {
Class clazz = context.getType(tab[i]);
String scope = context.isPrototype(tab[i]) ? "prototype" : "singleton";
String s = "<bean id=\"" + tab[i] + "\" class=\"" + clazz.getName() + "\" scope=\"" + scope + "\"/>";
beanDefinitions.add(s);
}
//Collections.addAll(beanDefinitions, tab);
}
@SuppressWarnings("restriction")
public void generateConfiguration() throws FileNotFoundException {
File xmlConfig = new File("D:\\dev\\svn\\...\\...\\src\\test\\resources\\springBoost.xml");
PrintWriter printer = new PrintWriter(xmlConfig);
generateHeader(printer);
generateCorpse(printer);
generateTail(printer);
printer.checkError();
}
@SuppressWarnings("restriction")
private void generateCorpse(PrintWriter printer) {
for (String beanPath : beanDefinitions) {
printer.println(beanPath);
}
}
@SuppressWarnings("restriction")
private void generateHeader(PrintWriter printer) {
printer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
printer.println("<beans xmlns=\"http://www.springframework.org/schema/beans\"");
printer.println("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
printer.println("xmlns:context=\"http://www.springframework.org/schema/context\"");
printer.println("xsi:schemaLocation=\"");
printer.println("http://www.springframework.org/schema/mvc");
printer.println("http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd");
printer.println("http://www.springframework.org/schema/beans");
printer.println("http://www.springframework.org/schema/beans/spring-beans-3.0.xsd");
printer.println("http://www.springframework.org/schema/context");
printer.println("http://www.springframework.org/schema/context/spring-context-3.0.xsd\"");
printer.println("default-lazy-init=\"true\">");
}
@SuppressWarnings("restriction")
private void generateTail(PrintWriter printer) {
//printer.println("<bean class=\"com.xxx.frmwrk.spring.processors.xxxBeanFactoryPostProcessor\"/>");
printer.println("<bean class=\"com.xxx.frmwrk.spring.processors.xxxPostProcessor\"/>");
printer.println("</beans>");
}
}
- Combien (en %) des classes dans les répertoires sont des Beans Spring?
- Je ne suis pas vraiment sûr (c'est un très gros projet) , mais ce que j'ai vu je crois que c'est autour de 90 à 100%, étant donné que le xml et des fichiers de propriétés sont isolés dans des endroits séparés)
- Pouah, sentez-vous la douleur. Juste hérité d'un 3600 bean Spring monstre avec 425 config xml de. 9min à tourner sur... sur une très bonne journée. Merci pour vos messages! Je croise les doigts et va ajouter toutes les pépites découvertes.
- comment résoudre ce pour @Autowire des trucs?!
- Ce qui confirme encore une fois que la réflexion est vraiment une opération coûteuse et doit toujours être mis en cache.... ou est-il juste de Printemps liés à la réflexion? Où doit-on déposer un bug? Oracle ou le Printemps? 😉
Vous devez vous connecter pour publier un commentaire.
Si le problème est vraiment le composant d'analyse et de ne pas la fève de l'initialisation du processus lui-même (et je doute fortement que), alors la seule solution que je peux imaginer est d'utiliser le Printemps de configuration XML à la place de la composante d'analyse. - (Peut vous pouvez créer le fichier XML automatiquement).
Mais si vous avez un grand nombre de classes et 90% - 100% d'entre eux sont les Haricots, puis, à la réduction de fichiers numérisés aura un maximale amélioration de 10% -0%.
Vous devriez essayer d'autres façons d'accélérer votre initialisation, peut utiliser le chargement paresseux ou tout chargement différé des techniques connexes, ou (et c'est pas une blague) utiliser l'accélération matérielle (si ce n'est pas une application autonome).
Un moyen facile de générer le Printemps XML est d'écrire un simple ressort de l'application qui utilise le chemin de classe de numérisation comme l'original de votre demande. Après tout, les Haricots sont initialiser, il parcourt les Haricots dans le Ressort du Contexte, de vérifier si le bean appartient à un colis important et écrire la configuration XML pour ce bean dans un fichier.
De la détection automatique de annoté des classes oblige actuellement à l'analyse de toutes les classes dans le package spécifié(s) et peut prendre beaucoup de temps, un problème connu de la classe actuelle mécanisme de chargement.
Java 9 va aider ici avec une scie Sauteuse.
À partir de la Plate-forme Java Module System exigences par Mark Reinold, http://openjdk.java.net/projects/jigsaw/spec/reqs/ :
Efficace annotation de détection
Il doit être possible d'identifier tous les fichiers de classe dans un module artefact dans lequel un particulier annotation est présente, sans devoir lire tous les fichiers de classe. Au moment de l'exécution, il doit être possible d'identifier toutes les classes dans un module chargé en particulier d'annotation est présente sans que l'énumération de toutes les classes dans le module, aussi longtemps que l'annotation a été retenu pour le moment de l'exécution. Pour l'efficacité, il peut être nécessaire de spécifier que seules certaines annotations doivent être détectables de cette manière.
Une approche possible consiste à développer un module de définition avec un index des annotations qui sont présents dans le module, avec une indication des éléments qui chaque annotation s'applique. Pour limiter la taille de l'index, seules les annotations qui eux-mêmes sont annotés avec une nouvelle méta-annotation, de dire @Indexés, serait inclus.
Pas beaucoup que vous pouvez faire au sujet de la performance de là, je suppose que vous n'êtes pas préoccupé par le démarrage en environnement de production, mais le temps de démarrage de votre tests*.
Deux conseils:
La seule chose qui vient à mon esprit, à côté de réduire les répertoires à scanner, est l'utilisation de paresseux bean initialisation.
Peut cela pourrait aider si vous avez beaucoup de haricots
Vous pouvez utiliser le Printemps Java configuration du conteneur au lieu de composant d'analyse.
En comparaison XML de configuration basé sur le Java conteneur de configuration est de type sécurisé.
Mais tout d'abord, vous devez vérifier si votre composant d'analyse des chemins d'accès sont assez spécifiques, de sorte qu'ils ne comprennent pas les classes des bibliothèques tierces.
Je sais que c'est une vieille question, et comme vous pourrez le voir, la situation était différente à l'époque, mais j'espère qu'il peut aider d'autres personnes à la recherche de cette question comme je l'ai fait.
Selon cette réponse à une autre question, Le
@ComponentScan
annotation prend désormais en charge unlazyInit
drapeau, ce qui devrait aider à réduire les temps de démarrage.https://stackoverflow.com/a/29832836/4266381
Remarque: Votre modifier rendu sonore, comme le passage à XML en lui-même était de la magie. Pourtant, en regardant de plus près le code, vous avez eu
default-lazy-init="true"
. Je me demande si c'était la vraie raison.