التنمية المتسارعة مع Spring Boot DevTools

كيفية تسريع عملية التطوير على Spring Boot مع DevTools وجعل هذه العملية أكثر متعة وإنتاجية؟

تعديل


كالمعتاد عند تطوير برنامج Spring Boot ، فإن الإعداد بسيط للغاية. كل ما عليك القيام به هو إضافة التبعية الصحيحة والانتهاء من ذلك. يجد Spring Boot ذلك ويقوم بتكوين DevTools تلقائيًا وفقًا لذلك.

إذا كنت تستخدم Maven:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> 

إذا كنت تستخدم Gradle:

 configurations { developmentOnly runtimeClasspath { extendsFrom developmentOnly } } dependencies { developmentOnly("org.springframework.boot:spring-boot-devtools") } 

يرجى ملاحظة أن التبعية تم إعلانها على أنها اختيارية. يعد هذا الأمر مهمًا لأن إعلان التبعية هذا يمنع تطبيق تبعية DevTools بشكل عابر على الوحدات الأخرى وفقًا لمشروعك.

إعادة التشغيل التلقائي


عند حدوث تغييرات في الملف في classpath ، ستقوم DevTools تلقائيًا بإعادة تشغيل تطبيق العمل الخاص بك مع التغييرات الجديدة. للتطوير المحلي ، قد يكون ذلك مفيدًا لأنك لا تحتاج إلى إعادة نشر التطبيق يدويًا.

هذا وحده لن يكون مفيدًا للغاية ، لأن إعادة التشغيل قد تستغرق وقتًا طويلاً. لحسن الحظ ، فإن إعادة التشغيل هذه أسرع بكثير من إعادة التشغيل العادية بسبب الخدعة الصعبة التي يستخدمها DevTools.

الحقيقة هي أنه عند تطوير تطبيق ما ، عادة ما تقوم بتغيير فئة أو عدة صفوف وتريد التحقق من النتائج في التطبيق قيد التشغيل للحصول على تعليقات. يمكنك إجراء تغييرات طفيفة على التطبيق الخاص بك ، في حين أن معظم الفئات المحملة تأتي من الأطر ومكتبات الطرف الثالث.

تحت غطاء محرك السيارة لـ Spring DevTools ، يتم استخدام محملان للفئة - القاعدة وإعادة التشغيل . يتم تحميل الفئات التي لا تتغير بواسطة قاعدة اللودر الأساسي . يتم تحميل الفئات التي تعمل معها باستخدام أداة إعادة التشغيل . في كل مرة تقوم بإعادة التشغيل ، يتم إعادة إنشاء أداة تحميل التمهيد. وبالتالي ، فإن إعادة تشغيل التطبيق أسرع بكثير من المعتاد ، ويمكن أن تكون بديلاً حقيقياً لإعادة تحميل فئة ديناميكية باستخدام أدوات مثل JRebel.

تهيئة إعادة التشغيل في IDE


يتم تشغيل إعادة التشغيل في كل مرة يتغير فيها ملف في classpath الخاص بك. ومع ذلك ، تعتمد هذه العملية على IDE الخاص بك. هذا يعني أن مجرد تغيير ملفات جافا الخاصة بك لا يكفي. الشيء المهم هو عندما تقوم IDE بالفعل بتحديث ملفات .class في classpath الخاصة بك.

عند استخدام IntelliJ IDEA ، تحتاج إلى تشغيل أمر build في مشروعك ( Ctrl + F9 أو Build → Build Project ). يمكنك أيضًا تكوين أمر build ليتم تشغيله تلقائيًا في IDEA . بالإضافة إلى ذلك ، يمكنك فتح تكوين بدء تشغيل Spring Boot وتحديد ما يحدث عند بدء تحديث التطبيق ( Ctrl + F10 ):



في مربع التحرير والسرد الأول ، يمكنك تحديد تحديث ملف المشغل لبدء إعادة تشغيل DevTools في كل مرة يتم تنفيذ إجراء التحديث . بدلاً من ذلك ، يمكنك حتى تحديد خيار Hot Swap ومحاولة إعادة تشغيل التطبيق باستخدام DevTools فقط في حالة فشل تنفيذ Hot Swap .

في مربع التحرير والسرد الثاني ، يمكنك تكوين إعادة التشغيل لجميع الموارد الثابتة والقوالب عندما تفقد نافذة IDEA التركيز (على سبيل المثال ، عند التبديل إلى نافذة المتصفح).

في Eclipse ، من السهل بدرجة كافية حفظ ملفاتك.

التنمية فقط


تم تصميم Spring Boot DevTools فقط من أجل التطوير ، وليس لعملية إنتاج التطبيق. إذا اكتشف تطبيقك أنك تعمل في بيئة إنتاج ، فسيتم تعطيل DevTools تلقائيًا.

لهذا الغرض ، كلما قمت بتشغيل التطبيق الخاص بك باعتباره قطعة أثرية معبأة بالكامل ، مثل جرة مع خادم تطبيق متكامل ، فإنه يعتبر تطبيق إنتاج:

 java -jar devtools-example-1.0.0.jar 

ينطبق الأمر نفسه عند بدء تشغيل التطبيق الخاص بك من خلال أداة تحميل فئة خاصة ، على سبيل المثال ، على خادم تطبيقات.

على العكس من ذلك ، عند تشغيل قطع أثرية غير مفككة (على سبيل المثال ، في IDE الخاص بك) ، يعتبر التطبيق الخاص بك في وضع التطوير. الأمر نفسه ينطبق على استخدام spring-boot-plugin لتشغيل التطبيق:

مخضرم:

 mvn spring-boot:run 

Gradle:

 gradle bootRun 

LiveReload


يعد LiveReload أداة مفيدة تتيح لك تحديث صفحة على الفور في متصفح كلما أجريت تغييرات على ملفات مثل HTML و CSS والصور وأكثر من ذلك. يقوم حتى بمعالجة الملفات حسب الحاجة - وهذا يعني تجميع تلقائي لملفات SASS أو LESS.



يبدأ Spring DevTools تلقائيًا مثيل محلي لخادم LiveReload الذي يتتبع ملفاتك. كل ما عليك فعله هو تثبيت ملحق المتصفح ، وقد انتهيت من ذلك. لا يفيد ذلك فقط في تطوير الواجهة الخارجية للتطبيق (في حالة توزيعها كجزء من قطعة أثرية لتطبيق Spring) ، ولكن يمكن استخدامه أيضًا لمراقبة إخراج واجهة برمجة تطبيقات REST وإعادة تحميلها.

تجاوز الملكية


عند تطوير تطبيق محليًا ، يكون لديك عادة احتياجات تكوين مختلفة عن العمل في بيئة الإنتاج. مثال واحد سيكون التخزين المؤقت. في بيئة الإنتاج ، من الأهمية بمكان الاعتماد على ذاكرة التخزين المؤقت المختلفة (مثل ذاكرة التخزين المؤقت لقالب المحرك ، ورؤوس التخزين المؤقت للموارد الثابتة ، وما إلى ذلك). أثناء التطوير ، قد يستخدم البيانات القديمة ولا يعكس أحدث التغييرات. مثال آخر هو قطع الأشجار المتقدمة ، والتي قد تكون مفيدة في التطوير ولكنها مفصلة للغاية بالنسبة لبيئة الإنتاج.

من الصعب للغاية إدارة نوعين من التكوين بنفسك. الأخبار الجيدة هي أن Spring Boot DevTools ، بشكل افتراضي ، يقوم بإعداد العديد من الخصائص للتطوير المحلي الخاص بك.

 spring.thymeleaf.cache=false spring.freemarker.cache=false spring.groovy.template.cache=false spring.mustache.cache=false server.servlet.session.persistent=true spring.h2.console.enabled=true spring.resources.cache.period=0 spring.resources.chain.cache=false spring.template.provider.cache=false spring.mvc.log-resolved-exception=true server.servlet.jsp.init-parameters.development=true spring.reactor.stacktrace-mode.enabled=true 

يمكنك العثور على قائمة بكافة الخصائص في فئة DevToolsPropertyDefaultsPostProcessor .

اتصال عن بعد


بالإضافة إلى التطوير المحلي ، يمكنك أيضًا الاتصال بتطبيق بعيد يقوم بتشغيل DevTools. هذه الأداة غير مخصصة لبيئات الإنتاج حيث إنها قد تشكل خطراً كبيراً على السلامة. ومع ذلك ، يمكن أن يكون مفيدًا للغاية في بيئة ما قبل الإنتاج.

تمكين الاتصال عن بعد


لم يتم تمكين الاتصال عن بعد بشكل افتراضي. تحتاج إلى تمكينه بشكل صريح عن طريق تعديل ملف pom:

 <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludeDevtools>false</excludeDevtools> </configuration> </plugin> </plugins> </build> 

أو باستخدام gradle ، تحتاج إلى تعيين excludeDevtools = false :

 bootWar { excludeDevtools = false } 

ثم تحتاج إلى تعيين كلمة مرور يتم استخدامها للمصادقة عند الاتصال بالتطبيق البعيد:

 spring.devtools.remote.secret=somesecret 

الاتصال بتطبيق بعيد


بعد بدء تشغيل التطبيق عن بُعد ، يمكنك بدء جلسة الاتصال عن بُعد. الآن كل ما عليك فعله هو تشغيل org.springframework.boot.devtools.RemoteSpringApplication بعنوان URL للتطبيق البعيد كوسيطة. يرجى ملاحظة أنه يجب عليك استخدام https إن أمكن.

من السهل بدء اتصال بعيد في IDE الخاص بك. في IDEA ، تحتاج فقط إلى إنشاء تكوين إطلاق جديد. انتقل إلى تشغيل → تحرير التكوينات ... وإنشاء تكوين جديد مع أيقونة + في الزاوية اليسرى العليا. اختر نوع التطبيق.

بالنسبة للفئة الرئيسية ، حدد RemoteSpringApplication من وحدة DevTools وتمرير عنوان URL الخاص بالتطبيق البعيد كوسيطة إلى البرنامج.



بعد بدء هذا التكوين ، سترى مخرجات مماثلة إذا كان الاتصال بالتطبيق البعيد ناجحًا.



بعد الاتصال بتطبيق بعيد ، يراقب DevTools تغييرات مسار الفصل بنفس طريقة التطوير المحلي. ومع ذلك ، بدلاً من إعادة التشغيل المحلية ، يقوم بنقل التغييرات إلى الخادم البعيد ويبدأ إعادة التشغيل هناك. يمكن أن يكون هذا أسرع بكثير من إنشاء تطبيق ونشره على جهاز بعيد.

التكوين العالمي


يمكنك تخصيص DevTools باستخدام خصائص التكوين ، كما هو الحال مع أي تطبيق Spring آخر. هذا يعني عادةً تحرير التطبيق . خصائص مشروعك. هذا التكوين منفصل لكل تطبيق.

ومع ذلك ، في بعض السيناريوهات ، قد يكون من المناسب وجود تكوين عمومي لجميع التطبيقات التي تعمل على نفس الكمبيوتر. يمكنك إنشاء ملف خصائص يسمى .spring-boot-devtools.properties الموجود في دليل $ HOME . ينطبق الإعلان الوارد في هذا الملف على جميع التطبيقات التي تستخدم DevTools.

قيود


تحديث لايف


يبدأ تطبيق Spring باستخدام DevTools تلقائيًا خادم LiveReload. لسوء الحظ ، يمكن بدء مثيل واحد فقط من هذا الخادم في كل مرة. بتعبير أدق ، سوف تعمل المثيل الأول فقط. لا ينطبق هذا فقط على عدة مثيلات لتطبيقات Spring مع DevTools ، ولكن أيضًا على أي تطبيقات أخرى تستخدم أيضًا LiverReload تحت الغطاء ، مثل Gatsby في وضع التطوير.

إذا كنت ترغب في تكوين تطبيق Spring بحيث لا يبدأ تشغيل خادم LiveReload ، فيمكن القيام بذلك في ملف application.properties الخاص بك:

 spring.devtools.livereload.enabled=false 

هوك الاغلاق


تعتمد DevTools على سمة ربط إيقاف التشغيل لفئة SpringApplication . لن يعمل الفصل بشكل صحيح إذا قمت بتعطيل السمة يدويًا باستخدام:

 springApplication.setRegisterShutdownHook(false); 

يتم تمكين السمة افتراضيًا ، لذلك لا داعي للقلق بشأنها إلا إذا قمت بتعطيلها بشكل صريح.

الاصطدامات مع مكتبات الطرف الثالث


على الرغم من أن DevTools يجب أن يعمل بشكل صحيح عادة ، فقد يكون لديهم تعارضات مع مكتبات الطرف الثالث. على وجه الخصوص ، هناك مشكلة معروفة في إلغاء التسلسل باستخدام ObjectInputStream القياسي.

في حالة حدوث مثل هذا التعارض ، يمكنك تعطيل إعادة التشغيل التلقائي من خلال الإعداد:

 spring.devtools.restart.enabled=false 

إعادة تشغيل لن تعمل. ومع ذلك ، لا يزال يتم استخدام أداة تحميل classloader. إذا كنت بحاجة إلى تعطيل برنامج تحميل الفئة بالكامل ، فيجب عليك القيام بذلك قبل بدء تشغيل التطبيق:

 public static void main(String[] args) { System.setProperty("spring.devtools.restart.enabled", "false"); SpringApplication.run(MyApp.class, args); } 

حتى إذا كنت لا تستخدم إعادة التشغيل التلقائي ، فلا يزال بإمكانك استخدام ميزات DevTools الأخرى.

تمكين التهيئة المتأخرة


يمكنك وضع علامة على المكونات الفردية كما تمت تهيئة كسول باستخدام التعليقات التوضيحية @كسولدولا. كانت هذه الميزة متاحة لبعض الوقت. بدءًا من Spring Boot 2.2 ، يمكنك تبديل التهيئة المتأخرة لجميع مكونات الحبة الخاصة بك باستخدام spring.main.lazy-initialization = true .

يمكن استخدام هذا بمفرده أو مع DevTools لإعادة تشغيل أسرع .

يسمح لك DevTools بإعادة تشغيل التطبيق في نفس JVM. تتمثل إحدى الميزات المهمة لإعادة التشغيل السريع في أنه يوفر لـ JIT المزيد من الخيارات لتحسين الكود المستخدم في تشغيل التطبيق الخاص بك. بعد إعادة تشغيل عدة مرات ، يتم تقليل الوقت الأولي البالغ 2500 مللي ثانية بحوالي 80٪ ويقترب من 500 مللي ثانية. مع التهيئة البطيئة ، يمكننا تحقيق نتائج أفضل. عند تثبيت spring.main.lazy-initialization ، يتم إعادة تشغيل تطبيقنا بعد 400 مللي ثانية مباشرة في IDE.

يعد استخدام التهيئة المتأخرة لجميع أنواع حبوبك في تطبيق الإنتاج أمرًا مشكوكًا فيه. يوفر هذا الإجراء مكاسب أداء بدء التشغيل فائقة بسبب طلبات لأول مرة أطول لمكونات الفول الفردية. الأهم من ذلك ، لا يتوقف تطبيقك عن العمل بسرعة. ولكن بدلاً من التعطل فور بدء التطبيق ، لن يفشل إلا بعد طلب المكون المكون بشكل غير صحيح بشكل مباشر. قد يكون ذلك خطيرًا جدًا نظرًا لأنك لن تجد العديد من الأخطاء إلا بعد فوات الأوان. ومع ذلك ، يمكن أن تكون عملية التأخير الشامل مفيدة في تسريع وقت التطوير ، لأنه عند العمل مع وظيفة معينة ، عادة ما تعمل فقط على جزء من التطبيق الخاص بك ، ولا تستخدم الباقي. الحل الوسط المثالي هو تمكين التهيئة المتأخرة بشكل كبير فقط للتنمية المحلية (على سبيل المثال ، استخدام ملف تعريف نابض) وتعطيله للبيئات الأعلى المنشورة.

استنتاج


DevTools يسرع ويبسط تطوير تطبيق Spring Boot من خلال توفير وظيفة إعادة التشغيل التلقائي و LiveReload. بالإضافة إلى ذلك ، فإنه يحدد خصائص متنوعة للقيم الأكثر ملاءمة للتطوير المحلي. بالإضافة إلى ذلك ، يسمح لك بالاتصال عن بعد بالتطبيق الخاص بك وفي الوقت نفسه استخدام معظم وظائفه. عند بدء تشغيل التطبيق في الإنتاج ، لا يتم استخدام DevTools. انظر الوثائق الرسمية للحصول على التفاصيل.

Source: https://habr.com/ru/post/ar479382/


All Articles