Skip to content

Annotation to generate JSR-330-compatible factories (aka Assisted Injection)

License

Notifications You must be signed in to change notification settings

stCarolas/enriched-beans

Repository files navigation

version badge

enriched-beans

A source code generator for JSR-330-compatible factories (for Spring, Micronaut and others). Like AutoFactory but usable with constructors generated by lombok.

Example

Say you have:

@RequiredArgsConstructor
public class SomeClass {

  private final String notInjectableField;

  @Enrich
  private final Integer depA;

  @Enrich
  @Named("myDep")
  private final String depB;

  public void sayHello(){
  }

}

Produced factory would be like:

@Singleton
@Named
public class SomeClassFactory {

  private final Integer depA;
  private final String depB;

  @Inject
  public SomeClassFactory(
    Integer depA,
    @Named("myDep") String depB
  ){
    this.depA = depA;
    this.depB = depB;
  }

  public SomeClass from(String notInjectableField){
    return new SomeClass(notInjectableField, depA, depB);
  }
}

And factory usage:

@Component
public class AnotherBean{

  @Autowired
  SomeClassFactory factory;

  ...

  public void sayHello(){
    factory.from("notInjectableFieldValue").sayHello();
  }
}

See also micronaut-example

Why not AutoFactory or AssistedInject ?

Its the same but with fewer code - annotations lies on fields so you can use generated constructor by lombok instead of writing one.

Using with Gradle, Lombok, Spring (Lombok must be placed before enriched)

  implementation 'javax.inject:javax.inject:1'
  implementation 'org.projectlombok:lombok:1.18.12'
  implementation 'io.github.stcarolas.enriched-beans:enriched-beans-assisted-inject-annotations:0.4.0'
  ...
  annotationProcessor 'org.projectlombok:lombok:1.18.12'
  annotationProcessor 'io.github.stcarolas.enriched-beans:enriched-beans-processor:0.4.0'

Using with Maven, Lombok, Micronaut (Lombok must be placed before enriched)

    <dependency>
      <groupId>io.github.stcarolas.enriched-beans</groupId>
      <artifactId>enriched-beans-assisted-inject-annotations</artifactId>
      <version>0.4.0</version>
    </dependency>
    ...
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.1</version>
      <configuration>
        <compilerArguments>
          <AaddGeneratedAnnotation>false</AaddGeneratedAnnotation>
          <Adebug>true</Adebug>
        </compilerArguments>
        <dependencies>
          <dependency>
            <groupId>org.ow2.asm</groupId>
            <artifactId>asm</artifactId>
            <version>7.3.1</version>
            <type>jar</type>
          </dependency>
        </dependencies>
        <annotationProcessorPaths>
          <annotationProcessorPath>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
          </annotationProcessorPath>
          <annotationProcessorPath>
            <groupId>io.github.stcarolas.enriched-beans</groupId>
            <artifactId>enriched-beans-processor</artifactId>
            <version>0.4.0</version>
          </annotationProcessorPath>
          <annotationProcessorPath>
            <groupId>io.micronaut</groupId>
            <artifactId>micronaut-inject-java</artifactId>
            <version>1.3.4</version>
          </annotationProcessorPath>
        </annotationProcessorPaths>
      </configuration>
    </plugin>

Factory customization

Compiler args listed below can be passed to define some aspects of generated factories

  1. factoryMethodName. Default value: "from".
  2. factoryVisibility. Available values: "public","package". Default value: "public".

Configuration example:

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.8.1</version>
  <configuration>
    <compilerArguments>
      <AfactoryMethodName>create</AfactoryMethodName>
      <AfactoryVisibility>package</AfactoryVisibility>
    </compilerArguments>
    <annotationProcessorPaths>
      <annotationProcessorPath>
        <groupId>io.github.stcarolas.enriched-beans</groupId>
        <artifactId>enriched-beans-processor</artifactId>
        <version>0.4.0</version>
      </annotationProcessorPath>
    </annotationProcessorPaths>
  </configuration>
</plugin>

How to view generated sources

All generated factories lies in $buildDir/generated/sources/annotationProcessor/java/main directory if using gradle and target/generated-sources/annotations if using maven

Eclipse JDT and Gradle

Eclipse JDT.LS has problems with using annotation processing so this trick can help

def generatedSources = "$buildDir/generated/sources/annotationProcessor/java/main"
def generatedOutputDir = file("$generatedSources")

sourceSets {
    main {
        java {
            srcDirs += generatedOutputDir
        }
    }
}

Run manually gradle build and eclipse will detect sources.