Čo je nové na jar 4.3?

1. Prehľad

Vydanie Spring 4.3 prinieslo niekoľko príjemných vylepšení v oblasti core container, caching, JMS, Web MVC a testovaní podmodulov frameworku.

V tomto príspevku sa budeme zaoberať niekoľkými z týchto vylepšení vrátane:

  • Implicitné vstrekovanie konštruktora
  • Podpora predvolených metód rozhrania Java 8
  • Vylepšené rozlíšenie závislostí
  • Vylepšenia abstrakcie medzipamäte
  • Skladaný @RequestMapping Varianty
  • Poznámky @Requestscope, @Sessionscope, @Applicationscope
  • @RequestAttribute a @SessionAttribute anotácie
  • Podpora verzií knižníc / aplikačných serverov
  • the InjectionPoint trieda

2. Implicitné vstrekovanie konštruktora

Zvážte nasledujúcu triedu služieb:

@Service verejná trieda FooService {súkromné ​​konečné úložisko FooRepository; @Autowired public FooService (FooRepository repository) {this.repository = repository}}

Docela bežný prípad použitia, ale ak zabudnete @Autowired anotácie konštruktora, kontajner vyvolá výnimku hľadajúcu predvoleného konštruktora, pokiaľ výslovne neurobíte zapojenie.

Takže od verzie 4.3 už nemusíte v takomto scenári s jedným konštruktorom špecifikovať explicitnú anotáciu vstrekovania. Toto je obzvlášť elegantné pre triedy, ktoré neobsahujú vôbec žiadne poznámky:

verejná trieda FooService {súkromné ​​konečné úložisko FooRepository; public FooService (FooRepository repository) {this.repository = repository}}

Na jar 4.2 a nižšie nebude nasledujúca konfigurácia pre tento fazuľa fungovať, pretože Spring nebude môcť nájsť predvolený konštruktor pre FooService. Jar 4.3 je inteligentnejšia a automaticky napája konštruktéra:

Podobne ste si to mohli všimnúť @ Konfigurácia triedy historicky nepodporovali injektor konštruktora. Od 4.3 robia a prirodzene umožňujú vynechanie @Autowired aj v scenári jedného konštruktéra:

@ Konfigurácia verejná trieda FooConfiguration {súkromné ​​konečné úložisko FooRepository; public FooConfiguration (FooRepository repository) {this.repository = repository; } @Bean public FooService fooService () {vrátiť nový FooService (this.repository); }}

3. Podpora predvolených metód rozhrania Java 8

Pred jarom 4.3 neboli predvolené metódy rozhrania podporované.

To nebolo ľahké implementovať, pretože ani introspektor JBD JavaBean nezistil predvolené metódy ako prístupové objekty. Od jari 4.3 sú getre a setre implementované ako predvolené metódy rozhrania identifikované počas vstrekovania, čo umožňuje ich použitie napríklad ako bežných preprocesorov pre prístupné vlastnosti, ako v tomto príklade:

verejné rozhranie IDateHolder {void setLocalDate (LocalDate localDate); LocalDate getLocalDate (); default void setStringDate (String stringDate) {setLocalDate (LocalDate.parse (stringDate, DateTimeFormatter.ofPattern ("dd.MM.rrrr"))); }} 

Táto fazuľa môže mať teraz stringDate vložený majetok:

To isté platí pre použitie testovacích anotácií ako @BeforeTransaction a @AfterTransaction na predvolené metódy rozhrania. JUnit 5 už podporuje svoje testovacie anotácie týkajúce sa predvolených metód rozhrania a jar 4.3 nasleduje príklad. Teraz môžete v rozhraní abstrahovať bežnú testovaciu logiku a implementovať ju do testovacích tried. Tu je rozhranie pre testovacie prípady, ktoré zaznamenáva správy pred a po transakciách v testoch:

verejné rozhranie ITransactionalTest {Logger log = LoggerFactory.getLogger (ITransactionalTest.class); @BeforeTransaction default void beforeTransaction () {log.info ("Pred otvorením transakcie"); } @AfterTransaction predvolené neplatné afterTransaction () {log.info ("Po ukončení transakcie"); }}

Ďalšie vylepšenie týkajúce sa anotácií @BeforeTransaction,@AfterTransaction a @ Transakčné je zmiernenie požiadavky, že anotované metódy by mali byť verejné - teraz môžu mať akúkoľvek úroveň viditeľnosti.

4. Vylepšené rozlíšenie závislostí

Najnovšia verzia taktiež predstavuje ObjectProvider, rozšírenie existujúceho ObjectFactory rozhranie s praktickými podpismi ako napr getIfAvailable a getIfUnique získať fazuľa, iba ak existuje, alebo ak je možné určiť jedného kandidáta (najmä: primárneho kandidáta v prípade viacerých zodpovedajúcich fazúľ).

@Service verejná trieda FooService {súkromné ​​konečné úložisko FooRepository; public FooService (ObjectProvider repositoryProvider) {this.repository = repositoryProvider.getIfUnique (); }}

Môžete použiť také ObjectProvider spracovať na účely vlastného rozlíšenia počas inicializácie, ako je uvedené vyššie, alebo uložiť popisovač do poľa pre neskoré rozlíšenie na požiadanie (ako to zvyčajne robí pri ObjectFactory).

5. Vylepšenia abstrakcie medzipamäte

Abstrakcia medzipamäte sa používa hlavne na ukladanie do pamäte hodnôt, ktoré sú náročné na CPU a IO. V konkrétnych prípadoch použitia môže byť daný kľúč požadovaný viacerými vláknami (t. J. Klientmi) paralelne, najmä pri štarte. Podpora synchronizovanej vyrovnávacej pamäte je dlho požadovaná funkcia, ktorá bola teraz implementovaná. Predpokladajme nasledovné:

@Service verejná trieda FooService {@Cacheable (cacheNames = "foos", sync = true) verejné Foo getFoo (ID reťazca) {...}}

Všimnite si sync = true atribút, ktorý povie rámcu, aby pri výpočte hodnoty blokoval všetky súbežné vlákna. Takto sa zabezpečí, že táto intenzívna operácia sa v prípade súbežného prístupu vyvolá iba raz.

Jar 4.3 tiež zlepšuje abstrakciu ukladania do vyrovnávacej pamäte takto:

  • Výrazy SpEL v anotáciách súvisiacich s cache môžu teraz odkazovať na fazuľa (t.j. @ beanName.method ()).
  • ConcurrentMapCacheManager a ConcurrentMapCache teraz podporujú serializáciu položiek vyrovnávacej pamäte pomocou nového storeByValue atribút.
  • @Cacheeable, @CacheEvict, @CachePuta @ Ukladanie do pamäte cache teraz možno použiť ako metaanotácie na vytvorenie vlastných komponovaných anotácií s prepísaním atribútov.

6. Skladané @RequestMapping Varianty

Jarný rámec 4.3 predstavuje nasledujúce zložené varianty @RequestMapping anotácia, ktorá pomáha zjednodušiť mapovanie pre bežné metódy HTTP a lepšie vyjadruje sémantiku metódy anotovanej obsluhy.

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping

Napríklad, @GetMapping je kratšia forma výroku @RequestMapping (metóda = RequestMethod.GET). Nasledujúci príklad ukazuje radič MVC, ktorý bol zjednodušený zložením @GetMapping anotácia.

@Controller @RequestMapping ("/ schôdzky") verejná trieda AppointmentsController {private final AppointmentBook jmenovanieKniha; @Autowired public AppointmentsController (AppointmentBook jmenovacia kniha) {this.appointmentBook = jmenovacia kniha; } @GetMapping public Map get () {return jmenovanieBook.getAppointmentsForToday (); }}

7. @RequestScope, @SessionScope, @ApplicationScope Anotácie

Pri použití komponentov poháňaných anotáciami alebo Java Config sa @RequestScope, @SessionScope a @ApplicationScope anotácie možno použiť na priradenie komponentu k požadovanému rozsahu. Tieto anotácie nielen nastavujú rozsah fazule, ale tiež nastavujú rozsah rozsahu proxy na ScopedProxyMode.TARGET_CLASS.

TARGET_CLASS režim znamená, že proxy CGLIB sa použije na proxyovanie tohto beanu a zaistí, aby ho bolo možné vložiť do iného beanu, a to aj v širšom rozsahu. TARGET_CLASS režim umožňuje proxy server nielen pre rozhrania, ale aj pre triedy.

@RequestScope @Component verejná trieda LoginAction {// ...}
@SessionScope @Component verejná trieda UserPreferences {// ...}
@ApplicationScope @Component verejná trieda AppPreferences {// ...}

8. @RequestAttribute a @SessionAttribute Anotácie

Dve ďalšie poznámky pre vloženie parametrov požiadavky HTTP do Kontrolór sa objavili metódy, a to @RequestAttribute a @SessionAttribute. Umožňujú vám prístup k niektorým už existujúcim atribútom spravovaným globálne (tj. Mimo servera) Kontrolór). Hodnoty pre tieto atribúty môžu byť poskytované napríklad registrovanými inštanciami javax.servlet.Filter alebo org.springframework.web.servlet.HandlerInterceptor.

Predpokladajme, že sme zaregistrovali nasledujúce HandlerInterceptor implementácia, ktorá analyzuje žiadosť a pridá Prihlásiť sa parameter relácie a ďalší dopyt parameter na požiadavku:

public class ParamInterceptor extends HandlerInterceptorAdapter {@Override public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {request.getSession (). setAttribute ("login", "john"); request.setAttribute ("dopyt", "faktúry"); návrat super.preHandle (požiadavka, odpoveď, obsluha); }}

Takéto parametre môžu byť vložené do a Kontrolór inštancia so zodpovedajúcimi anotáciami k argumentom metódy:

@GetMapping public String get (@SessionAttribute String login, @RequestAttribute String query) {return String.format ("login =% s, query =% s", login, dopyt); }

9. Podpora verzií knižníc / aplikačných serverov

Jar 4.3 podporuje nasledujúce verzie knižníc a generácie serverov:

  • Hibernácia ORM 5.2 (stále podporuje aj verzie 4.2 / 4.3 a 5.0 / 5.1, s podporou 3.6 už teraz)
  • Jackson 2.8 (minimálne od jari 4.3 zvýšené na Jackson 2.6+)
  • OkHttp 3.x (stále podporuje OkHttp 2.x vedľa seba)
  • Netto 4.1
  • Splatnosť 1.4
  • Tomcat 8.5.2 ako aj 9.0 M6

Jar 4.3 navyše obsahuje aktualizovaný ASM 5.1 a Objenesis 2.4 do spring-core.jar.

10. InjectionPoint

The InjectionPoint trieda je nová trieda predstavená na jar 4.3, ktorá poskytuje informácie o miestach, kde sa injekčne podáva konkrétna fazuľa, či už ide o parameter metódy / konštruktora alebo pole.

Typy informácií, ktoré môžete nájsť pomocou tejto triedy, sú:

  • Lúka objekt - môžete získať injekčný bod zabalený ako a Lúka objekt pomocou getField () metóda, ak sa fazuľa vstrekuje do poľa
  • MethodParameter - môžeš zavolať getMethodParameter () metóda na získanie bodu vstrekovania zabaleného ako a MethodParameter objekt, ak je fazuľa vložená do parametra
  • Poslanec - volanie getMember () metóda vráti entitu obsahujúcu injektovanú fazuľu zabalenú do a Poslanec objekt
  • Trieda - získať deklarovaný typ parametra alebo poľa, do ktorého sa fazuľa vstrekla, pomocou getDeclaredType ()
  • Anotácia [] - pomocou getAnnotations () Metóda umožňuje získať pole anotačných objektov, ktoré predstavujú anotácie spojené s poľom alebo parametrom
  • AnnotatedElement - hovor getAnnotatedElement () aby bol bod vpichu zabalený ako AnnotatedElement objekt

Prípad, v ktorom je táto trieda veľmi užitočná, je, keď chceme vytvárať Logger fazuľa podľa triedy, do ktorej patrí:

@Bean @Scope ("prototyp") verejný Logger Logger (InjectionPoint InjectionPoint) {return Logger.getLogger (InjectionPoint.getMethodParameter (). GetContainingClass ()); }

Fazuľa musí byť označená a prototyp rozsah tak, aby sa pre každú triedu vytvoril iný záznamník. Ak vytvoríte a singleton fazuľa a injektujte na viac miest, pružina vráti prvý narazený injekčný bod.

Potom môžeme fazuľu vpichnúť do našej AppointmentsController:

@Autowired private Logger logger;

11. Záver

V tomto článku sme diskutovali o niektorých nových funkciách predstavených vo verzii 4.3.

Prebrali sme užitočné anotácie, ktoré eliminujú štandardný štítok, nové užitočné metódy vyhľadávania a vkladania závislostí a niekoľko podstatných vylepšení v rámci webu a možností ukladania do pamäte cache.

Zdrojový kód článku nájdete na GitHub.