Reflaction API란?
https://syongsyong2.tistory.com/96
스프링 컨테이너는 애플리케이션을 초기화하고 빈을 생성하는 과정에서 Reflection을 사용하여 빈의 정보를 수집하고 유지한다.
스프링에서 빈을 정의하는 메타데이터를 담고 있는 인터페이스이다. 이 객체는 빈의 클래스, 스코프, 생성자 및 프로퍼티 등의 정보를 포함한다.
public class BeanInfoExample {
public static void main(String[] args) {
// AnnotationConfigApplicationContext를 통해 컨텍스트를 생성
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 빈 등록을 위한 BeanFactory
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
// 빈의 메타데이터를 정의하는 BeanDefinition 생성
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(MyBean.class);
// 빈을 등록
beanFactory.registerBeanDefinition("myBean", beanDefinition);
// 빈 이름으로 BeanDefinition 가져오기
BeanDefinition myBeanDefinition = beanFactory.getBeanDefinition("myBean");
// BeanDefinition에서 정보 추출
String beanClassName = myBeanDefinition.getBeanClassName();
String[] propertyNames = myBeanDefinition.getPropertyValues().getPropertyNames();
// 빈의 정보 출력
System.out.println("Bean Class Name: " + beanClassName);
System.out.println("Bean Property Names: " + String.join(", ", propertyNames));
// 컨텍스트 종료
applicationContext.close();
}
// 간단한 빈 클래스 정의
static class MyBean {
private String name;
public void setName(String name) {
this.name = name;
}
}
}
Bean 을 관리하고 생성하는 주요 인터페이스 중 하나이며, 여러 메소드를 통해 빈의 메타데이터에 접근할 수 있다.
getBeanDefinitionNames() : 컨테이너에 등록된 모든 빈의 이름을 문자열 배열로 반환
getBeanDefinition(String beanName) : 지정된 빈의 BeanDefinition을 반환. BeanDefinition에는 빈의 클래스 타입, 스코프, 생성자 인자, 속성 등의 메타데이터가 포함된다.
getBean(String beanName) : 지정된 이름의 빈 인스턴스를 반환. 빈의 인스턴스를 얻으면 해당 객체의 클래스 타입 등을 통해 reflection을 사용하여 더 많은 정보를 얻을 수 있다.
// ApplicationContext 생성
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
// 등록된 모든 빈의 이름 얻기
String[] beanNames = context.getBeanDefinitionNames();
for (String beanName : beanNames) {
// 각 빈의 BeanDefinition 얻기
BeanDefinition beanDefinition = ((AbstractApplicationContext) context).getBeanFactory().getBeanDefinition(beanName);
// BeanDefinition을 통한 메타데이터 활용
String className = beanDefinition.getBeanClassName();
ScopeMetadata scopeMetadata = beanDefinition.getScopeMetadata();
// 클래스 정보 등을 통해 reflection으로 더 많은 정보 얻기
Class<?> beanClass = Class.forName(className);
// 원하는 작업 수행
// ...
}
스프링 컨테이너에서 빈이 생성되거나 초기화 될 때 추가적인 작업을 수행할 수 있는 인터페이스이다. BeanPostProcessor는 빈이 초기화되기 전과 후에 콜백 메서드를 제공하며, 여기서 Reflection을 통해 빈의 정보를 확인하거나 수정할 수 있다.
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 빈 초기화 전에 수행할 작업 (콜백 메서드)
// 여기서 reflection을 통해 빈의 정보에 접근 가능
System.out.println("Before Initialization - Bean Name: " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 빈 초기화 후에 수행할 작업 (콜백 메서드)
// 여기서 reflection을 통해 빈의 정보에 접근 가능
System.out.println("After Initialization - Bean Name: " + beanName);
return bean;
}
}
@Configuration
public class AppConfig {
// 컨테이너에 등록
@Bean
public MyBeanPostProcessor myBeanPostProcessor() {
return new MyBeanPostProcessor();
}
// 다른 빈들을 정의
// ...
}
스프링은 애플리케이션이 실행되는 초기 단계에서 Reflection API를 사용하여 빈의 정보를 수집하고, 이 정보는 ApplicationContext를 통해 런타임에도 관리된다. 이를 통해 스프링 컨테이너는 위의 컴포넌트들을 활용하여 동적으로 생성된 빈의 상태를 추적하고 필요한 작업을 수행할 수 있다.