• Anasayfa
  • Eğitimler
    • JavaScript Eğitimi
    • Angular 2 Eğitimi
    • React.js Eğitimi
    • Java 8 Eğitimi
    • Java EE 7 Eğitimi
    • Spring Framework Eğitimi
    • Git Eğitimi
  • Online Eğitimler
    • Online React.js Eğitimi
    • Online Angular 2 Eğitimi
    • Online Spring Boot Eğitimi
  • Referanslar
  • Hakkında
  • İletişim
KodEdu
  • Anasayfa
  • Eğitimler
    • JavaScript Eğitimi
    • Angular 2 Eğitimi
    • React.js Eğitimi
    • Java 8 Eğitimi
    • Java EE 7 Eğitimi
    • Spring Framework Eğitimi
    • Git Eğitimi
  • Online Eğitimler
    • Online React.js Eğitimi
    • Online Angular 2 Eğitimi
    • Online Spring Boot Eğitimi
  • Referanslar
  • Hakkında
  • İletişim

CDI ile JCache Notasyonlarını Kullanalım

  • Posted by Kodedu
  • Categories Genel, Uncategorized, Yazılar
  • Date 3 Kasım 2015

JCache (JSR 107 – Java Temporary Caching API) Java EE 8 altında yer alacak, caching çözümlerine (Hazelcast, EhCache, Coherence vb.) çatı kuran bir standarttır. JCache Java EE 8 kullanıcıları anketinde %9.5 (turuncu) ile önemli bir oran alarak beklenilen bir standart olduğunu ortaya koymuştur.

ResultChart.png
Figure 1. Bkz Java EE 8 Community Survey

JCache aslında Java EE 7 içerisinde yer alacaktı, fakat yetişmediği için Java EE 8’e ötelenmişti.( Bkz. JCache to Miss Java EE 7)

JCache Başlangıç

JCache için daha önce iki yazı hazırlamıştım. Dilerseniz onlardan başlayabilirsiniz. Meselenin iç yüzünü bu şekilde daha iyi anlayabilirsiniz.

  1. JSR 107 – JCache Standardına İlk Bakış

  2. JCache – CacheLoader ve CacheWriter Kullanmak

JCache Notasyonları

Java EE ekosisteminde anotasyonlardan sıkça faydalanıyoruz. JCache içerisindeki kullanımda ise konfigürasyon ve kullanım detaylarını arka plana atarak sade bir kullanım elde ediyoruz.

Anotasyon nedir diyorsanız şu yazıyı öneririm. https://kodedu.com/2014/09/java-8-tekrarli-notasyonlar-nasil-kullanilir/

Şimdi JCache standart notasyonlarını tanıyalım;

JCache Notasyonları
  1. javax.cache.annotation.CacheDefaults

  2. javax.cache.annotation.CacheKey

  3. javax.cache.annotation.CacheResult

  4. javax.cache.annotation.CacheValue

  5. javax.cache.annotation.CachePut

  6. javax.cache.annotation.CacheRemove

  7. javax.cache.annotation.CacheRemoveAll

CacheDefaults

JCache @CacheDefaults notasyonu sınıf başına uygulanır. Tüm alt metodlar bunda tanımlı bilgileri kullanır. Örneğin CacheDefaults notasyonuyla isme göre eşsiz bir cache alanı tanımlayabiliriz. Bu notasyonu işleyecek olan DI (Dependency Injection) çözümü, tanımlı isim bilgisine göre arka planda javax.cache.Cache nesnesi oluşturacaktır.

Örneğin
@CacheDefaults(cacheName = "personCacher")
public class CacheBean {

///

}

CachePut

Bir metodun parametresinde yer alan key bilgisine göre value bilgisini cache alanına ekler. key, @CacheKey notasyonu ile belirtilirken, value @CacheValue ile belirtilir.

Örneğin
@CacheDefaults(cacheName = "personCacher")
public class CacheBean {

@CachePut
//@CachePut(cacheName = "<cache_name>")
public void put(@CacheKey Long id, @CacheValue Person person) {
   //
}

}

Yukarıdaki örnekte Long türündeki key bilgisine göre, Person sınıfı türündeki bir nesne, personCacher içine eklenir. Metod içi boş olabilir veya cache içine eklenen veri kalıcı bir ortama da yazılabilir. Tamamen sizin ihtiyacınıza bağlı bir durum.

CacheResult

Belirli bir cache alanından daha önce eklenen cache verisi elde edilir. Talep edilen veri cache içindeyse metod içine girilmez. Cache dışındaysa metod içerisine girilir ve metod dönüşü cache alanına eklenir.

Örneğin
@CacheDefaults(cacheName = "personCacher")
public class CacheBean {

@CacheResult
public Person get(@CacheKey Long id) {
    Person person = //
    return person;
}

@CachePut
//@CachePut(cacheName = "<cache_name>")
public void put(@CacheKey Long id, @CacheValue Person person) {
   //
}

}

Örneğin yukarıdaki CacheBean#get metodu, key bilgisine göre cache değerini döndürmektedir.

CacheRemove

key bilgisine göre daha evvel eklenen bir girdi cache alanından temizlenir.

Örneğin
@CacheDefaults(cacheName = "personCacher")
public class CacheBean {

@CacheRemove
public void invalidate(@CacheKey Long id) {
    //
}

}

Tüm cache girdilerini silmek için @CacheRemoveAll kullanabiliriz.

Örneğin
@CacheDefaults(cacheName = "personCacher")
public class CacheBean {

@CacheRemoveAll
public void invalidateAll() {
    //
}

}

Uygulama zamanı

javax.cache.annotation.* notasyonları dizayn edilmişlerdir, bundan dolayı bir DI çözümüyle (Spring, CDI, Guice vb.) işlenmelidir. Bu örnekte CDI tercih ettim, ama standart üzeri gittiğimiz için hangi DI teknolojisi kullandığımızın çok önemi yok!

CDI konteyneri bir JavaEE uygulamasında hazır olarak kullanabiliriz veya varsayılan uygulayıcısı JBoss Weld ile bir Java SE uygulamasında da başlatabiliriz. Ben ikincisini tercih ettim.

project tree.png
Figure 2. Proje dizin yapısı

Proje maven yapısında hazırlanmıştır.

  1. pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <packaging>jar</packaging>
    
        <groupId>CDI-JCache</groupId>
        <artifactId>CDI-JCache</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <dependency> (1)
                <groupId>org.jboss.weld.se</groupId>
                <artifactId>weld-se-core</artifactId>
                <version>3.0.0.Alpha13</version>
            </dependency>
            <dependency> (2)
                <groupId>org.jsr107.ri</groupId>
                <artifactId>cache-annotations-ri-cdi</artifactId>
                <version>1.0.0</version>
            </dependency>
            <dependency> (3)
                <groupId>org.jsr107.ri</groupId>
                <artifactId>cache-ri-impl</artifactId>
                <version>1.0.0</version>
            </dependency>
        </dependencies>
    
    </project>
    1 Weld Java SE bağımlılığı
    2 JSR 107 notasyonlarını işleyen CDI bağımlılığı (Bkz. maven.search.org)
    3 JCache varsayılan uygulayıcısı
  2. beans.xml

    CDI aktifleştirilmesi ve konfigürasyonu için şart olan beans.xml dosyası. Burada ayrıca javax.cache.annotation.* notasyonlarını işleyecek CDI kesicilerini (interceptor) tanımlamalıyız.

    <?xml version="1.0" encoding="UTF-8"?>
    <beans
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
        bean-discovery-mode="all">
    
    <interceptors>
        <class>org.jsr107.ri.annotations.cdi.CacheResultInterceptor</class> (1)
        <class>org.jsr107.ri.annotations.cdi.CacheRemoveEntryInterceptor</class> (2)
        <class>org.jsr107.ri.annotations.cdi.CacheRemoveAllInterceptor</class> (3)
        <class>org.jsr107.ri.annotations.cdi.CachePutInterceptor</class> (4)
    </interceptors>
    
    </beans>
    1 @CacheResult sahibi bir metod çağrıldığında işleme geçer
    2 @CacheRemove sahibi bir metod çağrıldığında işleme geçer
    3 @CacheRemoveAll sahibi bir metod çağrıldığında işleme geçer
    4 @CachePut sahibi bir metod çağrıldığında işleme geçer
  3. com.kodcu.*

    1. com.kodcu.Person

      public class Person implements Serializable {
      
          private Long id;
          private String name;
          private String status;
      
          public Person() {
          }
      
          public Person(Long id, String name) {
              this.id = id;
              this.name = name;
          }
      
          public Person(long id) {
              this(id, "Person-" + id);
          }
      
          // getter, setter metodları
      
      
          public void updateStatus() {
              setStatus("Cached " + ThreadLocalRandom.current().nextLong(1, 10000));
          }
      }
    2. com.kodcu.CacheBean

      @CacheDefaults(cacheName = "personCacher")
      public class CacheBean {
      
      
          @CachePut
          public void put(@CacheKey Long id, @CacheValue Person person) {
              person.updateStatus();
          }
      
          @CacheResult
          public Person get(@CacheKey Long id) {
              final Person person = new Person(id);
              person.updateStatus();
              return person;
          }
      
          @CacheRemove
          public void invalidate(@CacheKey Long id) {
      
          }
      
          @CacheRemoveAll
          public void invalidateAll() {
      
          }
      
      }
    3. com.kodcu.App

      public class App {
      
          @Inject
          private CacheBean cacheBean; (3)
      
          public static void main(String[] args) throws Exception {
      
              CDI<Object> cdi = CDI.getCDIProvider().initialize(); (1)
              final App app = cdi.select(App.class).get(); (2)
      
              final CacheBean cacheBean = app.cacheBean;
      
              print("Put first object in cache");
      
              // Put cahce id:1,name:Rahman Usta
              cacheBean.put(1L, new Person(1L));
      
              // Get id:1
              final Person p1 = cacheBean.get(1L);
              print(p1);
              // Get id:1
              final Person p2 = cacheBean.get(1L);
              print(p2);
              // Get id:1
              final Person p3 = cacheBean.get(1L);
              print(p3);
      
              print("\n******\n");
      
              print("Put second object in cache");
              cacheBean.put(2L, new Person(2L));
      
              // Get id:2
              final Person p4 = cacheBean.get(2L);
              print(p4);
              // Get id:2
              final Person p5 = cacheBean.get(2L);
              print(p5);
      
              print("\n******\n");
      
              // Invalidate one
              print("Invalidate first object in cache");
              cacheBean.invalidate(1L);
      
              print(cacheBean.get(1L));
              print(cacheBean.get(2L));
      
              print("\n******\n");
      
              // Invalidate all
              print("Invalidate all in cache");
              cacheBean.invalidateAll();
      
              print(cacheBean.get(1L));
              print(cacheBean.get(2L));
      
          }
      
      
          private static void print(Object object) {
              System.out.println(object);
          }
      
      }
      1 CDI konteyner başlatılıyor.
      2 App türünden CDI nesnesi elde ediliyor.
      3 CacheBean CDI nesnesi enjekte ediliyor.

      App#main metodu çalıştırıldığında aşağıdaki çıktıyı elde ederiz.

      INFO: WELD-ENV-002003: Weld SE container STATIC_INSTANCE initialized
      Kas 02, 2015 11:37:44 PM org.jsr107.ri.annotations.DefaultCacheResolverFactory getCacheResolver
      WARNING: No Cache named 'personCacher' was found in the CacheManager, a default cache will be created.
      
      Put first object in cache (1)
      Person{id=1, name='Person-1', status='Cached 5859'}
      Person{id=1, name='Person-1', status='Cached 5859'}
      Person{id=1, name='Person-1', status='Cached 5859'}
      ******
      Put second object in cache (2)
      Person{id=2, name='Person-2', status='Cached 3832'}
      Person{id=2, name='Person-2', status='Cached 3832'}
      ******
      Invalidate first object in cache (3)
      Person{id=1, name='Person-1', status='Cached 19'}
      Person{id=2, name='Person-2', status='Cached 3832'}
      ******
      Invalidate all in cache (4)
      Person{id=1, name='Person-1', status='Cached 9648'}
      Person{id=2, name='Person-2', status='Cached 9072'}
      Weld SE container STATIC_INSTANCE shut down by shutdown hook
      1 İlk Person nesnesi cache alanına ekleniyor ve her seferinde cache içindeki aynı nesne döndürülüyor.
      2 İkinci Person nesnesi cache alanına ekleniyor ve her seferinde cache içindeki aynı nesne döndürülüyor.
      3 İlk nesne cahce alanından çıkarılıyor, yeni bir talepte bir Person nesnesi elde edilerek cahce tazeleniyor.
      4 İki nesne birden cahce alanından çıkarılıyor, yeni bir talepte birer Person nesnesi elde edilerek cahce tazeleniyor.

Örnek uygulamaya https://github.com/Adopt-a-JSR/JCache-CDI adresinden erişebilirsiniz.

Tekrar görüşmek dileğiyle.

Tag:cdi, javaee8, jcache

  • Share:
author avatar
Kodedu

Previous post

AsciidocFX projesi Duke's Choice Award 2015 ödülünü kazandı
3 Kasım 2015

Next post

Crystal programlama diliyle tanışmaya hazır mısınız?
23 Kasım 2015

You may also like

api-logo
Swagger Nedir? Neden kullanılır?
10 Ekim, 2018
spring-cli-logo
Spring CLI ile Spring Boot Projeleri Hazırlamak
21 Ağustos, 2017
eureka_architecture
Spring Cloud Netflix ve Eureka Service Discovery
3 Temmuz, 2017

Leave A Reply Cevabı iptal et

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta listesine kayıt olun!






Gözde yazılar

JPQL sorgulama dili
13Eki2012
Java EE 7 – Concurrency Utilities
23Eki2013
Java 8 – Tekrarlı Notasyonlar Nasıl Kullanılır?
23Eyl2014
6. Ulusal Yazılım Mühendisliği Sempozyumu (UYMS)
24May2012

Son Yazılar

  • Java’da Record’lar 27 Ocak 2020
  • Swagger Nedir? Neden kullanılır? 10 Ekim 2018
  • Spring CLI ile Spring Boot Projeleri Hazırlamak 21 Ağustos 2017
  • Spring Cloud Netflix ve Eureka Service Discovery 3 Temmuz 2017
  • Online React.js Eğitimi ardından (15-25 Mayıs 2017) 31 Mayıs 2017

Son Yorumlar

  • Coupling ve Cohesion Kavramları Nedir? için Hilal
  • Naïve Bayes Sınıflandırma Algoritması için Rahman Usta
  • Naïve Bayes Sınıflandırma Algoritması için Mete
  • YAML Nedir? Neden YAML Kullanmalıyız? için kara
  • JWT (JSON Web Tokens) Nedir? Ne işe yarar? için Furkan

Get Java Software

Arşivler

Bizi takip edin

React.js Eğitimi Başlıyor
11-22 Eylül, 2017
Eğitmen
Rahman Usta
İletişim

merhaba@kodedu.com

  • Hakkında
  • Gizlilik Politikası
  • İletişim
  • Referanslar
Kodedu Bilişim Danışmanlık
Cemil Meriç mah. Çelebi sok.
No:16/3 Ümraniye/İSTANBUL
Tel: 0850 885 38 65
Alemdağ V.D.: 8960484815

KODEDU © Tüm hakları saklıdır.