MethodBeanDefinition.java
package sprout.beans;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Comparator;
public class MethodBeanDefinition implements BeanDefinition {
private final String name;
private final Class<?> type; // @Bean 메서드의 반환 타입
private final Method factoryMethod;
private final String factoryBeanName; // @Configuration 클래스의 빈 이름
private final Class<?>[] factoryMethodArgumentTypes;
private boolean isProxyTarget = false;
private boolean primary = false;
public MethodBeanDefinition(String name, Class<?> type, Method factoryMethod, String factoryBeanName, Class<?>[] factoryMethodArgumentTypes) {
this.name = name;
this.type = type;
this.factoryMethod = factoryMethod;
this.factoryBeanName = factoryBeanName;
this.factoryMethodArgumentTypes = factoryMethodArgumentTypes;
}
@Override public String getName() { return name; }
@Override public Class<?> getType() { return type; }
@Override public BeanCreationMethod getCreationMethod() { return BeanCreationMethod.FACTORY_METHOD; }
@Override public Constructor<?> getConstructor() { return null; }
@Override public Class<?>[] getConstructorArgumentTypes() { return null; }
@Override public Method getFactoryMethod() { return factoryMethod; }
@Override public String getFactoryBeanName() { return factoryBeanName; }
@Override
public Class<?>[] getFactoryMethodArgumentTypes() {
if (factoryMethodArgumentTypes != null) {
return factoryMethodArgumentTypes;
}
// 파라미터가 없는 경우 -> 반환 타입의 주 생성자 파라미터를 의존성으로 간주
Constructor<?> primaryCtor = Arrays.stream(type.getDeclaredConstructors())
.max(Comparator.comparingInt(Constructor::getParameterCount))
.orElse(null);
return primaryCtor != null ? primaryCtor.getParameterTypes() : new Class<?>[0];
}
@Override public boolean isProxyTarget() { return isProxyTarget; }
public void setProxyTarget(boolean proxyTarget) { isProxyTarget = proxyTarget; }
@Override public boolean isConfigurationClassProxyNeeded() { return false; } // @Bean 메서드는 자체로 Configuration 프록시 대상이 아님
@Override
public boolean isPrimary() {
return primary;
}
public void setPrimary(boolean primary) {
this.primary = primary;
}
}