Újdonságok 4.3 tavasszal?
1. Áttekintés
A 4.3 tavaszi kiadás szép finomításokat hozott a magtárolóba, a gyorsítótárba, a JMS-be, a Web MVC-be és a keretrendszer almoduljainak tesztelésébe.
Ebben a bejegyzésben néhány ilyen fejlesztést tárgyalunk, többek között:
- Implicit konstruktor injekció
- Java 8 alapértelmezett interfész-módszerek támogatása
- A függőségek jobb megoldása
- Gyorsítótár-absztrakció finomításai
- Komponált @RequestMapping Változatok
- @Requestscope, @Sessionscope, @Applicationscope Annotations
- @RequestAttribute és @SessionAttribute annotációk
- A könyvtárak / alkalmazáskiszolgálók verzióinak támogatása
- a InjectionPoint osztály
2. Implicit konstruktor injekció
Vegye figyelembe a következő szolgáltatási osztályt:
@Service public class FooService {private final FooRepository repository; @Autowired public FooService (FooRepository repository) {this.repository = repository}}
Elég gyakori eset, de ha elfelejtette a @Autowired megjegyzés a konstruktoron, a konténer kivételt vet egy alapértelmezett konstruktort keresve, hacsak nem kifejezetten nem végzi el a huzalozást.
Tehát a 4.3-tól kezdődően már nem kell megadnia egy kifejezett injektálási megjegyzéseket egy ilyen kivitelező esetében. Ez különösen elegáns azoknál az osztályoknál, amelyek egyáltalán nem tartalmaznak kommentárokat:
public class FooService {private final FooRepository repository; nyilvános FooService (FooRepository repository) {this.repository = repository}}
A 4.2-es és az azt követő tavasszal ennek a babnak a következő konfigurációja nem fog működni, mert a Spring nem fogja megtalálni az alapértelmezett konstruktort FooService. A 4.3 tavasz okosabb, és automatikusan meghúzza a kivitelezőt:
Hasonlóképpen észrevehette ezt @ Konfiguráció osztályok történelmileg nem támogatták a konstruktor injektálását. 4.3-tól kezdve megteszik, és természetesen megengedik a kihagyást @Autowired egy kivitelező esetén is:
@Configuration public class FooConfiguration {private final FooRepository repository; public FooConfiguration (FooRepository repository) {this.repository = repository; } @Bean public FooService fooService () {return new FooService (this.repository); }}
3. Java 8 alapértelmezett interfész-módszerek támogatása
A 4.3 tavasz előtt az alapértelmezett interfész-módszerek nem voltak támogatva.
Ezt nem volt könnyű megvalósítani, mert még a JDK JavaBean introspektorja sem észlelte az alapértelmezett módszereket hozzáférőként. A 4.3 tavasz óta az alapértelmezett interfész-módszerekként megvalósított getterek és beállítók azonosításra kerülnek az injektálás során, ami lehetővé teszi, hogy ezeket például a hozzáférhető tulajdonságok közös előprocesszoraként használják, például ebben a példában:
nyilvános felület IDateHolder {void setLocalDate (LocalDate localDate); LocalDate getLocalDate (); alapértelmezett void setStringDate (String stringDate) {setLocalDate (LocalDate.parse (stringDate, DateTimeFormatter.ofPattern ("dd.MM.yyyy"))); }}
Ennek a babnak most lehet stringDate injektált vagyon:
Ugyanez vonatkozik a (z) tesztjegyzetek használatára is @BeforeTransaction és @AfterTransaction az alapértelmezett interfész-módszerekről. A JUnit 5 már támogatja az alapértelmezett interfész-módszerek tesztjegyzeteit, és a 4.3-as rugó követi a vezetést. Most elvonatkoztathatja a közös tesztelési logikát egy felületen, és megvalósíthatja a tesztosztályokban. Itt található a tesztesetek kezelőfelülete, amely naplózza az üzeneteket a tesztek tranzakciói előtt és után:
nyilvános felület ITransactionalTest {Logger log = LoggerFactory.getLogger (ITransactionalTest.class); @BeforeTransaction alapértelmezett void beforeTransaction () {log.info ("A tranzakció megnyitása előtt"); } @AfterTransaction alapértelmezett érvénytelen afterTransaction () {log.info ("A tranzakció lezárása után"); }}
Újabb javulás az annotációkkal kapcsolatban @BeforeTransaction,@AfterTransaction és @ Tranzakció a megjegyzéssel ellátott módszerek követelményének enyhítése nyilvános - most bármilyen láthatósági szintjük lehet.
4. A függőségek jobb megoldása
A legújabb verzió bemutatja a ObjectProvider, a meglévő kiterjesztése ObjectFactory interfész praktikus aláírásokkal, mint pl getIfAvailable és getIfUnique a babot csak akkor kapja meg, ha létezik, vagy ha egyetlen jelölt meghatározható (különösen: elsődleges jelölt több egyező bab esetén).
@Service public class FooService {private final FooRepository repository; public FooService (ObjectProvider repositoryProvider) {this.repository = repositoryProvider.getIfUnique (); }}
Használhat ilyeneket ObjectProvider kezelni egyedi felbontási célokra az inicializálás során, a fentiek szerint, vagy tárolja a fogantyút egy mezőben a késői igény szerinti felbontáshoz (mint általában egy ObjectFactory).
5. Gyorsítótár-absztrakció finomításai
A gyorsítótár-absztrakciót elsősorban CPU-t és IO-t fogyasztó értékek gyorsítótárához használják. Különleges felhasználási esetekben egy adott kulcsot több szál (azaz kliens) kérhet párhuzamosan, főleg indításkor. A szinkronizált gyorsítótár-támogatás egy régóta kért szolgáltatás, amelyet most megvalósítottak. Tegyük fel a következőket:
@Service public class FooService {@Cacheable (cacheNames = "foos", sync = true) public Foo getFoo (String id) {...}}
Figyelje meg a szinkron = igaz attribútum, amely arra utasítja a keretet, hogy blokkolja az egyidejű szálakat az érték kiszámítása közben. Ez biztosítja, hogy ezt az intenzív műveletet egyszerre lehessen használni egyidejű hozzáférés esetén.
A 4.3 tavasz a következőképpen javítja a gyorsítótár-absztrakciót is:
- A gyorsítótárral kapcsolatos megjegyzések SpEL-kifejezései most babokra (azaz @ beanName.method ()).
- ConcurrentMapCacheManager és ConcurrentMapCache Most támogassa a gyorsítótár-bejegyzések sorosítását egy új storeByValue tulajdonság.
- @Cache, @CacheEvict, @CachePut, és @Caching most meta-annotációkként használhatók egyedi komponált kommentek létrehozására attribútum felülírásokkal.
6. Összeállítva @RequestMapping Változatok
A Spring Framework 4.3 a következő módszerszintű komponált változatokat mutatja be @RequestMapping olyan kommentárok, amelyek egyszerűsítik a szokásos HTTP módszerek leképezését és jobban kifejezik az annotált kezelő módszer szemantikáját.
- @GetMapping
- @PostMapping
- @PutMapping
- @DeleteMapping
- @PatchMapping
Például, @GetMapping a mondás rövidebb formája @RequestMapping (módszer = RequestMethod.GET). A következő példa egy MVC vezérlőt mutat be, amelyet egyszerűsítettek egy komponenssel @GetMapping annotáció.
@Controller @RequestMapping ("/ kinevezések") public class AppointmentsController {private final AppointmentBook kinevezési könyv; @Autowired public AppointmentsController (találkozókönyv találkozókönyv) {this.appointmentBook = találkozókönyv; } @GetMapping public Map get () {return találkozóBook.getAppointmentsForToday (); }}
7. @RequestScope, @SessionScope, @ApplicationScope Megjegyzések
Annotáció-vezérelt összetevők vagy Java Config használata esetén a @RequestScope, @SessionScope és @ApplicationScope kommentárokkal lehet hozzárendelni egy komponenst a kívánt hatókörhöz. Ezek a kommentárok nemcsak a bab hatókörét, hanem a hatókör proxy módját is ScopedProxyMode.TARGET_CLASS.
TARGET_CLASS mód azt jelenti, hogy a CGLIB proxy-t fogják használni ennek a babnak a proxyzására és annak biztosítására, hogy bármilyen más babba be lehessen injektálni, még szélesebb körben is. TARGET_CLASS mód lehetővé teszi a proxy-t nemcsak az interfészek, hanem az osztályok számára is.
@RequestScope @Component nyilvános osztály LoginAction {// ...}
@SessionScope @Component public class UserPreferences {// ...}
@ApplicationScope @Component public class AppPreferences {// ...}
8. @RequestAttribute és @SessionAttribute Megjegyzések
Még két megjegyzés a HTTP-kérelem paramétereinek beinjekciózásához Vezérlő megjelentek a módszerek, nevezetesen @RequestAttribute és @SessionAttribute. Lehetővé teszik néhány, már létező, globálisan (azaz a Vezérlő). Ezeknek az attribútumoknak az értékeit megadhatják például regisztrált példányai javax.servlet.Szűrő vagy org.springframework.web.servlet.HandlerInterceptor.
Tegyük fel, hogy a következőket regisztráltuk HandlerInterceptor a kérelmet elemző és hozzáadódó megvalósítás Belépés paraméter a munkamenethez és egy másik lekérdezés paraméter egy kéréshez:
public class ParamInterceptor kiterjeszti a HandlerInterceptorAdapter {@Orride public boolean preHandle (HttpServletRequest kérés, HttpServletResponse válasz, Object handler) dobja a Kivételt {request.getSession (). setAttribute ("login", "john"); request.setAttribute ("lekérdezés", "számlák"); return super.preHandle (kérés, válasz, kezelő); }}
Ilyen paramétereket lehet injektálni a Vezérlő példány a metódus argumentumok megfelelő kommentárjaival:
@GetMapping public String get (@SessionAttribute String login, @RequestAttribute String query) {return String.format ("login =% s, query =% s", bejelentkezés, lekérdezés); }
9. Könyvtárak / alkalmazáskiszolgálók verzióinak támogatása
A 4.3 tavasz a következő könyvtár verziókat és szerver generációkat támogatja:
- Hibernált ORM 5.2 (továbbra is támogatja a 4.2 / 4.3 és az 5.0 / 5.1-et is, a 3.6 már elavult)
- Jackson 2,8 (minimum 2,6+ -ra emelve a 4.3 tavasztól)
- OkHttp 3.x (továbbra is támogatja az OkHttp 2.x-et egymás mellett)
- Netty 4.1
- Undertow 1.4
- A Tomcat 8.5.2, valamint a 9.0 M6
Ezenkívül a 4.3 tavasz beágyazza a frissített ASM 5.1 és Objenesis 2.4 fájlokat rugómag.jar.
10. InjectionPoint
A InjectionPoint osztály a 4.3 tavasszal bevezetett új osztály, amely információkat nyújt azokról a helyekről, ahol az adott babot injekciózzák, legyen az metódus / konstruktor paraméter vagy mező.
Az osztály segítségével az alábbi típusú információk találhatók:
- Terület tárgy - megszerezheti az injekció beadásának pontját a Terület objektumot a getField () módszer, ha a babot egy mezőbe injektálják
- MethodParameter - hívhatsz getMethodParameter () módszer a befecskendezési pont megszerzésére a MethodParameter objektum, ha a babot egy paraméterbe injektálják
- Tag - hívás getMember () A metódus az a Tag tárgy
- Osztály - megkapja annak a paraméternek vagy mezőnek a deklarált típusát, amelybe a babot injektálták, a getDeclaredType ()
- Megjegyzés [] - a getAnnotations () módszerrel lekérheti az Annotation objektumok tömbjét, amelyek a mezőhöz vagy paraméterhez tartozó kommentárokat képviselik
- AnnotatedElement - hívás getAnnotatedElement () hogy az injekciózási pontot tekerje be egy AnnotatedElement tárgy
Olyan eset, amikor ez az osztály nagyon hasznos, amikor létrehozni akarunk Logger bab azon osztály alapján, amelyhez tartoznak:
@Bean @Scope ("prototípus") nyilvános naplózó (InjectionPoint injectionPoint) {return Logger.getLogger (injectionPoint.getMethodParameter (). GetContainingClass ()); }
A babot a-val kell meghatározni prototípus hatókört úgy, hogy minden osztályhoz külön naplózót hozzanak létre. Ha létrehoz egy szingli babot és több helyen beadja az injekciót, a tavasz visszaadja az első találkozási pontot.
Ezután beadhatjuk a babot a magunkba AppointmentsController:
@Autowired private Logger logger;
11. Következtetés
Ebben a cikkben megvitattuk a 4.3 tavasszal bevezetett új funkciókat.
Foglalkoztunk olyan hasznos kommentárokkal, amelyek kiküszöbölik a kazánlapot, a függőség felkutatásának és injektálásának új hasznos módszereiről, valamint számos jelentős fejlesztésről az interneten és a gyorsítótárban.
A cikk forráskódját a GitHubon találja meg.