빈이 머야.. 무서어..

고뱅쟁이·2020년 6월 4일
0
post-thumbnail

궁금증

spring framework를 제대로 공부하지 않은 상태에서 kafka ReplyingkafkaTemplate 예제를 따라하고 있었다.

@SpringBootApplication
public class KRequestingApplication {

    public static void main(String[] args) {
        SpringApplication.run(KRequestingApplication.class, args).close();
    }

    @Bean
    public ApplicationRunner runner(ReplyingKafkaTemplate<String, String, String> template) {
        return args -> {
            ProducerRecord<String, String> record = new ProducerRecord<>("kRequests", "foo");
            RequestReplyFuture<String, String, String> replyFuture = template.sendAndReceive(record);
            SendResult<String, String> sendResult = replyFuture.getSendFuture().get(10, TimeUnit.SECONDS);
            System.out.println("Sent ok: " + sendResult.getRecordMetadata());
            ConsumerRecord<String, String> consumerRecord = replyFuture.get(10, TimeUnit.SECONDS);
            System.out.println("Return value: " + consumerRecord.value());
        };
    }

    @Bean
    public ReplyingKafkaTemplate<String, String, String> replyingTemplate(
            ProducerFactory<String, String> pf,
            ConcurrentMessageListenerContainer<Long, String> repliesContainer) {

        return new ReplyingKafkaTemplate<>(pf, repliesContainer);
    }

    @Bean
    public ConcurrentMessageListenerContainer<String, String> repliesContainer(
            ConcurrentKafkaListenerContainerFactory<String, String> containerFactory) {

        ConcurrentMessageListenerContainer<String, String> repliesContainer =
                containerFactory.createContainer("replies");
        repliesContainer.getContainerProperties().setGroupId("repliesGroup");
        repliesContainer.setAutoStartup(false);
        return repliesContainer;
    }

    @Bean
    public NewTopic kRequests() {
        return TopicBuilder.name("kRequests")
            .partitions(10)
            .replicas(2)
            .build();
    }

    @Bean
    public NewTopic kReplies() {
        return TopicBuilder.name("kReplies")
            .partitions(10)
            .replicas(2)
            .build();
    }

}
레퍼런스 문서의 예제(링크는 여기)

replykafka에 대한 블로그는 나중에..하겠읍니다.

코드를 처음 봤을 때 드는 생각은
어..음.... 저게 단가... 저거만 하면 카프카에 전송을 할 수 있다고..???
음그래.. 러너는 run하면 실행되는거겠군.. 그래서 send도 있고.. 그래..
음..근데 다른 메소드는 하는거없이 그냥 저렇게 하고 끝내면 어떻게 돌아가는거지..
뭐야 @_@
음과 그래의 향연이었다.
어노테이션 자체가 너무 생소했기 때문이기도 하고 개념도 잡히지 않은상태에서 무작정 따라하기엔 힘들었다. 우선 메소드마다 빈이라는애가 붙여있는데 얘가 뭔지부터 찾아보기로 했다.

빈이란?

비니 아니다.

원빈 아니다.

빈을 이해하기 전에..

IoC 컨테이너, 의존성 주입이라는 용어부터 숙지해야 하더라.
위 코드에서 봤듯이 Main메소드에서 한것은 run한것 밖에 없다.
보통은 개발자가 1~10까지 다 해야하는데 1 4 10 정도로 만 챙겨주면 나머지는 알아서 컨테이너가 다해준다라고 생각하면 이해하기 쉬울 것 같다.
개발자는 Configuration 설정(1) 하고 비즈니스로직 구현하고(4,10)의 느낌으로만 챙기면 된다.
컨테이너가 알아서 하니까 IoC(inversion of Control,제어의 역전) 개발자가 아닌 컨테이너가 제어권을 가져간다. 그래서 IoC 컨테이너다!
IoC 컨테이너가 객체의 생성 소멸등의 제어를 하니까
객체가 필요할 때 컨테이너가 의존성을 주입한다. 뭐 이런 느낌으로 받아들였다.

진짜 빈이란 무엇인가

IoC 컨테이너가 관리하는 싱글톤 객체가 Bean이다.

내가 만든 클래스외부 라이브러리 클래스
@Controller@Bean
@Service
@Repository
@Component

외부 라이브러리 클래스를 Bean으로 만들고 싶을 때 직접 클래스에 어노테이션을 붙일 수 가 없어서 아래처럼 메소드에다가 붙여서 객체 생성해서 리턴하는 형식으로 사용한다고 한다.

    @Bean
    public ReplyingKafkaTemplate<String, String, String> replyingTemplate(
            ProducerFactory<String, String> pf,
            ConcurrentMessageListenerContainer<Long, String> repliesContainer) {

        return new ReplyingKafkaTemplate<>(pf, repliesContainer);
    }

그래서 메소드명만 다르게해서 리턴값을 동일하게 하면 에러난다.(궁금하면 한번 해보세요.)

Parameter 0 of method replyingTemplate in com.example.demo.ReplyingkafkaApplication required a single bean, but 2 were found:
	- producerFactory1: defined by method 'producerFactory1' in com.example.demo.ReplyingkafkaApplication
	- producerFactory2: defined by method 'producerFactory2' in com.example.demo.ReplyingkafkaApplication

결론

  1. @Bean이란 외부 라이브러리 갖다 쓰고싶을 때 쓰는 거 그리고 쓰기위해서 메소드를 쓴거임.
  2. 왜 메소드를 썼는지 이제 이해가 되었다.
  3. 엄청 검색해봤는데 내가 느끼기에 어렵게 써져있어서 이해하기 힘들었다.
  4. 내 글도 어려울 수 있다.
  5. 이제 안무서어
profile
냥이들과 함께하는 만년 초보 개발자

1개의 댓글

comment-user-thumbnail
2022년 3월 23일

감사합니당

답글 달기