-
Notifications
You must be signed in to change notification settings - Fork 1
/
ChangeUnitBeanFactoryInitializationAotProcessor.kt
58 lines (53 loc) · 2.69 KB
/
ChangeUnitBeanFactoryInitializationAotProcessor.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.example.graph.nativex
import io.mongock.api.annotations.ChangeUnit
import io.mongock.runner.springboot.MongockSpringboot
import org.springframework.aot.hint.MemberCategory.INVOKE_DECLARED_CONSTRUCTORS
import org.springframework.aot.hint.MemberCategory.INVOKE_DECLARED_METHODS
import org.springframework.aot.hint.ReflectionHints
import org.springframework.aot.hint.registerType
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory
import org.springframework.boot.autoconfigure.AutoConfigurationPackages
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider
import org.springframework.core.type.filter.AnnotationTypeFilter
import org.springframework.util.ClassUtils
import org.springframework.util.StringUtils
/**
* @author Julius Krah
*/
class ChangeUnitBeanFactoryInitializationAotProcessor: BeanFactoryInitializationAotProcessor {
override fun processAheadOfTime(beanFactory: ConfigurableListableBeanFactory): BeanFactoryInitializationAotContribution? {
if (AutoConfigurationPackages.has(beanFactory)) {
val changeUnitSet = mutableSetOf<Class<*>>()
val scanner = createScanner()
AutoConfigurationPackages.get(beanFactory).forEach { packageToScan ->
if(StringUtils.hasText(packageToScan)) {
for(beanDefinition in scanner.findCandidateComponents(packageToScan)) {
changeUnitSet.add(ClassUtils.forName(beanDefinition.beanClassName!!, beanFactory.beanClassLoader))
}
}
}
return BeanFactoryInitializationAotContribution { context, _ ->
val hints = context.runtimeHints.reflection()
registerReflectiveHints(hints, changeUnitSet)
}
}
return null
}
private fun createScanner(): ClassPathScanningCandidateComponentProvider {
val scanner = ClassPathScanningCandidateComponentProvider(false)
scanner.addIncludeFilter(AnnotationTypeFilter(ChangeUnit::class.java))
return scanner
}
private fun registerReflectiveHints(hints: ReflectionHints, changeUnits: Set<Class<*>>) {
changeUnits.forEach {
hints.registerType(it) { hint ->
hint.withMembers(INVOKE_DECLARED_METHODS, INVOKE_DECLARED_CONSTRUCTORS)
}
}
hints.registerType<MongockSpringboot.RunnerSpringbootBuilderImpl> {hint ->
hint.withMembers(INVOKE_DECLARED_METHODS, INVOKE_DECLARED_CONSTRUCTORS)
}
}
}