19 Nisan 2021 Pazartesi

IdendityHashMap Sınıfı

Giriş
Örnek ver

Logback logback.xml

Giriş
1. Appender'lar tanımlanır. Appender'larda encoder + layout bilgisi bulunur
2. paket isimleri veya sınıflar için logger ve seviyeleri tanımlanır.
3. Appender'lar root logger'a eklenir

Dosyanın Yolu
Açıklaması şöyle
The program uses a default configuration file named logback.xml or logback-test.xml, which should be located in the classpath in our case, we put the file in java/main/resources.

If neither of these files is found on the classpath, logback will default to invoking BasicConfigurator which will set up a minimal configuration. This minimal configuration consists of a ConsoleAppender attached to the root logger. The output is formatted using a PatternLayoutEncoder set to the pattern %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n. Moreover, by default the root logger is assigned the DEBUG level.
Farklı Bir Yol Kullanmak
Açıklaması şöyle
If you want to use a different configuration file, you can specify its location by setting the logback.configurationFile system property to the file path, like this:

java -Dlogback.configurationFile=/path/to/logback.xml
You can set the system property programmatically in your application code, like this:

System.setProperty("logback.configurationFile", "/path/to/logback.xml");

This should be done before Logback is initialized (i.e., before any logging calls are made). Once the system property is set, Logback will use the specified configuration file instead of the default one.

Örnek
Ben logback.xml dosyasını src/main/resource/logback.xml olarak sevmiyorum. 
1. maven-resources-plugin ile bu dosyayı jar ile aynı seviyeye kopyalıyorum. 
2. Uygulamayı çalıştırırken logback.xml dosyasını belirtiyorum
java -Dlogback.configurationFile=file:logback.xml -jar myjar.jar
Dosyadaki Hatalar
Dosyadaki hataları bulmak için şöyle yaparız
-Dlogback.statusListenerClass=ch.qos.logback.core.status.OnConsoleStatusListener
configuration tag
debug="true" yaparsak, logback başlarken bazı bilgileri gösterir. Açıklaması şöyle
You can add the debug="true" attribute to the <configuration> element to enable debug of the logback configuration. It will print the configuration to the console
Örnek - scanPeriod
Şöyle yaparız. scanPeriod kaç saniyede bir xml dosyasını tekrar okuyacağını belirtir.
<configuration debug="false" scan="true", scanPeriod=20">
appender tag
name Alanı
Örnek
Şöyle yaparız.
<configuration>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    ...
  </appender>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    ...
  </appender>

  <root level="debug">
    <appender-ref ref="FILE" />
    <appender-ref ref="STDOUT" />
  </root>
</configuration>
Örnek
Şöyle yaparız.
<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <layout class="com.touchcorp.touchpoint.utils.MaskingPatternLayout">
          <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </layout>
    </encoder>
  </appender>

  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logs/touchpoint.log</file>
      <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
        <fileNamePattern>logs/touchpoint.%i.log.zip</fileNamePattern>
        <minIndex>1</minIndex>
         <maxIndex>3</maxIndex>
      </rollingPolicy>

      <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
        <maxFileSize>10MB</maxFileSize>
      </triggeringPolicy>
      <encoder>
        ...
      </encoder>
  </appender>


  <logger name="com.touchcorp.touchpoint" level="DEBUG" />
  <logger name="org.springframework.web.servlet.mvc" level="TRACE" />

  <root level="INFO">
    <appender-ref ref="FILE" />
    <appender-ref ref="STDOUT" />
  </root>
</configuration>
Örnek
Şöyle yaparız
<configuration>
  <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

  <appender name="file" class="ch.qos.logback.core.FileAppender">
    <file>logback.log</file>
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="INFO">
    <appender-ref ref="console" />
    <appender-ref ref="file" />
  </root>

  <logger name="com.example.javasandbox" level="WARN" />
</configuration>
encoder tag
Örnek
Şöyle yaparız
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="INFO">
    <appender-ref ref="STDOUT"/>
  </root>

  <logger name="com.ning.http.client" level="WARN"/>
</configuration>

17 Nisan 2021 Cumartesi

PipedInputStream Sınıfı

Giriş
Açıklaması şöyle
There are use cases where data need to be read from source to a sink without modification. In code this might look quite simple: for example in Java, you may read data from one InputStream chunk by chunk into a small buffer (typically 8KB), and feed them into the OutputStream, or even better, you could create a PipedInputStream, which is basically just a util that maintains that buffer for you. 

RecordComponent Sınıfı

getType metodu
Şöyle yaparız
List<?> componentTypes = Stream
    .of(X.class.getRecordComponents())
    .map(RecordComponent::getType)
    .toList();

for (Constructor<?> c : X.class.getDeclaredConstructors())
    if (Arrays.asList(c.getParameterTypes()).equals(componentTypes))
        System.out.println(c);


16 Nisan 2021 Cuma

Lambda ve Yerel Değişken

Lambda Yerel Değişkene Erişebilir
Ancak bu değişken "effectively final" olmalı. Açıklaması şöyle.
Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.
Örnek
Şu kod derlenmez. Çünkü lambda içinde yerel değişken değiştiriliyor.
int ordinal = 0;
list.forEach(s -> {
  ...
  ordinal++;
});
Örnek
Şu kod derlenmez. Çünkü lambda içinde yerel değişken değiştiriliyor.
int sum = 0;
list.forEach(e -> { sum += e.size(); });
Aynı Kısıtlama Instance Member İçin Geçerli Değil
Açıklaması şöyle
There's a simple, straightforward answer to why instance variables can always be captured: this is always effectively final. That is, there is always one known fixed object at the time of the creation of a lambda accessing an instance variable
Yerel Değişken Capture Ediliyorsa Her Seferinde Yeni Lambda Instance Yaratılır
Açıklaması şöyle
Simply said, if a lambda expression does not capture values, it will be a singleton that is re-used on every invocation.

13 Nisan 2021 Salı

Lombok @Singular Anotasyonu

Giriş
Şu satırı dahil ederiz
import lombok.Singular;
Açıklaması şöyle
When the @Singular annotation is placed on a collection property, Lombok creates special builder methods to individually add items to that collection, rather than adding the entire collection at once. This is particularly nice for tests as creating small collections in Java is not concise.
Örnek
Şöyle yaparız
@Value
@Builder(toBuilder = true)
public class User {
  @NonNull
  UUID userId;
  @NonNull
  String email;
  @Singular
  Set<String> favoriteFoods;
  @NonNull
  @Builder.Default
  String avatar = “default.png”;
}

User user = User.builder()
  .userId(UUID.random())
  .email(“grubhub@grubhub.com”)
  .favoriteFood(“burritos”)
  .favoriteFood(“dosas”)
  .build()

Lombok @FieldDefaults Anotasyonu - Üye Alanları Örneğin Private ve Final Yapar

Giriş
Şu satırı dahil ederiz
import lombok.experimental.FieldDefaults;
Açıklaması şöyle
This annotation provides a way to set default modifiers for the fields in a class. You can control the access level of fields and specify whether they should be final. This is particularly useful in Spring-based applications where you might want to establish consistent field-level access control without explicitly declaring it for each field.
Açıklaması şöyle
When you annotate a class with @FieldDefaults, you can specify two key elements:

Access Level: The visibility of the fields, such as PRIVATE, PROTECTED, PACKAGE, or PUBLIC. The default value is PRIVATE.
Final: A Boolean value specifying whether the fields should be final. The default is false.

makeFinal Alanı
Açıklaması şöyle. Yani @Data ile üretilecek setter metodları engelleyebilir
Setting makeFinal = true works well when you are creating immutable classes, but it does limit the functionality of other Lombok annotations like @Setter. In classes annotated with @Data, the makeFinal = true setting will essentially disable the generation of setter methods, because final fields cannot be modified once initialized.
Örnek
Şöyle yaparız
import lombok.Data;
import lombok.experimental.FieldDefaults; import lombok.AccessLevel; @Data @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) public class SecureBook { String title; String author; int pages; }
Örnek
Elimizde şöyle bir kod olsun
@Slf4j
@RequiredArgsConstructor
@FieldDefaults(makeFinal=true, level=AccessLevel.PRIVATE)
public class UserService {
  @NonNull UserDao userDao;
}
Açıklaması şöyle
The @FieldDefaults annotation adds the final and private modifiers to all of the fields.