Heim Java javaLernprogramm Detailliertes Beispiel für das Kopieren von Java-Objekten

Detailliertes Beispiel für das Kopieren von Java-Objekten

May 02, 2017 pm 02:15 PM

In diesem Artikel werden hauptsächlich detaillierte Erklärungen und Beispiele für das Kopieren von Java-Objekten vorgestellt. Freunde, die es benötigen, können sich auf

Detaillierte Erklärungen und Beispiele für das Kopieren von Java-Objekten beziehen

Die Java-Zuweisung kopiert eine Objektreferenz. Wenn wir eine Kopie eines Objekts erhalten möchten, kann die Verwendung der Zuweisungsoperation den Zweck nicht erreichen:

@Test
public void testassign(){
 Person p1=new Person();
 p1.setAge(31);
 p1.setName("Peter");

 Person p2=p1;
 System.out.println(p1==p2);//true
}
Nach dem Login kopieren

Wenn Sie eine neue Kopie des Objekts erstellen, d. h Sagen wir, ihr Anfangszustand ist genau derselbe, aber Sie können ihren jeweiligen Zustand in Zukunft ändern, ohne sich gegenseitig zu beeinflussen. Daher müssen Sie die Kopie von Objekten in Java verwenden, z. B. die native Methode clone().

So klonen Sie ein Objekt

Das Object-Objekt verfügt über eine clone()-Methode, die das Kopieren jedes Attributs im Objekt realisiert, sein sichtbarer Bereich ist jedoch geschützt , also Die Voraussetzung für die Verwendung des Klonens für Entitätsklassen ist:

① Implementieren Sie die Cloneable-Schnittstelle, die eine Markierungsschnittstelle ist und keine eigenen Methoden hat.

② Überschreiben Sie die clone()-Methode und erhöhen Sie die Sichtbarkeit für die Öffentlichkeit.

@Data
public class Person implements Cloneable {
  private String name;
  private Integer age;
  private Address address;
  @Override
  protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
}

@Test
public void testShallowCopy() throws Exception{
 Person p1=new Person();
 p1.setAge(31);
 p1.setName("Peter");

 Person p2=(Person) p1.clone();
 System.out.println(p1==p2);//false
 p2.setName("Jacky");
 System.out.println("p1="+p1);//p1=Person [name=Peter, age=31]
 System.out.println("p2="+p2);//p2=Person [name=Jacky, age=31]
}
Nach dem Login kopieren

Dieser Testfall hat nur zwei Grundtypen von Mitgliedern, und der Test erfüllt seinen Zweck.

Die Dinge scheinen nicht so einfach zu sein. Fügen Sie ein Mitglied der Address-Klasse zu Person hinzu:

@Data
public class Address {
  private String type;
  private String value;
}
Nach dem Login kopieren

Testen Sie es erneut, und das Problem tritt auf.

@Test
public void testShallowCopy() throws Exception{
 Address address=new Address();
 address.setType("Home");
 address.setValue("北京");

 Person p1=new Person();
 p1.setAge(31);
 p1.setName("Peter");
 p1.setAddress(address);

 Person p2=(Person) p1.clone();
 System.out.println(p1==p2);//false

 p2.getAddress().setType("Office");
 System.out.println("p1="+p1);
 System.out.println("p2="+p2);
}
Nach dem Login kopieren

Sehen Sie sich die Ausgabe an:

false
p1=Person(name=Peter, age=31, address=Address(type=Office, value=北京))
p2=Person(name=Peter, age=31, address=Address(type=Office, value=北京))
Nach dem Login kopieren

Ich hatte ein Problem. Ich habe nur den Adresstyp von p2 geändert und beide Adresstypen wurden zu Office.

Shallow Copy und Deep Copy

Die vorherigen Beispiele sind typische Anwendungsfälle von Shallow Copy und Deep Copy.

Flache Kopie: Alle Wertattribute des kopierten Objekts enthalten dieselben Werte wie die des Originalobjekts, und alle Objektreferenzattribute verweisen weiterhin auf das Originalobjekt.

Tiefe Kopie: Auf der Grundlage der flachen Kopie werden alle Variablen, die auf andere Objekte verweisen, ebenfalls geklont und verweisen auf das kopierte neue Objekt.

Mit anderen Worten, ein Standardmechanismus zur Implementierung der clone()-Methode ist immer noch eine Zuweisung.

Wenn ein kopiertes Attribut ein Basistyp ist, müssen Sie nur den klonbaren Mechanismus der aktuellen Klasse implementieren. Dies ist eine flache Kopie.

Wenn die Eigenschaften des kopierten Objekts Verweise auf andere Entitätsklassenobjekte enthalten, müssen diese Entitätsklassenobjekte die klonbare Schnittstelle implementieren und die clone()-Methode überschreiben.

@Data
public class Address implements Cloneable {
  private String type;
  private String value;

  @Override
  protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
}
Nach dem Login kopieren

Das reicht nicht aus, Person's clone() muss seine Referenzmitglieder explizit klonen.

@Data
public class Person implements Cloneable {
  private String name;
  private Integer age;
  private Address address;
  @Override
  protected Object clone() throws CloneNotSupportedException {
    Object obj=super.clone();
    Address a=((Person)obj).getAddress();
    ((Person)obj).setAddress((Address) a.clone());
    return obj;
  }
}
Nach dem Login kopieren

Führen Sie den vorherigen Testfall erneut aus:

false
p1=Person(name=Peter, age=31, address=Address(type=Home, value=北京))
p2=Person(name=Peter, age=31, address=Address(type=Office, value=北京))
Nach dem Login kopieren

Zusammenfassung der Deep-Copy-in-Clone-Methode

① Wenn es eine Nicht- natives Mitglied, Wenn Sie ein Mitglied eines benutzerdefinierten Objekts definieren, benötigen Sie:

  1. Das Mitglied implementiert die Cloneable-Schnittstelle und überschreibt die clone()-Methode öffentliche Sichtbarkeit.

  2. Ändern Sie gleichzeitig die clone()-Methode der kopierten Klasse und fügen Sie die Klonlogik für Mitglieder hinzu.

② Wenn das kopierte Objekt Object nicht direkt erbt, gibt es dazwischen andere Vererbungsebenen. Jede Superklasse muss die Cloneable-Schnittstelle implementieren und die clone()-Methode überschreiben.

Im Gegensatz zu Objektmitgliedern erfordert das Klonen in einer Vererbungsbeziehung keine redundante Arbeit durch clone() der kopierten Klasse.

Kurz gesagt: Wenn Sie eine vollständige Tiefenkopie implementieren, muss jedes Objekt in der Vererbungskette und Referenzkette des kopierten Objekts den Klonmechanismus implementieren.

Das vorherige Beispiel ist akzeptabel, aber wenn es N Objektmitglieder und Vererbungsbeziehungen auf M-Ebene gibt, wird es sehr problematisch sein.

Serialisierung zur Implementierung von Deep Copy verwenden

Der Klonmechanismus wird nicht durch starke Typen eingeschränkt. Beispielsweise erzwingt die Implementierung von Cloneable die Objekte in der Vererbungskette muss ebenfalls implementiert werden; es gibt keine Kraft. Erfordert das Überschreiben der clone()-Methode. Daher kann es während des Codierungsprozesses leicht passieren, dass einer der Links übersehen wird, was die Fehlersuche bei komplexen Projekten erschwert.

Wenn Sie nach zuverlässigen, einfachen Methoden suchen, ist die Serialisierung die richtige Wahl.

1. Jedes Objekt in der Vererbungskette und Referenzkette des kopierten Objekts implementiert die java.io.Serializable-Schnittstelle. Dies ist relativ einfach und erfordert keine Implementierung von Methoden. Die Anforderung „serialVersionID“ ist nicht zwingend erforderlich und reicht für tiefes Kopieren aus.

2. Implementieren Sie Ihre eigene deepClone-Methode, schreiben Sie diese in den Stream und lesen Sie sie dann aus. Allgemein bekannt als: Gefrier-Tau-Wechsel.

@Data
public class Person implements Serializable {
  private String name;
  private Integer age;
  private Address address;
  public Person deepClone() {
    Person p2=null;
    Person p1=this;
    PipedOutputStream out=new PipedOutputStream();
    PipedInputStream in=new PipedInputStream();
    try {
      in.connect(out);
    } catch (IOException e) {
      e.printStackTrace();
    }

    try(ObjectOutputStream bo=new ObjectOutputStream(out);
        ObjectInputStream bi=new ObjectInputStream(in);) {
      bo.writeObject(p1);
      p2=(Person) bi.readObject();

    } catch (Exception e) {
      e.printStackTrace();
    }
    return p2;
  }
}
Nach dem Login kopieren

Prototyp-Fabrikklasse

Um das Testen zu erleichtern und Platz zu sparen, ist eine Fabrikklasse gekapselt.

Vermeiden Sie der Fairness halber die Verwendung von Caching-Mechanismen in einigen Werkzeugbibliotheken und verwenden Sie Prototypenfabriken.

public class PersonFactory{
  public static Person newPrototypeInstance(){
    Address address = new Address();
    address.setType("Home");
    address.setValue("北京");

    Person p1 = new Person();
    p1.setAddress(address);
    p1.setAge(31);
    p1.setName("Peter");
    return p1;
  }
}
Nach dem Login kopieren

Verwenden Sie Dozer, um Objekte zu kopieren

Dozer ist eine Bean-Verarbeitungsbibliothek.

Maven-Abhängigkeit

<dependency>
 <groupId>net.sf.dozer</groupId>
 <artifactId>dozer</artifactId>
 <version>5.5.1</version>
</dependency>
Nach dem Login kopieren

Testfall:

@Data
public class Person {
  private String name;
  private Integer age;
  private Address address;

  @Test
  public void testDozer() {
  Person p1=PersonFactory.newPrototypeInstance();
    Mapper mapper = new DozerBeanMapper();
    Person p2 = mapper.map(p1, Person.class);
    p2.getAddress().setType("Office");
    System.out.println("p1=" + p1);
    System.out.println("p2=" + p2);
  }
}

@Data
public class Address {
  private String type;
  private String value;
}
Nach dem Login kopieren

Ausgabe:

p1=Person(name=Peter, age=31, address=Address(type=Home, value=北京))
p2=Person(name=Peter, age=31, address=Address(type=Office, value=北京))
Nach dem Login kopieren

Hinweis: In 10.000 Tests gibt es einen Dozer A Sehr ernstes Problem. Wenn das DozerBeanMapper-Objekt in einer for-Schleife erstellt wird, wird die Effizienz (dozer:7358) um ​​fast das Zehnfache reduziert. Da DozerBeanMapper threadsicher ist, sollte nicht jedes Mal eine neue Instanz erstellt werden. Sie können die integrierte Singleton-Factory DozerBeanMapperSingletonWrapper verwenden, um einen Mapper zu erstellen oder ihn in Spring zu integrieren.

Es gibt noch mehr Gewalt, erstellen Sie eine People-Klasse:

@Data
public class People {
  private String name;
  private String age;//这里已经不是Integer了
  private Address address;

  @Test
  public void testDozer() {
  Person p1=PersonFactory.newPrototypeInstance();
    Mapper mapper = new DozerBeanMapper();
    People p2 = mapper.map(p1, People.class);
    p2.getAddress().setType("Office");
    System.out.println("p1=" + p1);
    System.out.println("p2=" + p2);
  }
}
Nach dem Login kopieren

Solange die Attributnamen gleich sind, tun Sie es ~

Weiter verwüsten:

@Data
public class People {
  private String name;
  private String age;
  private Map<String,String> address;//��

  @Test
  public void testDozer() {
  Person p1=PersonFactory.newPrototypeInstance();
    Mapper mapper = new DozerBeanMapper();
    People p2 = mapper.map(p1, People.class);
    p2.getAddress().put("type", "Office");
    System.out.println("p1=" + p1);
    System.out.println("p2=" + p2);
  }
}
Nach dem Login kopieren

Verwenden Sie Commons-BeanUtils, um Objekte zu kopieren

Maven-Abhängigkeit

<dependency>
 <groupId>commons-beanutils</groupId>
 <artifactId>commons-beanutils</artifactId>
 <version>1.9.3</version>
</dependency>
Nach dem Login kopieren

Testfall:

@Data
public class Person {
  private String name;
  private String age;
  private Address address;

  @Test
  public void testCommonsBeanUtils(){
  Person p1=PersonFactory.newPrototypeInstance();
    try {
      Person p2=(Person) BeanUtils.cloneBean(p1);
      System.out.println("p1=" + p1);
      p2.getAddress().setType("Office");
      System.out.println("p2=" + p2);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
Nach dem Login kopieren

Verwenden Sie cglib, um Objekte zu kopieren

Maven-Abhängigkeit:

<dependency>
 <groupId>cglib</groupId>
 <artifactId>cglib</artifactId>
 <version>3.2.4</version>
</dependency>
Nach dem Login kopieren

Testfall:

@Test
public void testCglib(){
 Person p1=PersonFactory.newPrototypeInstance();
 BeanCopier beanCopier=BeanCopier.create(Person.class, Person.class, false);
 Person p2=new Person();
 beanCopier.copy(p1, p2,null);
 p2.getAddress().setType("Office");
 System.out.println("p1=" + p1);
 System.out.println("p2=" + p2);
}
Nach dem Login kopieren

Das Ergebnis ist schockierend, cglib ist so großartig , es ist eigentlich eine oberflächliche Kopie. cglib bietet jedoch Erweiterungsmöglichkeiten:

@Test
public void testCglib(){
 Person p1=PersonFactory.newPrototypeInstance();
 BeanCopier beanCopier=BeanCopier.create(Person.class, Person.class, true);
 Person p2=new Person();
 beanCopier.copy(p1, p2, new Converter(){
  @Override
  public Object convert(Object value, Class target, Object context) {
   if(target.isSynthetic()){
    BeanCopier.create(target, target, true).copy(value, value, this);
   }
   return value;
  }
 });
 p2.getAddress().setType("Office");
 System.out.println("p1=" + p1);
 System.out.println("p2=" + p2);
}
Nach dem Login kopieren

Orika复制对象

orika的作用不仅仅在于处理bean拷贝,更擅长各种类型之间的转换。

maven依赖:

<dependency>
 <groupId>ma.glasnost.orika</groupId>
 <artifactId>orika-core</artifactId>
 <version>1.5.0</version>
</dependency>
</dependencies>
Nach dem Login kopieren

测试用例:

@Test
public void testOrika() {
 MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

 mapperFactory.classMap(Person.class, Person.class)
 .byDefault()
 .register();
 ConverterFactory converterFactory = mapperFactory.getConverterFactory();
 MapperFacade mapper = mapperFactory.getMapperFacade();

 Person p1=PersonFactory.newPrototypeInstance();
 Person p2 = mapper.map(p1, Person.class);
 System.out.println("p1=" + p1);
 p2.getAddress().setType("Office");
 System.out.println("p2=" + p2);
}
Nach dem Login kopieren

Spring BeanUtils复制对象

给Spring个面子,貌似它不支持深拷贝。

Person p1=PersonFactory.newPrototypeInstance();
Person p2 = new Person();
Person p2 = (Person) BeanUtils.cloneBean(p1);
//BeanUtils.copyProperties(p2, p1);//这个更没戏
Nach dem Login kopieren

深拷贝性能对比

@Test
public void testBatchDozer(){
 Long start=System.currentTimeMillis();
 Mapper mapper = new DozerBeanMapper();
 for(int i=0;i<10000;i++){
  Person p1=PersonFactory.newPrototypeInstance();
  Person p2 = mapper.map(p1, Person.class);
 }
 System.out.println("dozer:"+(System.currentTimeMillis()-start));
 //dozer:721
}
@Test
public void testBatchBeanUtils(){
 Long start=System.currentTimeMillis();
 for(int i=0;i<10000;i++){
  Person p1=PersonFactory.newPrototypeInstance();
  try {
   Person p2=(Person) BeanUtils.cloneBean(p1);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 System.out.println("commons-beanutils:"+(System.currentTimeMillis()-start));
 //commons-beanutils:229
}
@Test
public void testBatchCglib(){
 Long start=System.currentTimeMillis();
 for(int i=0;i<10000;i++){
  Person p1=PersonFactory.newPrototypeInstance();
  BeanCopier beanCopier=BeanCopier.create(Person.class, Person.class, true);
  Person p2=new Person();
  beanCopier.copy(p1, p2, new Converter(){
   @Override
   public Object convert(Object value, Class target, Object context) {
    if(target.isSynthetic()){
     BeanCopier.create(target, target, true).copy(value, value, this);
    }
    return value;
   }
  });
 }
 System.out.println("cglib:"+(System.currentTimeMillis()-start));
 //cglib:133
}
@Test
public void testBatchSerial(){
 Long start=System.currentTimeMillis();
 for(int i=0;i<10000;i++){
  Person p1=PersonFactory.newPrototypeInstance();
  Person p2=p1.deepClone();
 }
 System.out.println("serializable:"+(System.currentTimeMillis()-start));
 //serializable:687
}
@Test
public void testBatchOrika() {
 MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

 mapperFactory.classMap(Person.class, Person.class)
 .field("name", "name")
 .byDefault()
 .register();
 ConverterFactory converterFactory = mapperFactory.getConverterFactory();
 MapperFacade mapper = mapperFactory.getMapperFacade();

 Long start=System.currentTimeMillis();
 for(int i=0;i<10000;i++){
  Person p1=PersonFactory.newPrototypeInstance();
  Person p2 = mapper.map(p1, Person.class);
 }
 System.out.println("orika:"+(System.currentTimeMillis()-start));
 //orika:83
}

@Test
public void testBatchClone(){
 Long start=System.currentTimeMillis();
 for(int i=0;i<10000;i++){
  Person p1=PersonFactory.newPrototypeInstance();
  try {
   Person p2=(Person) p1.clone();
  } catch (CloneNotSupportedException e) {
   e.printStackTrace();
  }
 }
 System.out.println("clone:"+(System.currentTimeMillis()-start));
 //clone:8
}
Nach dem Login kopieren

(10k)性能比较:

//dozer:721
//commons-beanutils:229
//cglib:133
//serializable:687
//orika:83
//clone:8
Nach dem Login kopieren

深拷贝总结

原生的clone效率无疑是最高的,用脚趾头都能想到。

偶尔用一次,用哪个都问题都不大。

一般性能要求稍高的应用场景,cglib和orika完全可以接受。

另外一个考虑的因素,如果项目已经引入了某个依赖,就用那个依赖来做吧,没必要再引入一个第三方依赖。

Das obige ist der detaillierte Inhalt vonDetailliertes Beispiel für das Kopieren von Java-Objekten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Crossplay haben?
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Perfekte Zahl in Java Perfekte Zahl in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur perfekten Zahl in Java. Hier besprechen wir die Definition, Wie prüft man die perfekte Zahl in Java?, Beispiele mit Code-Implementierung.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Leitfaden für Weka in Java. Hier besprechen wir die Einführung, die Verwendung von Weka Java, die Art der Plattform und die Vorteile anhand von Beispielen.

Smith-Nummer in Java Smith-Nummer in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

Fragen zum Java Spring-Interview Fragen zum Java Spring-Interview Aug 30, 2024 pm 04:29 PM

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Brechen oder aus Java 8 Stream foreach zurückkehren? Brechen oder aus Java 8 Stream foreach zurückkehren? Feb 07, 2025 pm 12:09 PM

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

Zeitstempel für Datum in Java Zeitstempel für Datum in Java Aug 30, 2024 pm 04:28 PM

Anleitung zum TimeStamp to Date in Java. Hier diskutieren wir auch die Einführung und wie man Zeitstempel in Java in ein Datum konvertiert, zusammen mit Beispielen.

Java -Programm, um das Kapselvolumen zu finden Java -Programm, um das Kapselvolumen zu finden Feb 07, 2025 am 11:37 AM

Kapseln sind dreidimensionale geometrische Figuren, die aus einem Zylinder und einer Hemisphäre an beiden Enden bestehen. Das Volumen der Kapsel kann berechnet werden, indem das Volumen des Zylinders und das Volumen der Hemisphäre an beiden Enden hinzugefügt werden. In diesem Tutorial wird erörtert, wie das Volumen einer bestimmten Kapsel in Java mit verschiedenen Methoden berechnet wird. Kapselvolumenformel Die Formel für das Kapselvolumen lautet wie folgt: Kapselvolumen = zylindrisches Volumenvolumen Zwei Hemisphäre Volumen In, R: Der Radius der Hemisphäre. H: Die Höhe des Zylinders (ohne die Hemisphäre). Beispiel 1 eingeben Radius = 5 Einheiten Höhe = 10 Einheiten Ausgabe Volumen = 1570,8 Kubikeinheiten erklären Berechnen Sie das Volumen mithilfe der Formel: Volumen = π × R2 × H (4

Wie führe ich Ihre erste Spring -Boot -Anwendung in der Spring Tool Suite aus? Wie führe ich Ihre erste Spring -Boot -Anwendung in der Spring Tool Suite aus? Feb 07, 2025 pm 12:11 PM

Spring Boot vereinfacht die Schaffung robuster, skalierbarer und produktionsbereiteter Java-Anwendungen, wodurch die Java-Entwicklung revolutioniert wird. Der Ansatz "Übereinkommen über Konfiguration", der dem Feder -Ökosystem inhärent ist, minimiert das manuelle Setup, Allo

See all articles