Adding attributes to a Java class
You can add attributes to your Java classes in your Roo project, either from your IDE or by using the field
commands of Spring Roo. There are advantages in adding attributes using Roo as opposed to using an IDE, which we will see in this recipe. The following table shows the name and type of attributes that we will add to a Passenger
class in the package sample.roo.flightapp.domain
of the flight-app
project:
Field name |
Type |
---|---|
|
|
|
|
|
|
|
|
Getting ready
Start the Roo shell from the C:\roo-cookbook\ch01-recipe
directory, which contains the flight-app
project.
How to do it...
Roo provides field commands, which you can use to add different types of fields in your Java class, shown as follows:
Create an
Address
class, which is an attribute type in thePassenger
class, as shown here:roo> class --class ~.domain.Address --rooAnnotations
Create a
Passenger
class, to which we want to add attributes using thefield
commands, as shown here:sample.roo.flightapp.domain.Address roo> class --class ~.domain.Passenger --rooAnnotations
Add
firstName
andlastName
attributes to thePassenger
class usingfield string
command, shown as follows:sample.roo.flightapp.domain.Passenger roo> field string --fieldName firstName Updated ..Passenger.java Created ..Passenger_Roo_JavaBean.aj Created ..Passenger_Roo_ToString.aj .. roo> field string --fieldName lastName Updated ..Passenger.java Updated ..Passenger_Roo_JavaBean.aj Updated ..Passenger_Roo_ToString.aj
Add an
age
attribute to thePassenger
class, using thefield
number
command, shown as follows:.. roo> field number --fieldName age --type java.lang.Integer Updated ..Passenger.java Updated ..Passenger_Roo_JavaBean.aj Updated ..Passenger_Roo_ToString.aj
Add an
address
attribute of typeAddress
to thePassenger
class, using thefield other
command, shown as follows:.. roo> field other --fieldName address --type sample.roo.flightapp.domain.Address Updated ..Passenger.java Updated ..Passenger_Roo_JavaBean.aj Updated ..Passenger_Roo_ToString.aj
The given output for each of these commands shows that when an attribute is added to the Passenger
class for the first time, the Passenger_Roo_JavaBean.aj
and Passenger_Roo_ToString.aj
files are created. You may notice that every time you add an attribute, the Passenger_Roo_JavaBean.aj
and Passenger_Roo_ToString.aj
AspectJ ITD files are also updated.
How it works...
Spring Roo provides multiple field
commands for adding different types of attributes to the Java class. For instance, field
string
is for adding a String
type field, field
date
is for adding a java.util.Date
or java.util.Calendar
type field, field
other
is for adding a field of custom Java type, and so on.
Note
Some of the field
commands, like field
set
and field
reference
, apply only to JPA entities, and are therefore not applicable to every Java class that you create in your Roo project. Also, field
commands accept certain arguments, which make sense only if the target Java class is a JPA entity. We will discuss JPA entity specific field commands in Chapter 2.
The field
string
, field
other,
and field
number
commands accept the name
argument, which identifies the name of the attribute to be added to the Java class. The field other
and field
number
also require the type
of the attribute.
The following code shows Passenger_Roo_JavaBean.aj
AspectJ ITD, which was modified by Spring Roo when we added fields to the Passenger
class:
privileged aspect Passenger_Roo_JavaBean { public String Passenger.getFirstName() { return this.firstName; } public void Passenger.setFirstName(String firstName) { this.firstName = firstName; } ... }
The given code shows that Passenger_Roo_JavaBean.aj
was updated by Spring Roo to introduce getter and setter methods for each of the fields added to Passenger
class. This was possible because of the presence of @RooJavaBean
annotation in the Passenger
class.
The following code shows Passenger_Roo_ToString.aj
AspectJ ITD, which was also modified by Spring Roo when fields were added to the Passenger
class:
privileged aspect Passenger_Roo_ToString { public String Passenger.toString() { StringBuilder sb = new StringBuilder(); sb.append("FirstName:").append(getFirstName()).append(","); sb.append("LastName: ").append(getLastName()).append(", "); sb.append("Age: ").append(getAge()).append(", "); sb.append("Address: ").append(getAddress()); return sb.toString(); } }
As the given code suggests, it introduces a toString
method to the Passenger
class, which returns a concatenated String
containing the value of each of its attribute. This was possible because the Passenger
class was annotated with the @RooToString
annotation.
Tip
What if I add an attribute using IDE?
Spring Roo actively monitors changes to classes that are annotated with Roo annotations, and any change to classes triggers Spring Roo to update the corresponding AspectJ ITD files. So, it doesn't matter whether you add attributes to your Java class using Roo shell or an IDE.
The following figure shows how Spring Roo manages AspectJ ITD files:
The given figure shows that when you start the Spring Roo shell from a directory, it actively monitors the Java classes in the file system that are annotated with Roo annotations (for example @RooToString
, @RooJavaBean
, and so on). When any of these Java classes are modified using an IDE or any other editor, Spring Roo checks if the AspectJ ITD files (which follow the naming convention *_Roo_*.aj
, as explained earlier) corresponding to the Java classes are in sync with the Java classes. If they are not, it updates the AspectJ ITD files accordingly. Spring Roo makes use of add-ons to make modifications to the AspectJ ITD files.
There's more...
This recipe showed that if you want Roo to automatically generate a toString
method and getter and setter methods for all the attributes, then annotate your class with @RooToString
and @RooJavaBean
annotations.
Tip
What if I add an attribute when Spring Roo is not running?
When you start Roo shell, it checks if AspectJ ITDs are in sync with the corresponding Java classes. If there are differences, then Roo updates the AspectJ ITD files to reflect the current state of the Java class. At this time Roo may even remove an ITD file if it finds that it is no longer required. For instance, if you remove all the attributes from Passenger
class, then the corresponding Passenger_Roo_JavaBean.aj
and Passenger_Roo_ToString.aj
files are automatically removed by Roo.
Spring Roo doesn't provide commands to remove or modify an attribute. So, if you want to remove or modify an existing attribute of a Java class, you can do so using your IDE. Spring Roo will take care of removing or modifying the attribute in corresponding AspectJ ITD files.
@RooJavaBean—controlling the generation of getter and setter methods
We saw that using @RooJavaBean
annotation introduces getter and setter methods for all the fields in a class. In some cases, you may want to control the generation of these getter and setter methods. @RooJavaBean
allows you to do so using the gettersByDefault
and settersByDefault
attributes. These attributes
specify whether getter and setter methods should be generated by default or not. The default value of these attributes is true
, which means the @RooJavaBean
annotation will create getter and setter methods in the corresponding *_Roo_JavaBean.aj
ITD for all the fields defined in the class.
If you specify the value of both gettersByDefault
and settersByDefault
elements as false, then Spring Roo deletes the corresponding AspectJ ITD file.
See also
The Creating a Java interface recipe shows how to create a Java interface using Spring Roo
The Adding fields to persistent entities recipe of Chapter 2, Persisting Objects Using JPA shows the additional arguments that are available in
field
commands