Search code examples
javaspringspring-bootannotation-processor

Generate Spring component from annotation processor


I am using a custom AbstractProcessor to generate some classes. I tried to generate Spring components A and B where B "autowire" A. Output classes looks something similar to:

@Component
public class ClassA {
    @Bean
    public MyBean getMyBean() {
        return new MyBean();
    }
}
@Component
public class ClassB {
    @Autowired
    private ClassA myClassA;

    private MyBean myBean;

    public ClassB() {
        this.myBean = myClassA.getMyBean();
    }
}

But the autowired myClassA is null. I suspect that Spring scanning is happening before my classes are genarted.

When I run a mvn clean install I have

...
[INFO] --- spring-boot-maven-plugin:2.0.1.RELEASE:repackage (default) @ main ---

[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ main ---
[INFO] Installing C:\Users\me\Documents\kubernetes\spring\testproject2\main\target\main-1.0-SNAPSHOT.jar to C:\Users\me\.m2\repository\be\mycompany\main\1.0-SNAPSHOT\main-1.0-SNAPSHOT.jar
[INFO] Installing C:\Users\me\Documents\kubernetes\spring\testproject2\main\pom.xml to C:\Users\me\.m2\repository\be\mycompany\main\1.0-SNAPSHOT\main-1.0-SNAPSHOT.pom

Which states that the spring-boot-maven-plugin is running before the maven-install-plugin. Here is the plugin configuration used in my "annotation processor" project:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <showWarnings>true</showWarnings>
            </configuration>
            <executions>
                <execution>
                    <id>default-compile</id>
                    <configuration>
                        <compilerArgument>-proc:none</compilerArgument>
                        <includes>
                            <include>be/mycompany/testproject2/dbgenerator/processing/DatabaseAnnotationProcessor.java</include>
                        </includes>
                    </configuration>
                </execution>
                <execution>
                    <id>compile-project</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Any hints on how I could ensure that my generated components can autowire themselves ?

Thanks.


Solution

  • In this case you should to use the constructor of the Class B to be sure that the Class A present :

    @Component
    public class ClassB {
        @Autowired
        private ClassA myClassA;
    
        private MyBean myBean;
    
        public ClassB(ClassA myClassA) {
            this.myBean = myClassA.getMyBean();
            this.myClassA= myClassA;
        }
    }