개발/Spring & Springboot

[Spring] Bean 생성시 이름 바꾸기

뚜키 💻 2022. 4. 7. 23:27
반응형

[Spring] Bean 생성시 이름 바꿔서 만들어주기

 

환경)

Spring 4.3.30

 

 

Spring에서는 Bean을 생성하고 관리해준다.

Bean이란 Spring IoC 컨테이너가 관리하는 자바 객체를 말한다.

Spring에서 Bean을 생성할때 지정되는 이름을 변경해줄수가있다.

 

주로 클래스명이 같을때 빈이름 중복을 피하려고 이 처리를 해주는경우가 많은것같다

 

 

Spring에서는 BeanNameGenerator 구현체를 이용해 Bean이름을 만들어 등록한다.

 

 * Copyright 2002-2007 the original author or authors.

package org.springframework.beans.factory.support;

import org.springframework.beans.factory.config.BeanDefinition;

/**
 * Strategy interface for generating bean names for bean definitions.
 *
 * @author Juergen Hoeller
 * @since 2.0.3
 */
public interface BeanNameGenerator {

	/**
	 * Generate a bean name for the given bean definition.
	 * @param definition the bean definition to generate a name for
	 * @param registry the bean definition registry that the given definition
	 * is supposed to be registered with
	 * @return the generated bean name
	 */
	String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry);

}

 

 

이 BeanNameGenerator의 구현체를 만들어서 처리해주자

 

import java.util.Set;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.stereotype.Service;

public class SimpleBeanNameGenerator implements BeanNameGenerator {

    private final AnnotationBeanNameGenerator defaultGenerator = new AnnotationBeanNameGenerator();
    
    @Override
    public String generateBeanName(final BeanDefinition definition, final BeanDefinitionRegistry registry) {
        // 여기서 원해는 패턴으로 Bean 이름을 다시 만들어서 return해주면 됨
        String result = this.defaultGenerator.generateBeanName(definition, registry);
        
        if(isTarget(definition)) {
            result = result.replaceAll("Impl$", "");
        }
        
        return result;
    }
    
    private boolean isTarget(final BeanDefinition definition) {
        if (definition instanceof AnnotatedBeanDefinition) {
            final Set<String> annotationTypes = getAnnotationTypes(definition);
            
            for (final String annotationType : annotationTypes) {
                if (annotationType.equals(Service.class.getName())) {
                    return true;
                }
            }

        }
        return false;
    }
    
    private Set<String> getAnnotationTypes(final BeanDefinition definition) {
        final AnnotatedBeanDefinition annotatedDef = (AnnotatedBeanDefinition) definition;
        final AnnotationMetadata metadata = annotatedDef.getMetadata();
        return metadata.getAnnotationTypes();
    }

}

SimpleBeanNameGenerator이라는 클래스를 만들어서 구현체를 만들었다.

generateBeanName 를 재정의해서 내가 원하는 문자열로 만드는 처리를 해주면 된다.

 

위의 소스같은 경우는 @Service Annotation이 붙어있으면 impl이라는 글자를 제거해서 Bean 이름을 만들어주는 소스다

 

 

 

이제 새로만든 BeanNameGenerator를 등록해줘야 동작을 한다

스프링은 앱 어플리케이션이 켜질때 ComponentScan을 이용하여 빈을 등록하는데 그 부분에 적용해준다

 

 

나는 설정파일이 자바로 되어있어서 @ComponentScan 안에 nameGenerator를 추가해주었다

@ComponentScan(
        nameGenerator = SimpleBeanNameGenerator.class
        ,...
)

 

만약 xml에서 component scan 설정이 들어가있다면 아래와 같이 지정해주면된다

<context:component-scan base-package="aaa" name-generator="common.config.SimpleBeanNameGenerator">
    ...
</context:component-scan>

 

 

 

 

 

반응형