Daily Notebook

[Spring] private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

by 배부른코딩로그
💡 로그를 찍을 때, 제목 한 줄에 들어있는 의미를 파악해보자!

목표

  • `private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());`의 의미를 설명할 수 있다.
  • 의미가 분명한 로깅 코드를 작성할 수 있다.

 

자바 프로그래밍을 작성한다면, 로그를 찍는 것은 필수적이다.

private static final Logger LOGGER = LoggerFactory.getLogger(this.class);

순수 자바에서는 위와 같이 사용을 했었고, 스프링에서도 아무생각 없이 코드를 복붙했었다.

기능상의 문제는 없지만, 스프링의 DI를 이해한다면, 불필요한 자원 낭비를 피할 수 있다.

 

스프링에서는 다음과 같이 LOGGER를 생성하는 것을 권장한다.

private final Logger logger = LoggerFactory.getLogger(this.getClass());

왜 위 방식을 권장할까?

 

 

🔥 Line by line 분석

🍖 스프링. static을 뺀 이유!

static을 선언하면 객체 생성할 때 마다 해당 객체를 매번 생성하지 않고 초기 클래스 로딩 시 한 번만 생성해서 사용하게 된다. 하지만, Spring에서는 객체를 싱글턴 패턴으로 디자인하지 않아도 DI Container에서 객체의 생명주기를 싱글턴과 유사하게 관리해준다. 따라서, static으로 선언하여 Perm 영역의 공간을 불필요하게 소비할 필요가 없다.

※ Perm(Permanent Generation)영역이란?
객체의 생명주기가 영구적일 것으로 생각되는 객체를 관리하며,
이 영역에서 관리되는 객체는 GC대상에서 제외된다.

 

🍖 final로 선언하는 이유!

Logger 객체는 초기 생성된 이후 변경될 필요가 없다.

따라서, final 상수로 선언하여 개발자의 실수에서 보호하고 코드의 유지보수와 가독성을 높이기 위함이다.

상수 선언 시 변수명도 대문자로 사용하기 때문에 객체 내부에서 의미가 분명하게 사용할 수 있다.

 

💡 결론

결국, 이를 권장하는 이유는 다음과 같다.

 

1) 모든 클래스에서든 변경 없이 사용 가능.

private final Logger logger = LoggerFactory.getLogger(this.getClass());

약간, 보일러 플레이트 코드 같지만, 한 줄 복붙만으로 바로바로 사용할 수 있다는 장점이 있다.

 

2) 클래스 변수 선언 vs. 인스턴스 변수 선언에 따른 장단점.

 

a.  Advantages for declaring loggers as static

  1. common and well-established idiom
  2. less CPU overhead: loggers are retrieved and assigned only once, at hosting class initialization
  3. less memory overhead: logger declaration will consume one reference per class

 

b. Disadvantages for declaring loggers as static

  1. For libraries shared between applications, not possible to take advantage of repository selectors. It should be noted that if the SLF4 J binding and the underlying API ships with each application (not shared between applications), then each application will still have its own logging environment.
  2. not IOC-friendly

 

c. Advantages for declaring loggers as instance variables

  1. Possible to take advantage of repository selectors even for libraries shared between applications. However, repository selectors only work if the underlying logging system is logback-classic. Repository selectors do not work for the SLF4J+log4 j combination.
  2. IOC-friendly

 

d. Disadvantages for declaring loggers as instance variables

  1. Less common idiom than declaring loggers as static variables
  2. higher CPU overhead: loggers are retrieved and assigned for each instance of the hosting class
  3. higher memory overhead: logger declaration will consume one reference per instance of the hosting class

 

e. Explanation

Static logger members cost a single variable reference for all instances of the class whereas an instance logger member will cost a variable reference for every instance of the class. For simple classes instantiated thousands of times there might be a noticeable difference.

However, more recent logging systems, e.g log4j or logback, support a distinct logger context for each application running in the application server. Thus, even if a single copy of log4j.jar or logback-classic.jar is deployed in the server, the logging system will be able to differentiate between applications and offer a distinct logging environment for each application.

More specifically, each time a logger is retrieved by invoking LoggerFactory.getLogger() method, the underlying logging system will return an instance appropriate for the current application. Please note that within the same application retrieving a logger by a given name will always return the same logger. For a given name, a different logger will be returned only for different applications.

If the logger is static, then it will only be retrieved once when the hosting class is loaded into memory. If the hosting class is used in only in one application, there is not much to be concerned about. However, if the hosting class is shared between several applications, then all instances of the shared class will log into the context of the application which happened to first load the shared class into memory - hardly the behavior expected by the user.

 

 

출처

 

Last Updated. 2022. 08. 27.

 

반응형

블로그의 정보

배부른코딩로그

배부른코딩로그

활동하기