개발일기장

Spring 모든 빈 검사하기.. (CommandLineRunner) 본문

Spring Boot

Spring 모든 빈 검사하기.. (CommandLineRunner)

게슬 2023. 8. 14. 16:24
728x90

Spring boot를 시작할 때 모든 직접 추가한 모든 Bean을 확인하고 검사하는 로직이 필요할거 같음..

https://tlqckd0.tistory.com/94

 

Spring 공부 02. 스프링 컨테이너

https://tlqckd0.tistory.com/93 Spring 공부 01. Configuration, Bean import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 이거 사용해서 Config 를 등록 할 수 있다. ApplicationContext a

tlqckd0.tistory.com

그래서 Spring 을 시작하고 나서 바로 실행되게 하는 CommandLineRunner를 사용해서 검사하기로 했음.

 

@Slf4j
@Component
public class Initializer implements CommandLineRunner {

    @PostConstruct
    private void postConstruct(){
        log.info("Start ... ");
    }

    @PreDestroy
    private void preDestory(){
        //DB 연결
        log.info("Destory Program");
    }

    @Override
    public void run(String... args) throws Exception {
        log.info("Starter");
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AdvancedApplication.class);
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName  : beanDefinitionNames){
            BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);

            if(beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION){
                log.info("Path : [{}] / Bean Name : [{}]",beanDefinition.getBeanClassName() ,beanDefinition.getFactoryBeanName());
            }
        }

    }

}

일단 이런거 생성해뒀음.

단순히 이렇게 작성하고 Spirng boot를 시작해보자..

 

위에꺼는 내가 설정한게 맞는데 밑에 뭐 엄청나게 많이 생김

분명 자신이 직접 등록한 Component는 Bean의 Role이 BeanDefinition.ROLE_APPICATION이라고 했으면서 이상한것도 나옴.

        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AdvancedApplication.class, LogTraceConfig.class);
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName  : beanDefinitionNames){
            BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);

            if(beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION){// ??????
                log.info("Path : [{}] / Bean Name : [{}]",beanDefinition.getBeanClassName() ,beanDefinition.getFactoryBeanName());
            }
        }

아마도 웹으로 설정을 해서 이렇게 된게 아닐까? 싶은 생각이 들었음 Jackson이나 Http같은것들이 몇게 보이고 그럼

 

구분을 어떻게 할까? 싶어서 일단 모든 beanDefinition 객체를 그냥 다 찍어보자 .(toString)

 

//내가 한거임 !
 Path : [hello.advanced.app.v3.OrderServiceV3] / Bean Name : [orderServiceV3]
 Generic bean: class [hello.advanced.app.v3.OrderServiceV3]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [C:\Users\tlqck\OneDrive\바탕화면\spring 원리\advanced\advanced\out\production\classes\hello\advanced\app\v3\OrderServiceV3.class]
 
 Path : [hello.advanced.trace.hellotrace.HelloTranceV1] / Bean Name : [helloTranceV1]
 Generic bean: class [hello.advanced.trace.hellotrace.HelloTranceV1]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [C:\Users\tlqck\OneDrive\바탕화면\spring 원리\advanced\advanced\out\production\classes\hello\advanced\trace\hellotrace\HelloTranceV1.class]
 
 Path : [hello.advanced.trace.hellotrace.HelloTranceV2] / Bean Name : [helloTranceV2]
 Generic bean: class [hello.advanced.trace.hellotrace.HelloTranceV2]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [C:\Users\tlqck\OneDrive\바탕화면\spring 원리\advanced\advanced\out\production\classes\hello\advanced\trace\hellotrace\HelloTranceV2.class]
 
 Path : [null] / Bean Name : [logTrace]
 Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=logTraceConfig; factoryMethodName=logTrace; initMethodName=null; destroyMethodName=(inferred); defined in hello.advanced.LogTraceConfig
 
//내가한거 아님 ㅜㅜ
 Path : [org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration] / Bean Name : [org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration]
 Generic bean: class [org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
 
 Path : [org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration] / Bean Name : [propertySourcesPlaceholderConfigurer]
 Root bean: class [org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=propertySourcesPlaceholderConfigurer; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/context/PropertyPlaceholderAutoConfiguration.class]

toString은 이렇게 생겨먹음

아마 그러면 Root Bean은 Root에서 실행될 때 가지고 오는거고

Generic bean의 경우에는 일반적으로 내부에서 Component로 찍어서 들고오는 놈으로 생각하면 될까?

 

그냥 file 이름에 org/springframework 이거 달린놈이

bean 이름에 org.springframework 달린놈을 제외해보자.

 

    @Override
    public void run(String... args) throws Exception {
        log.info("Starter");
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AdvancedApplication.class, LogTraceConfig.class);
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName  : beanDefinitionNames){

            //Bean 이름에 org.springframework 가 포함되면 제외
            if(beanDefinitionName.contains("org.springframework")){
                continue;
            }

            BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);

            //Bean 의 resource 가 org/springframework 에 포함되어 있으면 제외
            if(beanDefinition.getResourceDescription() != null && beanDefinition.getResourceDescription().contains("org/springframework")){
                continue;
            }

            if(beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION){
                log.info("Class Name : [{}] / Bean Name : [{}] / Resource : [{}]"
                        ,beanDefinition.getBeanClassName()
                        ,beanDefinitionName
                        ,beanDefinition.getResourceDescription()
                );
            }
        }

    }

잘 나온다.. 근대 이게 맞는지는 모르겠으니깐 좀더 찾아봐야겠다.. 직접 Bean 주입한 configuration 같은 것도 있고 그러니깐.. 차이점이 뭘까

728x90

'Spring Boot' 카테고리의 다른 글

Spring Boot - AOP (1)  (0) 2023.12.11
Spring Proxy Factory  (1) 2023.12.05
Spring 공부 07. web scope, provider, proxy  (0) 2023.07.17
Spring 공부 06. singleton, prototype  (0) 2023.07.12
Spring 공부 05. Bean Life Cycle  (0) 2023.07.10
Comments