| name | preboot-core |
| description | Skill do używania biblioteki preboot-core. Użyj tego skilla zawsze gdy użytkownik chce cache z TTL, rate limiting, synchronizację dostępu po kluczu, transakcje programowe, hashowanie parametrów, walidację beanów, konfigurację Jacksona, lub pracuje z infrastrukturą współbieżności. Obejmuje: TTLMap, AccessSynchronizer, RateLimiter, TransactionWrapper, HashUtils, BeanValidator, JsonMapperFactory, JacksonCustomizerAutoConfiguration. Triggeruje się na: TTL cache, rate limiter, token bucket, key-based lock, synchronizacja po kluczu, ReentrantLock, virtual threads, transakcje programowe, REQUIRES_NEW, SHA-1 hash, bean validation, Jackson 3, JsonMapper, auto-configuration, preboot-core, concurrent access, cache eviction, composite key, fair lock. |
preboot-core
Moduł fundacyjny PreBoot.io — dostarcza infrastrukturę współbieżności (TTL cache, rate limiter, key-based synchronization), wrappery transakcyjne, narzędzia hashujące, walidację beanów i auto-konfigurację Jacksona 3.
Zależność Maven
<dependency>
<groupId>io.preboot</groupId>
<artifactId>preboot-core</artifactId>
</dependency>
Wersje zarządzane przez preboot-bom — nie podawaj <version>.
Zależności provided — Twój projekt musi mieć Spring Boot Starter. Opcjonalnie spring-boot-starter-json dla konfiguracji Jacksona.
Szybki start
1. TTL Cache — cache z automatycznym wygasaniem
TTLMap<String, UserSession> sessions = new TTLMap<>(60);
sessions.put("user-123", session);
sessions.put("user-456", anotherSession, 120);
UserSession s = sessions.get("user-123");
2. Key-based synchronization — blokowanie po kluczu zasobu
@Service
public class OrderService {
private final AccessSynchronizer sync = new AccessSynchronizer();
public Order processOrder(String orderId) {
return sync.synchronize(orderId, () -> {
return doExpensiveWork(orderId);
});
}
}
3. Rate limiter — ograniczanie żądań per klient
RateLimiter limiter = new RateLimiter(10);
limiter.acquire("client-A");
boolean ok = limiter.tryAcquire("B");
String result = limiter.executeWithRateLimit("C", () -> callApi());
4. Programowe transakcje
@Service
public class MyService {
private final TransactionWrapper tx;
public void doWork() {
tx.doInTransaction(() -> {
repo.save(entity);
repo.delete(old);
});
tx.doAlwaysInNewTransaction(() -> auditRepo.save(log));
}
}
Główne koncepty
Auto-konfiguracja
preboot-core rejestruje się automatycznie przez Spring Boot auto-configuration (META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports):
- PreBootAutoConfiguration —
@ComponentScan("io.preboot") — skanuje wszystkie moduły preboot
- JsonMapperAutoConfiguration — rejestruje domyślny
JsonMapper bean (Jackson 3) jeśli brak
- JacksonCustomizerAutoConfiguration — wyłącza
FAIL_ON_NULL_FOR_PRIMITIVES (Jackson 3 domyślnie rzuca błąd na null → boolean)
Współbieżność (pakiet io.preboot.core.concurent)
| Klasa | Wzorzec | Zastosowanie |
|---|
AccessSynchronizer | Key-based locking z ReentrantLock | Zapobieganie race conditions na tym samym zasobie |
RateLimiter | Token bucket | Ograniczanie API calls per klient |
Oba zaprojektowane z myślą o Java 21 virtual threads (ReentrantLock zamiast synchronized).
Kolekcje (pakiet io.preboot.core.colections)
TTLMap<K, V> — thread-safe cache z:
- Per-entry TTL (nadpisywalny)
- Background cleanup co 1 sekundę (shared scheduler)
- Opcjonalny eviction callback (
BiConsumer<K, V>)
- Shutdown hook dla graceful cleanup
Transakcje (pakiet io.preboot.core.transaction)
TransactionWrapper — interfejs do programowego zarządzania transakcjami:
doInTransaction() — @Transactional (REQUIRED)
doAlwaysInNewTransaction() — @Transactional(propagation = REQUIRES_NEW)
Przydatne gdy @Transactional na metodzie nie wystarczy (np. część logiki w nowej transakcji).
Narzędzia
| Klasa | Opis |
|---|
HashUtils.getHash(Map) | SHA-1 hash z parametrów, niezależny od kolejności kluczy |
BeanValidator.validate(Object) | Jakarta Bean Validation — rzuca ConstraintViolationException |
JsonMapperFactory.createJsonMapper() | Fabryka skonfigurowanego Jackson 3 JsonMapper |
Typowe przepływy
Cache sesji z callbackiem na eviction
TTLMap<String, WebSocketSession> activeSessions = new TTLMap<>(300,
(sessionId, session) -> {
session.close();
log.info("Session {} expired", sessionId);
}
);
Synchronizacja po kluczu złożonym
import static io.preboot.core.concurent.AccessSynchronizer.compositeKey;
sync.synchronize(compositeKey("tenant", tenantId, "order", orderId), () -> {
return processOrder(tenantId, orderId);
});
Rate limit z custom limitem per klient
RateLimiter limiter = new RateLimiter(5);
limiter.setRateLimit("premium-client", 100);
limiter.executeWithRateLimit(clientId, () -> externalApiCall());
Hashowanie parametrów zapytania (cache key)
Map<String, String> params = Map.of("page", "1", "size", "20", "sort", "name");
String cacheKey = HashUtils.getHash(params);
Walidacja obiektu bez Spring kontekstu
@NotNull String name;
@Min(0) int age;
MyDto dto = new MyDto(null, -1);
BeanValidator.validate(dto);
Pułapki i częste błędy
-
TTLMap.close() — zawsze wywołuj close() gdy kończysz używanie mapy (np. w @PreDestroy). Inaczej eviction callbacks mogą nie zostać wywołane.
-
TTLMap.shutdownCleanupService() — statyczny shutdown. Nie wywoływaj ręcznie — jest automatyczny shutdown hook. Wywołanie zamknie cleanup dla WSZYSTKICH instancji TTLMap.
-
AccessSynchronizer nie jest distributed — działa tylko w ramach jednej JVM. Dla distributed locking użyj Redis/Zookeeper.
-
RateLimiter nie jest distributed — analogicznie, per-JVM. Dla API gateway rate limiting użyj dedykowanego rozwiązania.
-
TransactionWrapper wymaga Spring context — nie zadziała w unit testach bez Spring. Mockuj interfejs TransactionWrapper w testach.
-
Jackson 3 (nie 2) — JsonMapperFactory i auto-konfiguracja używają tools.jackson.databind (Jackson 3), nie com.fasterxml.jackson (Jackson 2). Upewnij się, że Twój projekt ma Jackson 3 na classpath.
-
Pakiet concurent — literówka w nazwie (brak drugiego 'r'), ale jest zamierzona i stabilna.
Kiedy sięgnąć do references/
- api-reference.md — pełne sygnatury metod, typy parametrów, wyjątki, szczegóły implementacji
- examples.md — więcej przykładów użycia, scenariusze zaawansowane, wzorce integracji z innymi modułami preboot