Tässä artikkelissa kuvataan, miten a Kevään saapas sovellus toisesta Java-ohjelmasta. Spring Boot -sovellus on tyypillisesti rakennettu yhteen suoritettavaan JAR-arkistoon. Se sisältää kaikki sisällä olevat riippuvuudet pakattuna sisäkkäisiksi JAR-tiedostoiksi.
Samoin Spring Boot -projekti rakennetaan yleensä suoritettavana JAR-tiedostona toimitetulla maven-laajennuksella, joka tekee kaiken likainen työn. Tuloksena on kätevä, yksi JAR-tiedosto, joka on helppo jakaa muiden kanssa, ottaa käyttöön palvelimella ja niin edelleen.
Spring Boot -sovelluksen käynnistäminen on yhtä helppoa kuin kirjoittaminen java -jar mySpringProg.jar , ja sovellus tulostaa konsoliin joitain hienosti muotoiltuja tietoviestejä.
Mutta entä jos a Spring Boot -kehittäjä haluaa suorittaa sovelluksen toisesta Java-ohjelmasta ilman ihmisen väliintuloa?
Jos haluat pakata Java-ohjelman, jossa on kaikki riippuvuudet, yhdeksi suoritettavaksi JAR-tiedostoksi, on toimitettava myös riippuvuudet, jotka ovat myös JAR-tiedostoja, ja jotenkin tallennettava lopullisen suoritettavan JAR-tiedoston sisälle.
'Varjostus' on yksi vaihtoehto. Riippuvuuksien varjostaminen on prosessi, joka sisältää riippuvuuksien sisällyttämisen ja nimeämisen, luokkien uudelleensijoittamisen sekä asianomaisten tavukoodien ja resurssien uudelleenkirjoittamisen, jotta voidaan luoda kopio, joka niputetaan yhdessä sovelluksen (projekti) oman koodin kanssa.
Varjostamisen avulla käyttäjät voivat purkaa kaikki luokat ja resurssit riippuvuuksista ja pakata ne takaisin suoritettavaan JAR-tiedostoon. Tämä saattaa toimia yksinkertaisissa tilanteissa, mutta jos kaksi riippuvuutta sisältää saman resurssitiedoston tai luokan, jolla on täsmälleen sama nimi ja polku, ne menevät päällekkäin ja ohjelma ei välttämättä toimi.
Spring Boot käyttää erilaista lähestymistapaa ja pakkaa riippuvuuden JAR: t juoksevaan JAR: iin sisäkkäisinä JAR: eina.
example.jar | +-META-INF | +-MANIFEST.MF +-org | +-springframework | +-boot | +-loader | +- +-BOOT-INF +-classes | +-mycompany | +-project | +-YourClasses.class +-lib +-dependency1.jar +-dependency2.jar
TO JAR-arkisto on järjestetty tavalliseksi Java-ajettavaksi JAR-tiedostoksi. Spring Boot loader -luokat sijaitsevat osoitteessa org/springframework/boot/loader
polku, kun taas käyttäjäluokat ja riippuvuudet ovat BOOT-INF/classes
ja BOOT-INF/lib
.
Huomautus: Jos olet uusi kevät, voit myös haluta katsoa meidän Top 10 yleisintä kevään kehysvirhettä artikla .
Tyypillinen Spring Boot JAR -tiedosto sisältää kolmen tyyppisiä merkintöjä:
Spring Boot Classloader asettaa ensin JAR-kirjastot luokkatielle ja sitten projekti luokkiin, mikä tekee pienen eron Spring Boot -sovelluksen suorittamisen välillä IDE: stä ( Pimennys , IntelliJ ) ja konsolista.
Lisätietoja luokan ohituksista ja luokan latausohjelmasta saat ottamalla yhteyttä Tämä artikkeli .
Spring Boot -sovelluksen manuaalinen käynnistäminen komentoriviltä tai kuoresta on helppoa, koska kirjoitat seuraavan:
java -jar example.jar
Spring Boot -sovelluksen käynnistäminen ohjelmallisesti toisesta Java-ohjelmasta vaatii kuitenkin enemmän vaivaa. org/springframework/boot/loader/*.class
On ladattava -koodia, käytä vähän Java-heijastusta JarFileArchive
, JarLauncher
ja kutsu launch(String[])
menetelmä.
Seuraavassa tarkastellaan tarkemmin, miten tämä saavutetaan.
Kuten jo huomautimme, Spring Boot JAR -tiedosto on aivan kuten mikä tahansa JAR-arkisto. On mahdollista ladata org/springframework/boot/loader/*.class
merkinnät, luo luokan objektit ja käytä niitä käynnistääksesi Spring Boot -sovellukset myöhemmin.
import java.net.URLClassLoader; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; . . . public static void loadJar(final String pathToJar) throws IOException . . . { // Class name to Class object mapping. final Map classMap = new HashMap(); final JarFile jarFile = new JarFile(pathToJar); final Enumeration jarEntryEnum = jarFile.entries(); final URL[] urls = { new URL('jar:file:' + pathToJar + '!/') }; final URLClassLoader urlClassLoader = URLClassLoader.newInstance(urls);
Täällä voimme nähdä classMap
pitää luokan objektit kartoitettuina vastaaviin pakettien nimiin, esim. merkkijonoarvo org.springframework.boot.loader.JarLauncher
kartoitetaan JarLauncher.class
esine.
while (jarEntryEnum.hasMoreElements()) { final JarEntry jarEntry = jarEntryEnum.nextElement(); if (jarEntry.getName().startsWith('org/springframework/boot') && jarEntry.getName().endsWith('.class') == true) { int endIndex = jarEntryName.lastIndexOf('.class'); className = jarEntryName.substring(0, endIndex).replace('/', '.'); try { final Class loadedClass = urlClassLoader.loadClass(className); result.put(loadedClass.getName(), loadedClass); } catch (final ClassNotFoundException ex) { } } } jarFile.close();
Lopputulos samalla silmukka on kartta, jossa on Spring Boot loader -luokan objekteja.
Ladattuaan tieltä voimme viimeistellä automaattisen käynnistämisen ja käyttää sitä sovelluksen käynnistämiseen.
Java-heijastus mahdollistaa objektien luomisen ladatuista luokista, mikä on varsin hyödyllistä opetusohjelmamme yhteydessä.
Ensimmäinen vaihe on luoda JarFileArchive
esine.
// Create JarFileArchive(File) object, needed for JarLauncher. final Class jarFileArchiveClass = result.get('org.springframework.boot.loader.archive.JarFileArchive'); final Constructor jarFileArchiveConstructor = jarFileArchiveClass.getConstructor(File.class); final Object jarFileArchive = jarFileArchiveConstructor.newInstance(new File(pathToJar));
JarFileArchive
: N rakentaja objekti vie File(String)
objekti argumenttina, joten se on annettava.
Seuraava vaihe on luoda JarLauncher
objekti, joka vaatii Archive
sen rakentaja.
final Class archiveClass = result.get('org.springframework.boot.loader.archive.Archive'); // Create JarLauncher object using JarLauncher(Archive) constructor. final Constructor jarLauncherConstructor = mainClass.getDeclaredConstructor(archiveClass); jarLauncherConstructor.setAccessible(true); final Object jarLauncher = jarLauncherConstructor.newInstance(jarFileArchive);
Sekaannusten välttämiseksi huomaa, että Archive
on itse asiassa käyttöliittymä, kun taas JarFileArchive
on yksi toteutuksista.
Viimeinen vaihe prosessissa on kutsua launch(String[])
menetelmä äskettäin luotuun jarLauncher
esine. Tämä on suhteellisen yksinkertaista ja vaatii vain muutaman rivin koodia.
// Invoke JarLauncher#launch(String[]) method. final Class launcherClass = result.get('org.springframework.boot.loader.Launcher'); final Method launchMethod = launcherClass.getDeclaredMethod('launch', String[].class); launchMethod.setAccessible(true); launchMethod.invoke(jarLauncher, new Object[]{new String[0]});
invoke(jarLauncer, new Object[]{new String[0]})
menetelmä käynnistää lopulta Spring Boot -sovelluksen. Huomaa, että pääkierre pysähtyy ja odottaa Spring Boot -sovelluksen päättymistä.
Spring Boot JAR -tiedostomme tutkiminen paljastaa seuraavan rakenteen:
+--- mySpringApp1-0.0.1-SNAPSHOT.jar +--- META-INF +--- BOOT-INF | +--- classes # 1 - project classes | | | | | +--- com.example.mySpringApp1 | | --- SpringBootLoaderApplication.class | | | +--- lib # 2 - nested jar libraries | +--- javax.annotation-api-1.3.1 | +--- spring-boot-2.0.0.M7.jar | --- (...) | +--- org.springframework.boot.loader # 3 - Spring Boot loader classes +--- JarLauncher.class +--- LaunchedURLClassLoader.class --- (...)
Huomaa kolmen tyyppiset merkinnät:
Sekä projektiluokkia (BOOT-INF/classes
) että sisäkkäisiä JAR-tiedostoja (BOOT-INF/lib
) käsittelee sama luokan kuormaaja LaunchedURLClassLoader
Tämä laturi sijaitsee Spring Boot JAR -sovelluksen juuressa.
LaunchedURLClassLoader
lataa luokan sisällön (BOOT-INF/classes
) kirjaston sisällön (BOOT-INF/lib
) jälkeen, mikä eroaa IDE: stä. Esimerkiksi Eclipse sijoittaa ensin luokan sisällön luokkatielle ja sitten kirjastot (riippuvuudet).
LaunchedURLClassLoader
extends java.net.URLClassLoader
, joka luodaan joukolla URL-osoitteita, joita käytetään luokan lataamiseen. URL-osoite saattaa osoittaa sijaintiin, kuten JAR-arkisto tai luokkakansio. Kun suoritat luokan latausta, kaikki URL-osoitteiden määrittelemät resurssit kulkevat siinä järjestyksessä kuin URL-osoitteet annettiin, ja ensimmäistä etsittyä luokkaa sisältävää resurssia käytetään.
Klassinen Java-sovellus edellyttää, että kaikki riippuvuudet luetellaan classpath-argumentissa, mikä tekee käynnistysprosessista hieman hankalaa ja monimutkaista.
Sitä vastoin Spring Boot -sovellukset ovat käteviä ja helppoja käynnistää komentoriviltä. He hallitsevat kaikkia riippuvuuksia, eikä loppukäyttäjän tarvitse huolehtia yksityiskohdista.
Spring Boot -sovelluksen käynnistäminen toisesta Java-ohjelmasta tekee kuitenkin menettelystä monimutkaisemman, koska se vaatii Spring Boot -sovelluksen latausluokkien lataamista luomalla erikoistuneita esineitä, kuten JarFileArchive
ja JarLauncher
ja sitten Java-heijastuksen avulla launch
menetelmä.
Bottom line : Spring Boot voi huolehtia monista vähäisistä tehtävistä konepellin alla, jolloin kehittäjät voivat vapauttaa aikaa ja keskittyä hyödyllisempään työhön, kuten uusien ominaisuuksien luomiseen, testaamiseen ja niin edelleen.
Spring Boot -toiminnon avulla on helppo luoda erillisiä, tuotantoluokan kevätpohjaisia sovelluksia, jotka on helppo suorittaa tai ottaa käyttöön, kun taas Spring Framework on kattava joukko Java-kirjastoja, joita käytetään rikkaiden verkko-, työpöytä- tai mobiilisovellusten kehittämiseen.
Spring Boot tarjoaa maven-malleja, sisäänrakennetun Tomcat-verkkopalvelimen ja joitain ennalta määritettyjä kokoonpanoja Springin käytön yksinkertaistamiseksi. Useimmat Spring Boot -sovellukset tarvitsevat hyvin vähän Spring-määrityksiä. Spring Bootia käytetään luomaan Java-sovelluksia, jotka voidaan käynnistää käyttämällä java -jar-ohjelmaa tai perinteisempiä sotatilanteita.
Spring Boot -arkkitehtuuri tarjoaa käynnistimet, automaattisen määrityksen ja komponenttien skannauksen, jotta pääset alkuun Springin kanssa ilman monimutkaisia XML-määritystiedostoja.