package quant.rich.emoney.config;

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import lombok.extern.slf4j.Slf4j;
import quant.rich.emoney.interfaces.IConfig;
import quant.rich.emoney.service.ConfigService;

/**
 * 配置类工厂
 * @param <T> 配置类
 * 
 */
@Slf4j
public class ConfigServiceFactoryBean<T extends IConfig<T>> implements FactoryBean<T>, BeanNameAware {

    private final Class<T> targetClass;
    
    private String beanName;

    @Autowired
    private AutowireCapableBeanFactory beanFactory;
    
    @Autowired
    private ConfigService configService;

    public ConfigServiceFactoryBean(Class<T> targetClass) {
        this.targetClass = targetClass;
    }
    
    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }

    @Override
    public T getObject() throws Exception {
        ConstructionGuard.enter(targetClass);
        try {
            T bean = configService.getConfig(targetClass);
            beanFactory.autowireBean(bean);
            beanFactory.initializeBean(bean, beanName);
            //configService.saveOrUpdate(bean);
            return bean;
        }
        catch (Exception e) {
            log.error("无法载入配置类: " + targetClass.getName(), e);
            throw e;
        }
        finally {
            ConstructionGuard.exit(targetClass);
        }
    }

    @Override
    public Class<?> getObjectType() {
        return targetClass;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}
