class EasyormConfiguration {

    static {

    }

    @Bean
    @ConditionalOnMissingBean
    public EntityFactory entityFactory(ObjectProvider<EntityMappingCustomizer> customizers) {
        MapperEntityFactory factory = new MapperEntityFactory();
        for (EntityMappingCustomizer customizer : customizers) {
            customizer.custom(factory);
        }
        return factory;
    }

    @Bean
    @ConditionalOnMissingBean
    @SuppressWarnings("all")
    public RDBDatabaseMetadata databaseMetadata(Optional<SyncSqlExecutor> syncSqlExecutor,
                                                Optional<ReactiveSqlExecutor> reactiveSqlExecutor,
                                                EasyormProperties properties) {
        RDBDatabaseMetadata metadata = properties.createDatabaseMetadata();
        syncSqlExecutor.ifPresent(metadata::addFeature);
        reactiveSqlExecutor.ifPresent(metadata::addFeature);
        if (properties.isAutoDdl() && reactiveSqlExecutor.isPresent()) {
            for (RDBSchemaMetadata schema : metadata.getSchemas()) {
                schema.loadAllTableReactive()
                      .block(Duration.ofSeconds(30));
            }
        }
        return metadata;
    }

    @Bean
    @ConditionalOnMissingBean
    public DatabaseOperator databaseOperator(RDBDatabaseMetadata metadata) {

        return DefaultDatabaseOperator.of(metadata);
    }

    @Bean
    public QueryHelper queryHelper(DatabaseOperator databaseOperator) {
        return new DefaultQueryHelper(databaseOperator);
    }

    @Bean
    public BeanPostProcessor autoRegisterFeature(RDBDatabaseMetadata metadata) {
        CompositeEventListener eventListener = new CompositeEventListener();
        metadata.addFeature(eventListener);
        return new BeanPostProcessor() {
            @Override
            public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {<FILL_FUNCTION_BODY>}
        };
    }


    @Bean
    public CreatorEventListener creatorEventListener() {
        return new CreatorEventListener();
    }


    @Bean
    public ValidateEventListener validateEventListener() {
        return new ValidateEventListener();
    }

    @Bean
    public EntityEventListener entityEventListener(ApplicationEventPublisher eventPublisher,
                                                   ObjectProvider<SqlExpressionInvoker> invokers,
                                                   ObjectProvider<EntityEventListenerCustomizer> customizers) {
        DefaultEntityEventListenerConfigure configure = new DefaultEntityEventListenerConfigure();
        customizers.forEach(customizer -> customizer.customize(configure));
        EntityEventListener entityEventListener = new EntityEventListener(eventPublisher, configure);
        entityEventListener.setExpressionInvoker(invokers.getIfAvailable(SpelSqlExpressionInvoker::new));

        return entityEventListener;
    }

    @Bean
    @ConfigurationProperties(prefix = "easyorm.default-value-generator")
    public DefaultIdGenerator defaultIdGenerator() {

        return new DefaultIdGenerator();
    }

    @Bean
    public MD5Generator md5Generator() {
        return new MD5Generator();
    }

    @Bean
    public SnowFlakeStringIdGenerator snowFlakeStringIdGenerator() {
        return new SnowFlakeStringIdGenerator();
    }

    @Bean
    public CurrentTimeGenerator currentTimeGenerator() {
        return new CurrentTimeGenerator();
    }

    @Configuration
    public static class EntityTableMetadataParserConfiguration {

        @Bean
        public DefaultEntityResultWrapperFactory defaultEntityResultWrapperFactory(EntityManager entityManager) {
            return new DefaultEntityResultWrapperFactory(entityManager);
        }

        @Bean
        @ConditionalOnMissingBean
        public EntityManager entityManager(EntityTableMetadataResolver resolver, EntityFactory entityFactory) {
            return new EntityManager() {
                @Override
                @SneakyThrows
                public <E> E newInstance(Class<E> type) {
                    return entityFactory.newInstance(type);
                }

                @Override
                public EntityColumnMapping getMapping(Class entity) {

                    return resolver.resolve(entity)
                                   .getFeature(MappingFeatureType.columnPropertyMapping.createFeatureId(entity))
                                   .map(EntityColumnMapping.class::cast)
                                   .orElse(null);
                }
            };
        }

        @Bean
        @ConditionalOnMissingBean
        public EntityTableMetadataResolver entityTableMappingResolver(ObjectProvider<EntityTableMetadataParser> parsers) {
            CompositeEntityTableMetadataResolver resolver = new CompositeEntityTableMetadataResolver();
            parsers.forEach(resolver::addParser);
            return resolver;
        }

        @Bean
        @ConditionalOnMissingBean
        public EntityTableMetadataParser jpaEntityTableMetadataParser(RDBDatabaseMetadata metadata,
                                                                      EntityFactory factory,
                                                                      ObjectProvider<TableMetadataCustomizer> customizers) {

            JpaEntityTableMetadataParser parser = new JpaEntityTableMetadataParser() {

                @Override
                public Optional<RDBTableMetadata> parseTableMetadata(Class<?> entityType) {
                    Class<?> realType = factory.getInstanceType(entityType, true);
                    Optional<RDBTableMetadata> tableOpt = super.parseTableMetadata(realType);
                    tableOpt.ifPresent(table -> {
                        EntityColumnMapping columnMapping = table.findFeatureNow(
                            MappingFeatureType.columnPropertyMapping.createFeatureId(realType)
                        );
                        if (realType != entityType) {
                            table.addFeature(columnMapping = new DetectEntityColumnMapping(entityType, columnMapping, factory));
                        }
                        for (TableMetadataCustomizer customizer : customizers) {
                            customizer.customTable(realType, table);
                        }
                        columnMapping.reload();
                    });
                    return tableOpt;
                }

                @Override
                protected JpaEntityTableMetadataParserProcessor createProcessor(RDBTableMetadata table, Class<?> type) {
                    Class<?> realType = factory.getInstanceType(type, true);
                    return new JpaEntityTableMetadataParserProcessor(table, realType) {
                        @Override
                        protected void customColumn(PropertyDescriptor descriptor,
                                                    Field field,
                                                    RDBColumnMetadata column,
                                                    Set<Annotation> annotations) {
                            super.customColumn(descriptor, field, column, annotations);
                            for (TableMetadataCustomizer customizer : customizers) {
                                customizer.customColumn(realType, descriptor, field, annotations, column);
                            }
                        }
                    };
                }
            };
            parser.setDatabaseMetadata(metadata);

            return parser;
        }
    }
}


                if (bean instanceof EventListener) {
                    eventListener.addListener(((EventListener) bean));
                } else if (bean instanceof Feature) {
                    metadata.addFeature(((Feature) bean));
                }

                return bean;
            
<no_super_class>