5 Şubat 2022 Cumartesi

SpringContext ClassPathScanningCandidateComponentProvider Sınıfı

Giriş
Şu satırı dahil ederiz
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
Örnek
Şöyle yaparız
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;

ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(FooAnnotation.class));

Set<BeanDefinition> beanDefinitions = scanner.findCandidateComponents("com.foo");

if (!CollectionUtils.isEmpty(beanDefinitions)) {
  for (final BeanDefinition beanDefinition : beanDefinitions) {
    Class<?> fooClass = Class.forName(beanDefinition.getBeanClassName());
    ...
  }
}

1 Şubat 2022 Salı

SpringCloud @EnableDiscoveryClient Anotasyonu

Giriş
Açıklaması şöyle
@EnableDiscoveryClient which comes from spring-cloud-commons is the same as @EnableEurekaClient but it is a more generic implementation of “Discovery Service”.

@EnableEurekaClient only works with Eureka whereas @EnableDiscoveryClient works with eureka, consul, zookeeper. But if Eureka is on the application classpath, they are effectively the same.
@EnableZookeeper Anotasyonu
Maven
Şu satırı dahil ederiz
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.5.7</version>
</dependency>
Örnek
Şöyle yaparız
@Configuration
@EnableZookeeper
public class ZooKeeperConfiguration extends ZookeeperProperties {
    public ZooKeeperConfiguration() {
        setConnectString("localhost:2181");
        setBaseSleepTimeMs(1000);
        setMaxRetries(3);
        setSessionTimeoutMs(5000);
    }
}

@Service
public class MyService {
  @Autowired
  private ZooKeeperClient zooKeeperClient;

  public List<String> getNodes(String path) throws KeeperException, InterruptedException {
    return zooKeeperClient.getChildren(path);
  }
}
Açıklaması şöyle
Next, you’ll need to configure the connection to your ZooKeeper server. You can do this by creating a ZooKeeperConfiguration class that extends org.springframework.cloud.zookeeper.ZookeeperProperties and sets the connection properties, like so:

This sets the connection string to localhost:2181 and configures some other properties for the connection.

Finally, you can use the ZooKeeper client in your Spring Boot application by autowiring a ZooKeeperClient instance. 





3 Ocak 2022 Pazartesi

SpringWebFlux Flux.merge

Örnek
Şöyle yaparız
public Flux<Incidence> findAllFlux() {
  Flux<Incidence> lstPre1 = WebClient.create("...").get().retrieve()
.bodyToFlux(Incidence.class);
  Flux<Incidence> lstPre2 = WebClient.create("...").get().retrieve()
.bodyToFlux(Incidence.class);
  Flux<Incidence> lstPro1 = WebClient.create("...").get().retrieve()
.bodyToFlux(Incidence.class);
  Flux<Incidence> lstPro2 = WebClient.create("...").get().retrieve()
.bodyToFlux(Incidence.class);
  return Flux.merge(lstPre1, lstPre2, lstPro1, lstPro2);
}

Flux.delaySequence

Giriş
delayElements metodundan farklı. Açıklaması şöyle. Yani initial delay olarak düşünülebilir.
With this operator, a source emitting at 10Hz with a delaySequence Duration of 1s will still emit at 10Hz, with an initial "hiccup" of 1s. On the other hand, delayElements(Duration) would end up emitting at 1Hz.
Örnek
Şöyle yaparız
@GetMapping("/incidenceFlux/{env}/{server}")
public Flux<Incidence> findAllFlux(@PathVariable String env, @PathVariable String server) {
  return Flux.just(new Incidence(...),
     new Incidence(...),
   new Incidence(...)
    )
    .delaySequence(Duration.ofSeconds(3));
}

13 Aralık 2021 Pazartesi

SpringCache Ehcache 3 Kullanımı

Giriş
Açıklaması şöyle
The EhCache is an open source Java based cache used to boost performance. It stores the cache in memory and disk (SSD).

EhCache used a file called ehcache.xml. The EhCacheCacheManager is automatically configured if the application found the file on the classpath.
Maven
Şu satırı dahil ederiz
<dependency>
<groupId>org.ehcache</groupId> <artifactId>ehcache</artifactId> <version>3.9.6</version> </dependency> <dependency> <groupId>javax.cache</groupId> <artifactId>cache-api</artifactId> <version>1.1.0</version> <scope>runtime</scope> </dependency>
Açıklaması şöyle
You need both JCache and EhCache if you are using EhCache v3. In the previous v2, JCache was not needed as it was not built upon the JSR standard.
Bundan sonra cache ayarlarını ya xml ya da kodla vermek gerekir.

XML İle Belirtmek
application.properties dosyasında şöyle yaparız
spring.cache.jcache.config=classpath:ehcache.xml
ehcache.xml
Örnek
Şöyle yaparız.
<config
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns='http://www.ehcache.org/v3'
  xsi:schemaLocation="http://www.ehcache.org/v3
                      http://www.ehcache.org/schema/ehcache-core.xsd">

  <cache alias="cache_10s">
    <expiry>
      <ttl unit="seconds">10</ttl>
    </expiry>
    <heap unit="entries">10000</heap>
  </cache>

  <cache alias="cache_30s">
    <expiry>
      <ttl unit="seconds">30</ttl>
    </expiry>
    <heap unit="entries">10000</heap>
  </cache>
</config>
Örnek
Şöyle yaparız. Burada offheap ile JVM dışında kulanılabilecek bellek belirtiliyor.
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://www.ehcache.org/v3"
   xmlns:jsr107="http://www.ehcache.org/v3/jsr107"
   xsi:schemaLocation="
     http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd
     http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd">

  <cache alias="allUserCache">
    <key-type>java.lang.String</key-type>
    <value-type>java.util.List</value-type>
    <expiry>
      <ttl unit="seconds">30</ttl>
    </expiry>
    <resources>
      <heap unit="entries">10</heap>
      <offheap unit="MB">10</offheap>
    </resources>
  </cache>
</config>
Kodla Belirtmek
1. org.ehcache.config.builders.CacheManagerBuilder kullanılır
Ehcache 3 CacheManagerBuilder Sınıfı yazında Ehcache3 ayarları görülebilir.
JCacheCacheManager Sınıfı - EhCache 3 yazında Ehcache3 ile Spring'in nasıl birleştirildiği görülebilir.

2. Eh107Configuration kullanılır
Örnek
Şöyle yaparız. Burada  org.ehcache.config.builders.CacheManagerBuilder kullanılarak bir org.ehcache.config.CacheConfiguration yaratılıyor. 

Daha sonra org.ehcache.jsr107.Eh107Configuration kullanılarak CacheConfiguration nesnesi 
JSR-107 javax.cache.configuration.Configuration haline çevriliyor.
Daha sonra JSR-107 configuration nesnesi yine JSR-107 javax.cache.spi.CachingProvider nesnesine takılıyor
import org.ehcache.config.CacheConfiguration;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.ExpiryPolicyBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.MemoryUnit;
import org.ehcache.jsr107.Eh107Configuration;
import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.cache.spi.CachingProvider;
import java.time.Duration;

@Configuration
public class AppConfig {

  @Bean
  public CacheManager EhcacheManager() {

    CacheConfiguration<String, Person> cachecConfig = CacheConfigurationBuilder
      .newCacheConfigurationBuilder(String.class,
                        Person.class,
                        ResourcePoolsBuilder.newResourcePoolsBuilder()
                                .offheap(10, MemoryUnit.MB)
                                .build())
      .withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofSeconds(10)))
      .build();

    CachingProvider cachingProvider = Caching.getCachingProvider();
    CacheManager cacheManager = cachingProvider.getCacheManager();

    javax.cache.configuration.Configuration<String, Person> configuration = Eh107Configuration.fromEhcacheCacheConfiguration(cachecConfig);
    cacheManager.createCache("cacheStore", configuration);
    return cacheManager;
  }
}

SpringData JPA @Query Anotasyonu ve Named Parameter

Giriş
Named Parameter Queries  yavaş olabilir. Açıklaması şöyle
The major issue we might face with this parameterised approach is the query performance.The query might run well in your local environment, but suddenly when you start running in Production environment it starts taking too much of time.This is because of the dynamic binding of the parameters to the query by Spring JPA as it cannot determine the data type of the parameter its binding and has to run through all possible types.
@Param Anotasyonu
Java 8'den önce metod parametrelerinin SQL cümlesine atanması için @Param ile işaretli olması gerekir. Yoksa şöyle bir exception fırlatılır.
java.lang.IllegalArgumentException: Name for parameter binding must not be null or empty! For named parameters you need to use @Param for query method parameters on Java versions < 8.
Java 8'den itibaren derleyiciye -parameters seçeneği geçilir.

Eğer metod imzasında fazla parametre varsa exception fırlatılır.
Örnek
Elimizde şöyle bir kod olsun
@Repository
public interface ParentRepository extends JpaRepository<Parent, String> {

  @Query(value = "SELECT c FROM Child c where c.parent.id =:id")  
  public List<Child> findChildById(String id, Example example, Pageable pageable);

}
Exception olarak şunu alırız
Using named parameters for method public abstract 
java.util.List com.example.test.ParentRepository.findChildById
(java.lang.String,org.hibernate.criterion.Example,
 org.springframework.data.domain.Pageable)
but parameter 'Optional[example]' not found in annotated query 
'SELECT c FROM Child c where c.parent.id =:id'!
Örnek - select
Şöyle yaparız.
@Query("select p from Person p where p.name = :name and p.address=:address")
Person withNameAndAddressQuery(@Param("name")String name, @Param("address")String addr);
Örnek - select
Şöyle yaparız.
@Query("select t from TimeTable t where MONTH(t.date) =:month and YEAR(t.date) =:year")
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
Örnek - count
Şöyle yaparız.
public interface UserRepository extends JpaRepository<User, Long> {

  @Query("select count(u) > 0 from User u where u.email = :email")
  Boolean isEmailExist(@Param("email")String email);
}