Field Injection은 Spring Framework와 같은 의존성 주입(Dependency Injection) 프레임워크에서 사용되는 주입 방법 중 하나입니다. Field Injection은 클래스의 멤버 변수 (필드)에 어노테이션을 사용하여 의존성을 주입하는 방식입니다. 예를 들어, @Autowired 어노테이션을 사용하여 필드에 의존성을 주입하는 것이 Field Injection의 예입니다.

Field Injection이 좋지 않은 이유는 다음과 같습니다:

  1. 의존성이 숨겨짐: Field Injection을 사용하면 의존성이 클래스의 필드에 직접 주입되므로, 이를 클래스의 생성자나 메서드 매개변수를 통해 명시적으로 주입하는 것보다 의존성이 숨겨질 수 있습니다. 이로 인해 클래스의 의존성 관계가 명확하지 않고, 코드의 가독성과 유지보수성이 저하될 수 있습니다.
  2. 테스트 어려움: Field Injection을 사용하면 테스트 시 해당 필드에 대한 의존성을 주입하기 어려울 수 있습니다. 특히 단위 테스트에서 이 필드에 대한 가짜 (모의) 의존성을 주입하거나 값을 모의하는 것이 어려울 수 있습니다.
  3. 의존성 주입 순서 문제: Field Injection은 의존성 주입 순서에 따른 문제를 일으킬 수 있습니다. 예를 들어, 필드를 초기화하기 위해 다른 의존성이 먼저 주입되어야 하는 경우, 순서 문제로 인해 예기치 않은 동작이 발생할 수 있습니다.
  4. 클래스에 직접 접근: Field Injection을 사용하면 클래스의 필드에 직접 접근이 가능하므로, 클래스 내부의 상태를 변경하거나 다른 객체와 상호작용하는 부분에서 의존성 주입을 통제하기 어려워질 수 있습니다.
  5. 의존성 관리 어려움: Field Injection을 사용하면 클래스가 여러 개의 의존성을 가질 때 어떤 의존성이 주입되었는지 명확하게 파악하기 어려울 수 있습니다.

그러므로, 대부분의 경우에는 Constructor Injection 또는 Setter Injection과 같은 명시적인 의존성 주입 방법을 사용하는 것이 권장됩니다. 이러한 방식을 사용하면 의존성 관리와 테스트 용이성을 향상시키고, 코드의 가독성을 향상시킬 수 있습니다. Field Injection은 간단한 코드에서는 사용될 수 있지만, 대규모 또는 복잡한 프로젝트에서는 피하는 것이 좋습니다.

반응형

T000000001 T000000002 T000000003 T000000004 T000000005 ... 의 유형에서 한개씩 늘어나게 코딩 하는 자바 코드

 

public class NextString {
    public static String getNextString(String currentString) {
        String prefix = currentString.substring(0, 1); // 문자열의 첫 글자 (여기서는 "T") 추출
        int number = Integer.parseInt(currentString.substring(1)); // 숫자 부분 추출 후 정수로 변환

        // 다음 문자열을 만들기 위해 숫자 부분에 1을 더하고, 다시 문자열로 변환
        String nextNumber = String.format("%09d", number + 1);

        // 다음 문자열을 반환
        return prefix + nextNumber;
    }

    public static void main(String[] args) {
        String currentString = "T000000001"; // 입력된 문자열
        String nextString = getNextString(currentString); // 다음 문자열 계산
        System.out.println(nextString); // 결과 출력
    }
}

반응형

클로드의 예시

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;

import com.example.model.Data;

public class WebClientExample {

    public static void main(String[] args) {
        WebClient webClient = WebClient.create("http://example.com");

        Data data = new Data("Sample Data");

        webClient.post()
                .uri("/api/data")
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(data))
                .retrieve()
                .bodyToMono(String.class)
                .map(ResponseEntity::ok)
                .onErrorResume(WebClientResponseException.class,
                        ex -> ex.getRawStatusCode() == 404 ? Mono.just(ResponseEntity.notFound().build()) : Mono.error(ex))
                .subscribe(response -> handleResponse(response));
    }

    private static void handleResponse(Object response) {
        System.out.println("Response received: " + response);
    }
}

 

이를 응용 하여 

 

@Configuration 에 빈으로 등록

 

private HttpClient httpClientConfig(int sec){
    int timeOut = sec * 1000;
    return HttpClient.create()
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, timeOut)
            .responseTimeout(Duration.ofMillis(timeOut))
            .doOnConnected(conn -> conn
                    .addHandlerLast(new ReadTimeoutHandler(timeOut, TimeUnit.MILLISECONDS))
                    .addHandlerLast(new WriteTimeoutHandler(timeOut, TimeUnit.MILLISECONDS)));
}

private ExchangeStrategies exchangeStrategiesConfig(){
    ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder()
            .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(1024*1024*50))
            .build();
    exchangeStrategies
            .messageWriters().stream()
            .filter(LoggingCodecSupport.class::isInstance)
            .forEach(writer -> ((LoggingCodecSupport)writer).setEnableLoggingRequestDetails(true));

    return exchangeStrategies;
}

private ExchangeFilterFunction logRequest(){
    return ExchangeFilterFunction.ofRequestProcessor(
            clientRequest -> {
                log.debug("Request: {} {}", clientRequest.method(), clientRequest.url());
                clientRequest.headers().forEach((name, values) -> values.forEach(value -> log.debug("{} : {}", name, value)));
                return Mono.just(clientRequest);
            }
    );
}

private ExchangeFilterFunction logResponse(){
    return ExchangeFilterFunction.ofResponseProcessor(
            clientResponse -> {
                log.debug("Response: {}", clientResponse.statusCode());
                clientResponse.headers().asHttpHeaders().forEach((name, values) -> values.forEach(value -> log.debug("{} : {}", name, value)));
                return Mono.just(clientResponse);
            }
    );
}

@Bean(name = "testWebClient")
    public WebClient testWebClient() {
        return WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClientConfig(15)))
                .baseUrl("http://localhost:8080")
                .exchangeStrategies(exchangeStrategiesConfig())
                .filter(logRequest())
                .filter(logResponse())
                .build();

    }

 

어쩌다보니 필터 로깅 하는 거까지 하게 됬습니다.

 

 

 

@Service
@RequiredArgsConstructor
@Slf4j
public class Client {
    private final WebClient testWebClient;

    public Mono<String> testWebClient(final MultiValueMap<String, HttpEntity<?>> formData) {
        return testWebClient.post()
                .uri(uriBuilder -> uriBuilder
                        .path("/test")
                        .build())
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .bodyValue(formData)
                .retrieve()
                .bodyToMono(String.class)
                .doOnNext(responseBody -> log.debug("Body: {}", responseBody.trim()));
    }
}

 

 

빈으로 등록한 웹클라이언트를 가져와서 서비스코딩 해주고

 

MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();

formData.add("subject", "테스트");

client.testWebClient(formData, fsr.contentLength()).subscribe(
                        responseString -> { //이하생략

 

 

반응형

Ehache로 추가하고 삭제하고.. 글이 참 많지만

모든 캐시들을 삭제하는 건 글이 별로 없기에 작성한다!

 

Ehcache에 대한 설명과 Config 만드는 법은 아래 글을 참고!

https://kagoon.tistory.com/56

 

spring cache 를 사용 하기 위한 ehcache 사용법

강준한 입니다. 감동을 줄 뻔한 이야기로 시작해보죠. 아들이 치매에 걸린 아버지와 같이 있습니다. 아버지는 멀리 있는 새를 보고 아들에게 물었습니다, 저게 무어냐? 아들이 말하죠... 까마귀

kagoon.tistory.com

 

Class 안에 아래 코드를 적어준다!

 

@Autowired
    private CacheConfig ehcacheManager;

    public void cacheClear () {
    
        CacheManager cacheManager = ehcacheManager.EhcacheManager();
        cacheManager.getCacheNames().forEach(cacheName -> cacheManager.getCache(cacheName).clear());
        
    }

 

그럼 만들어둔 캐싱을 하나씩 불러와 결론적으로 전체 삭제가 되는 것을 확인할 수 있다!

필자의 경우 혹시 모를 실패나 성공 여부를 확인하기 위해 cacheClaer메소드 안을 try catch로 잡았고,

String을 리턴값으로 줘 확인 가능하도록 코드를 구성했다 ㅎㅎ

반응형

+ Recent posts