美文网首页
SpringBoot 自定义 AutoConfiguration

SpringBoot 自定义 AutoConfiguration

作者: 走在成长的道路上 | 来源:发表于2019-12-24 15:15 被阅读0次

这两天写使用 netty + springboot 的方式实现代理服务器,在此须希望通过 auto configuration的方式配置。

  1. 定制 XXXProperties 属性
@Data
public class XXXProperties {
    private String key;
    private String value;
    private int weight;
}
  1. 构建 XXXBean 工厂
public class XXXFactoryBean implements FactoryBean<XXXBean>, ApplicationContextAware {

    /**
     * 应用服务器上下文
     */
    private ApplicationContext applicationContext;

    @Getter
    @Setter
    private XXXProperties xxxProperties;

    @Override
    public XXXBean getObject() throws Exception {
        return new XXXBean();
    }

    @Override
    public Class<?> getObjectType() {
        return XXXBean.class;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

}
  1. 注册 XXXBeanSpring 框架
@Component
public class XXXBeanDefinitionRegister implements BeanDefinitionRegistryPostProcessor, EnvironmentAware {

    // 绑定 xxx 前缀开始的属性
    private static final String XXX_PREFIX = "xxx";

    private Environment environment;

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        Binder binder = Binder.get(environment);

        // 没配置xxx, 忽略
        BindResult<XXXProperties> bindResult = binder.bind(XXX_PREFIX, XXXProperties.class);
        if (!bindResult.isBound()) {
            return;
        }
        XXXProperties xxxProperties = bindResult.get();

        if (StringUtils.isEmpty(xxxProperties.getName())) {
            return;
        }
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(ProxyServerFactoryBean.class)
                    // 添加属性参数
                    .addPropertyValue("xxxProperties", xxxProperties)
                    // 生成 XXXBean 实例
                    .getBeanDefinition();
        registry.registerBeanDefinition(xxxProperties.getName(), beanDefinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }
}
  1. 定义 XXXBeanAutoConfiguration 自动导入类

@Configuration
@EnableConfigurationProperties({XXXProperties.class})
public class XXXBeanAutoConfiguration implements ResourceLoaderAware {

    /**
     * 资源加载器
     */
    private ResourceLoader resourceLoader;

    /**
     * XXX 代理配置
     */
    private final XXXProperties xxxProperties;

    public XXXBeanAutoConfiguration(XXXProperties xxxProperties) {
        this.xxxProperties = xxxProperties;
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

}
  1. 若需要在创建过程中需要有数据校验,则需实现 BeanPostProcessor 来实现,比如:
@Component
public class BoundPortCheckerPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof XXXBean) {
            XXXBean server = (XXXBean) bean;
            // 校验数据,如果不符合规则,则直接抛出 BeansException 即可
        }
        return bean;
    }
}
  1. application.yaml 文件中定义即可
xxx:
  yyy: AAAA
  1. 添加依赖
    // 添加 Annotation Processor 模块 (自定义 properties 实例)
    compileOnly "org.springframework.boot:spring-boot-configuration-processor"
  1. 自动启动某些服务

spring 体系下,当 Spring 容器加载所有 bean 并完成初始化之后,会接着回调实现 SmartLifecycle 接口的类中对应的方法(start()方法)。因此,通常情况下,比如 netty 等都可以 SmartLifecycle 接口的方式来进行启动后台 netty 服务。

相关文章

网友评论

      本文标题:SpringBoot 自定义 AutoConfiguration

      本文链接:https://www.haomeiwen.com/subject/bpffoctx.html