Autor: Michael Karneim
Página inicial do projeto: http://github.com/mkarneim/pojobuilder
O PojoBuilder Generator é um processador de anotação compatível com Java 6 que gera uma classe construtora fluente para POJOs (Plain Old Java Object).
O construtor gerado fornece
Aqui está um exemplo de como você poderia usar um construtor pojo gerado a partir do seu código:
Contact james = new ContactBuilder ()
. withSurname ( "Bond" )
. withFirstname ( "James" )
. withEmail ( "[email protected]" )
. build ();
Os construtores são bastante úteis, por exemplo, para construir dados de teste, onde você deseja apenas definir as propriedades de dados relevantes.
Para mais informações sobre
O código fonte localizado no diretório "src" está no PUBLIC DOMAIN. Para mais informações, leia o arquivo COPYING.
PojoBuilder é um gerador de código puro. Ele não adiciona nenhuma dependência de tempo de execução ao seu projeto.
No entanto, o PojoBuilder adiciona a seguinte dependência de tempo de compilação ao seu projeto, que possui sua própria licença:
PojoBuilder é de código aberto. O código-fonte está disponível em http://github.com/mkarneim/pojobuilder. Para versões mais antigas e um log de alterações, consulte a página de histórico de lançamentos.
Os binários do PojoBuilder estão disponíveis para download no Sonatype OSS Maven Repository e no Maven Central.
Se você não usa nenhuma ferramenta de automação de construção que suporte repositórios maven, você pode querer baixar o pojobuilder-4.3.0-jar-with-dependencies.jar
para obter o PojoBuilder completo com todas as bibliotecas dependentes incluídas.
O gerador PojoBuilder usa um processador de anotação para gerar construtores pojo para você. Você tem as seguintes opções para acionar a geração do código:
Para gerar uma classe construtora para um pojo você pode anotar um de seus construtores com @GeneratePojoBuilder
.
Vamos dar uma olhada no seguinte exemplo de pojo:
public class Contact {
private final String surname ;
private final String firstname ;
private String email ;
@ GeneratePojoBuilder
public Contact ( String surname , String firstname ) {
this . surname = surname ;
this . firstname = firstname ;
}
public String getEmail () {
return email ;
}
public void setEmail ( String email ) {
this . email = email ;
}
public String getSurname () {
return surname ;
}
public String getFirstname () {
return firstname ;
}
}
A anotação @GeneratePojoBuilder informa ao processador de anotação para criar um novo arquivo de origem Java com o nome ContactBuilder
. Dê uma olhada em ContactBuilder.java
para ver o código-fonte gerado.
Observe que o construtor deve ser público ou acessível de outra forma para o construtor gerado, por exemplo, se estiver protegido, o construtor gerado deve residir no mesmo pacote.
E observe também que os nomes dos parâmetros do construtor devem corresponder exatamente aos nomes das propriedades do pojo.
Uma anotação @ConstructorProperties opcional pode ser usada para especificar o mapeamento dos nomes dos parâmetros do construtor para os nomes das propriedades do bean correspondentes no pojo, se eles forem diferentes.
public class Contact {
private final String surname ;
private final String firstname ;
private String email ;
@ GeneratePojoBuilder
@ ConstructorProperties ({ "surname" , "firstname" })
public Contact ( String arg1 , String arg2 ) {
this . surname = arg1 ;
this . firstname = arg2 ;
}
public String getEmail () {
return email ;
}
public void setEmail ( String email ) {
this . email = email ;
}
public String getSurname () {
return surname ;
}
public String getFirstname () {
return firstname ;
}
}
Se o seu pojo não tiver construtor (ou um construtor público padrão), você poderá anotar sua classe com @GeneratePojoBuilder
.
Vamos dar uma olhada no seguinte exemplo de pojo:
@ GeneratePojoBuilder
public class User {
private String name ;
private char [] password ;
public String getName () {
return name ;
}
public void setName ( String name ) {
this . name = name ;
}
public char [] getPassword () {
return password ;
}
public void setPassword ( char [] password ) {
this . password = password ;
}
}
Dê uma olhada em UserBuilder.java
para ver o código-fonte gerado.
Alternativamente, se você não tem acesso ao código-fonte do pojo, ou se não gosta de anotar um pojo, você pode anotar um método de fábrica:
public class UrlFactory {
@ GeneratePojoBuilder ( withName = "UrlBuilder" , intoPackage = "samples" )
public static URL createUrl (
String protocol , String host , int port , String file , URLStreamHandler handler )
throws MalformedURLException {
return new URL ( protocol , host , port , file , handler );
}
}
Dê uma olhada em UrlBuilder.java
para ver o código-fonte gerado.
Observe que o método de fábrica deve ser público e estático . Os nomes dos parâmetros do método devem corresponder exatamente aos nomes das propriedades do pojo.
Uma anotação opcional @FactoryProperties pode ser usada para especificar o mapeamento dos nomes dos parâmetros do método de fábrica para os nomes das propriedades do bean correspondentes no pojo, se eles forem diferentes.
public class FileFactory {
@ GeneratePojoBuilder ( intoPackage = "samples" )
@ FactoryProperties ({ "path" })
public static File createFile ( String arg1 ) {
return new File ( arg1 );
}
}
Dê uma olhada em FileBuilder.java
para ver o código-fonte gerado.
A partir do PojoBuilder 4.3 você pode anotar um tipo de registro Java 17:
@ GeneratePojoBuilder
public record MyRecord ( int x , int y , String blah ) {}
Os seguintes elementos de @GeneratePojoBuilder podem ser usados para configurar a saída do processo de geração de código.
Fluent*Builder
se tornará FluentContactBuilder
se o nome do pojo for Contact
. O padrão padrão é *Builder
.Visibility.PUBLIC
.*.util
se tornará com.example.util
se o pacote do pojo for com.example
. O padrão padrão é *
.Object.class
.Address.java
, Builder.java
e AddressBuilder.java
. O padrão é Void.class
, o que significa que nenhuma interface deve ser implementada.Recipient.java
, Builder.java
e RecipientBuilder.java
. O padrão é false
.InputSourceFactory.java
e InputSourceBuilder.java
. O padrão é *
.CalendarFactory.java
e GregorianCalendarBuilder.java
. O padrão é a matriz vazia.Player.java
, PlayerBuilder.java
e AbstractPlayerBuilder.java
. O padrão é false
.TextEmail.java
e TextEmailBuilder.java
. O padrão é false
.com.google.common.base.Optional
e java.util.Optional
do Google Guava introduzidos com Java 8. O padrão é Void.class
, o que significa que nenhum método setter baseado em opcional é gerado.with*
.validate
com um parâmetro compatível com o tipo do pojo. Se a validação falhar, o método deverá lançar alguma exceção de tempo de execução (ou uma de suas subclasses). Para obter um exemplo, consulte Credentials.java
, CredentialsValidator.java
e CredentialsBuilder.java
.Task.java
e TaskBuilder.java
. O padrão é ""
significando não gerar este método.A partir da versão 3, o PojoBuilder suporta meta-anotações . Ou seja, você pode colocar @GeneratePojoBuilder em outra anotação e ela será herdada.
As vantagens são:
O exemplo a seguir define @AppPojo
que pode ser aplicado em nível de classe e encapsula as anotações de três fontes diferentes (PojoBuilder, Lombok e JSR-305).
@ GeneratePojoBuilder ( withName = "Fluent*Builder" )
@ lombok . experimental . Value // class-level annotation from Lombok
@ javax . annotation . concurrent . Immutable // class-level annotation from JSR-305
@ Target ({ ElementType . TYPE , ElementType . ANNOTATION_TYPE })
public @interface AppPojo {
}
Isso pode ser colocado em cada um dos seus pojos:
@ AppPojo
public class Contact {
public String name ;
}
PojoBuilder irá gerar FluentContactBuilder
com base nas diretivas herdadas da anotação @AppPojo
.
Os padrões herdados de meta-anotações podem ser substituídos por mais anotações @GeneratePojoBuilder
'locais':
@ AppPojo
@ GeneratePojoBuilder ( intoPackage = "builder" )
public class Contact {
public String name ;
}
Isso irá gerar FluentContactBuilder
como antes, mas no builder
de pacotes.
O wiki do PojoBuilder fornece um livro de receitas sobre como usar o PojoBuilder Generator, por exemplo, para construir uma linguagem específica de domínio para testes automatizados.
Para alguns exemplos de código completos, dê uma olhada na pasta src/testdata/java/samples.
Para executar o processador de anotação PojoBuilder você só precisa colocá-lo no classpath de tempo de compilação. Durante o tempo de execução, nenhuma biblioteca é necessária, pois a política de retenção das anotações do PojoBuilder é CLASS
.
Aqui está uma lista de breves descrições sobre como executar o PojoBuilder com
O compilador javac
detectará automaticamente a presença do PojoBuilder se pojobuilder-*.jar
estiver incluído no caminho de classe.
Por exemplo:
javac -cp pojobuilder-4.3.0-jar-with-dependencies.jar Contact.java
irá gerar um ContactBuilder
se Contact
for anotado com @GeneratePojoBuilder
.
Para obter mais informações, consulte a documentação do javac.
Adicione o seguinte ao pom.xml
do seu projeto para configurar o processador de anotação PojoBuilder.
net.karneim
pojobuilder
4.3.0
provided
Notas:
${project.build.directory}/generated-sources/annotations
.target
, configure o generatedSourcesDirectory
do maven-compiler-plugin
. Veja o exemplo do Maven pom para ver um exemplo.Este é um pequeno script de construção que mostra como executar o processador de anotação PojoBuilder com Gradle.
apply plugin : ' java '
repositories {
mavenCentral()
}
dependencies {
compile ' net.karneim:pojobuilder:4.3.0 '
}
Observe que isso não apenas adiciona o PojoBuilder e suas dependências ao caminho de classe em tempo de compilação, mas também ao caminho de classe em tempo de execução.
Alternativamente, você pode usar o seguinte script para adicionar PojoBuilder apenas ao caminho de classe em tempo de compilação:
apply plugin : ' java '
repositories {
mavenCentral()
}
configurations {
codeGeneration
}
dependencies {
codeGeneration ' net.karneim:pojobuilder:4.3.0 '
compileOnly ' net.karneim:pojobuilder:4.3.0:annotations '
}
compileJava . classpath + = configurations . codeGeneration
compileTestJava . classpath + = configurations . codeGeneration
Em ambos os casos, as fontes geradas serão colocadas no diretório padrão build/classes
.
Se você quiser colocá-los em outro lugar, basta especificar o destino assim:
compileJava . options . compilerArgs + = [ ' -s ' , ' src/generated/java ' ]
O wiki contém um script Gradle estendido que distingue completamente entre geração de código e tarefas de compilação.
Há outro script Gradle que habilita o PojoBuilder para Eclipse IDE.
Com o Gradle 5.0, qualquer processador de anotação no caminho de classe não é mais executado. Para fazer o pojobuilder funcionar novamente, substitua o escopo de dependência usado por annotationProcessor
dependencies {
annotationProcessor ' net.karneim:pojobuilder:4.3.0 '
}
Aqui está um trecho de código de um exemplo de script de construção ANT que executa o processador de anotação PojoBuilder na tarefa javac
.
< fileset id = " libs.fileset " dir = " ${basedir}/lib " >
< include name = " *.jar " />
fileset >
< path id = " class.path " >
< fileset refid = " libs.fileset " />
path >
< target name = " compile " depends = " init "
description = " Compile java sources and run annotation processor " >
< mkdir dir = " ${src.gen.java.dir} " />
< mkdir dir = " ${build.classes.dir} " />
< javac classpathref = " class.path " destdir = " ${build.classes.dir} " >
< src path = " ${src.main.java.dir} " />
< compilerarg line = " -s ${src.gen.java.dir} " />
javac >
target >
Você também pode configurar o Eclipse para executar o processador de anotação PojoBuilder durante o ciclo de construção. Ele será invocado sempre que você salvar arquivos que contenham fontes anotadas com @GeneratePojoBuilder
.
Faça o seguinte para ativar o PojoBuilder para seu projeto Eclipse:
pojobuilder-4.3.0-annotations.jar
ao classpath do seu projetopojobuiler-4.3.0-jar-with-dependencies.jar
Se você quiser compilar os fontes deste projeto você mesmo pode usar Gradle (veja build.gradle).