Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.jetbrains.rd.util.getLogger
import com.jetbrains.rd.util.info
import com.jetbrains.rd.util.warn
import org.springframework.beans.factory.BeanCreationException
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition
import org.springframework.beans.factory.config.BeanFactoryPostProcessor
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory
import org.springframework.beans.factory.support.BeanDefinitionRegistry
Expand All @@ -30,16 +31,37 @@ object UtBotBeanFactoryPostProcessor : BeanFactoryPostProcessor, PriorityOrdered
throw UtBotSpringShutdownException("Finished post-processing bean factory in UtBot", beanQualifiedNames)
}

private fun findBeanClassNames(beanFactory: ConfigurableListableBeanFactory): List<String> {
return beanFactory.beanDefinitionNames.mapNotNull {
try {
beanFactory.getBeanDefinition(it).beanClassName ?: beanFactory.getBean(it).javaClass.name
private fun findBeanClassNames(beanFactory: ConfigurableListableBeanFactory): List<String> =
beanFactory.beanDefinitionNames
.mapNotNull { getBeanFqn(beanFactory, it) }
.filterNot { it.startsWith("org.utbot.spring") }
.distinct()

private fun getBeanFqn(beanFactory: ConfigurableListableBeanFactory, beanName: String): String? {
val beanDefinition = beanFactory.getBeanDefinition(beanName)
return if (beanDefinition is AnnotatedBeanDefinition) {
if (beanDefinition.factoryMethodMetadata == null) {
// there's no factoryMethod so bean is defined with @Component-like annotation rather than @Bean annotation
// same approach isn't applicable for @Bean beans, because for them, it returns name of @Configuration class
beanDefinition.metadata.className.also { fqn ->
logger.info { "Got $fqn as metadata.className for @Component-like bean: $beanName" }
}
} else try {
// TODO to avoid side effects, determine beanClassName without getting bean by analyzing method
// defining bean, for example, by finding all its return statements and determining their common type
// NOTE: do not simply use return type from method signature because it may be an interface type
beanFactory.getBean(beanName)::class.java.name.also { fqn ->
logger.info { "Got $fqn as runtime type for @Bean-like bean: $beanName" }
}
} catch (e: BeanCreationException) {
logger.warn { "Failed to get bean: $it" }
logger.warn { "Failed to get bean: $beanName" }
null
}
}.filterNot { it.startsWith("org.utbot.spring") }
.distinct()
} else {
beanDefinition.beanClassName.also { fqn ->
logger.info { "Got $fqn as beanClassName for XML-like bean: $beanName" }
}
}
}

private fun destroyBeanDefinitions(beanFactory: ConfigurableListableBeanFactory) {
Expand Down