more fun with roo
We have created a Spring web project using Spring Roo, now let us have a look at the generated codes.
If you created the project from Eclipse directly, skip this section.
In the Package view, click the array icon besides project node of the imported project to expand all nodes of the project.
It is a standard Maven web project.
src/main/java includes all java source files, and all configuration files of the project are placed in the src/main/resource, including the Spring specific configuration files, they will be included in the /WEB-INF/classes in the final deployment war structure. src/test/java includes the test files, and src/main/webapp includes all web resources. In these nodes, src/main/java and src/test/java are recognized as package nodes and displayed as package view.
Expand src/main/java source package node, you will see some packages we have already created in previous steps.
Open the entity class Conference, you will find three annotations defined on the class, @RooJavaBean, @RooToString, @RooJpaEntity, they mean some aspects applied on the class.
We have also created a ConferenceRepository class in the ~.repository package and ConferenceService class in the ~.service package for the entity Conference. ConferenceRepository is a empty interface with an annotation added on the class definition @RooJpaRepository(domainType = Conference.class), ConferenceRepository_Roo_Jpa_Repository includes the database operations, it reused the effort from Spring Data subproject. ConferenceService and ConferenceService_Roo_Service include all business logic declaration, and ConferenceServiceImpl and ConferenceServiceImpl_Roo_Service include the certain implementation.
and JpaSpecificationExecutor interfaces, which are from the Spring Data JPA project.
In the ~.service package, it also includes related aspects for ConferenceService interface and implementation class ConferenceServiceImpl.
All abstract methods of interface ConferenceService are included in the aspect ConferenceService_Roo_Service.
And in the aspect ConferenceServiceImpl_Roo_Service, it provides the operations of the implementation class, show as below.
In this example, we used --activeRecord=false to generate the codes, if you are using activeRecord(use --activeRecord=true or omit this option), the codes will be a little different.
I have create another entity class named Signup, which used ActiveRecord pattern. You will find there is another annotation @RooJpaActiveRecord on the Signup entity class instead of @RooJpaEntity, and two more AspectJ aspect files are generated in the same package, Signup_Roo_Configurable and Signup_Roo_Jpa_ActiveRecord.
Let us explore the ~.web package.
Spring Roo also generated a custom ConversionService for this project.
In the src/test/java Source node, it includes a ~.model package, some test classes are generated for the Conference entity.
The ConferenceDataOnDemand is use for populating testing data for test classes for specified classes. The codes are easy to understand.
The ConferenceIntegrationTest_Roo_Configurable, ConferenceIntegrationTest_Roo_IntegrationTest and ConferenceIntegrationTest is very direct and easy to understand, they include the certain test case.
The Spring ToolSuite includes AspectJ Development Tools, which can help you remove the AspectJ specific files and convert the AspectJ files into standard Java class.
Import codes into Eclipse workspace
If you created the project from Roo console, you can follow the following steps to import the project codes into your Eclipse workspace.If you created the project from Eclipse directly, skip this section.
- Start Eclipse IDE.
- Select Import... menu item from File menu in the Eclipse main menu.
- In the popup Import... dialog, expand the Maven node, and select Existing Maven Projects and click Next button.
- Choose the created project folder, it will scan the project files, and recognize the pom.xml file, select it by checking the checkbox, and click Finish button.
Explore the project codes
Switch to Spring perspective, and open Package view.In the Package view, click the array icon besides project node of the imported project to expand all nodes of the project.
It is a standard Maven web project.
src/main/java includes all java source files, and all configuration files of the project are placed in the src/main/resource, including the Spring specific configuration files, they will be included in the /WEB-INF/classes in the final deployment war structure. src/test/java includes the test files, and src/main/webapp includes all web resources. In these nodes, src/main/java and src/test/java are recognized as package nodes and displayed as package view.
Expand src/main/java source package node, you will see some packages we have already created in previous steps.
- ~.model contains the JPA entity classes.
- ~.repository includes the classes of the repository layer.
- ~.service includes the classes of the service layer.
- ~.controller includes the web controller classes for the presentation layer.
Open the entity class Conference, you will find three annotations defined on the class, @RooJavaBean, @RooToString, @RooJpaEntity, they mean some aspects applied on the class.
@RooJavaBean @RooToString @RooJpaEntity public class Conference { //fields }And in the same package, you must see other AspectJ specific aspect files which are generated by Spring Roo, Conference_Roo_JavaBean.aj, Conference_Roo_Jpa_Entity.aj, Conference_Roo_ToString.aj .
privileged aspect Conference_Roo_JavaBean { public String Conference.getName() { return this.name; } public void Conference.setName(String name) { this.name = name; } //setters and getters of other fields. }Aligned with @RooJavaBean annotation on the Conference class, Conference_Roo_JavaBean.aj will contribute the general JavaBean properties(setters and getters excluding the @Id and @Version properties) to the entity Conference.
privileged aspect Conference_Roo_ToString { public String Conference.toString() { return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE); } }@RooToString and Conference_Roo_ToString.aj will override the toString method of Conference class, it used ReflectionToStringBuilder which is from the Apache Commons Lang project.
privileged aspect Conference_Roo_Jpa_Entity { declare @type: Conference: @Entity; @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id") private Long Conference.id; @Version @Column(name = "version") private Integer Conference.version; public Long Conference.getId() { return this.id; } public void Conference.setId(Long id) { this.id = id; } public Integer Conference.getVersion() { return this.version; } public void Conference.setVersion(Integer version) { this.version = version; } }@RooJpaEntity and Conference_Roo_Jpa_Entity.aj will contribute the annotation @Entity to Conference and also manage the entity related properties, such as @Id, @Version.
We have also created a ConferenceRepository class in the ~.repository package and ConferenceService class in the ~.service package for the entity Conference. ConferenceRepository is a empty interface with an annotation added on the class definition @RooJpaRepository(domainType = Conference.class), ConferenceRepository_Roo_Jpa_Repository includes the database operations, it reused the effort from Spring Data subproject. ConferenceService and ConferenceService_Roo_Service include all business logic declaration, and ConferenceServiceImpl and ConferenceServiceImpl_Roo_Service include the certain implementation.
privileged aspect ConferenceRepository_Roo_Jpa_Repository { declare parents: ConferenceRepository extends JpaRepository; declare parents: ConferenceRepository extends JpaSpecificationExecutor; declare @type: ConferenceRepository: @Repository; }Obviously, this aspect will add annotation @Repository on class ConferenceRepository and make ConferenceRepository extend JpaRepository
In the ~.service package, it also includes related aspects for ConferenceService interface and implementation class ConferenceServiceImpl.
All abstract methods of interface ConferenceService are included in the aspect ConferenceService_Roo_Service.
And in the aspect ConferenceServiceImpl_Roo_Service, it provides the operations of the implementation class, show as below.
privileged aspect ConferenceServiceImpl_Roo_Service { declare @type: ConferenceServiceImpl: @Service; declare @type: ConferenceServiceImpl: @Transactional; @Autowired ConferenceRepository ConferenceServiceImpl.conferenceRepository; }Annotations @Service and @Transactional are added and ConferenceRepository is injected for ConferenceServiceImpl.
In this example, we used --activeRecord=false to generate the codes, if you are using activeRecord(use --activeRecord=true or omit this option), the codes will be a little different.
I have create another entity class named Signup, which used ActiveRecord pattern. You will find there is another annotation @RooJpaActiveRecord on the Signup entity class instead of @RooJpaEntity, and two more AspectJ aspect files are generated in the same package, Signup_Roo_Configurable and Signup_Roo_Jpa_ActiveRecord.
privileged aspect Signup_Roo_Configurable { declare @type: Signup: @Configurable; }This aspect will add another @Configurable annotation on the entity class, this make the entity is injectable, and you can use @PersisteneceContext to inject EntityManager in an entity.
privileged aspect Signup_Roo_Jpa_ActiveRecord { @PersistenceContext transient EntityManager Signup.entityManager; //all database operations. }The Signup_Roo_Jpa_ActiveRecord aspect will contribute all database operations to the entity class.
Let us explore the ~.web package.
Spring Roo also generated a custom ConversionService for this project.
@RooConversionService public class ApplicationConversionServiceFactoryBean extends FormattingConversionServiceFactoryBean { @Override protected void installFormatters(FormatterRegistry registry) { super.installFormatters(registry); // Register application converters and formatters } }The ApplicationConversionServiceFactoryBean_Roo_ConversionService aspect includes some conversions, such id(Long) to Object, string to Object, etc which are useful in the page scoped select dropdown controls.
privileged aspect ApplicationConversionServiceFactoryBean_Roo_ConversionService { declare @type: ApplicationConversionServiceFactoryBean: @Configurable; @Autowired ConferenceService ApplicationConversionServiceFactoryBean.conferenceService; }There are also some controllers and related aspects in the ~.web package.
privileged aspect ConferenceController_Roo_Controller { @Autowired ConferenceService ConferenceController.conferenceService; // the controller methods are omitted. }
@RequestMapping("/conferences") @Controller @RooWebScaffold(path = "conferences", formBackingObject = Conference.class) public class ConferenceController { }They are easy to understand, the ConferenceController declares it as a @Controller and set url path. All related request processing are moved to ConferenceController_Roo_Controller.
In the src/test/java Source node, it includes a ~.model package, some test classes are generated for the Conference entity.
The ConferenceDataOnDemand is use for populating testing data for test classes for specified classes. The codes are easy to understand.
privileged aspect ConferenceDataOnDemand_Roo_Configurable { declare @type: ConferenceDataOnDemand: @Configurable; }ConferenceDataOnDemand_Roo_Configurable aspect will contribute annotation @Configurable to the class ConferenceDataOnDemand.
privileged aspect ConferenceDataOnDemand_Roo_DataOnDemand { declare @type: ConferenceDataOnDemand: @Component; private Random ConferenceDataOnDemand.rnd = new SecureRandom(); private List ConferenceDataOnDemand.data; @Autowired ConferenceService ConferenceDataOnDemand.conferenceService; @Autowired ConferenceRepository ConferenceDataOnDemand.conferenceRepository; }ConferenceDataOnDemand_Roo_DataOnDemand aspect includes all operations of generating a new test object.
The ConferenceIntegrationTest_Roo_Configurable, ConferenceIntegrationTest_Roo_IntegrationTest and ConferenceIntegrationTest is very direct and easy to understand, they include the certain test case.
Remove the Roo specific codes...
Some people maybe enjoy their before experience and feel a little incompatible with AspectJ. An new programming model introduced by Spring Roo means there is a learning curve to developers, you have to spend some time to master it. Roo does not force you to follow the Roo-style. You can remove Roo specific codes easily via Spring ToolSuite if you dislike it.The Spring ToolSuite includes AspectJ Development Tools, which can help you remove the AspectJ specific files and convert the AspectJ files into standard Java class.
-
Right click the project node, select Refactor->Push In... in the context menu. In the popup Push In Intertype Declaration dialog, it lists all Aspect files, you can click Preview button the preview the processing result one by one, or click OK button to start the conversion.
After it is done, all of aspect specific files are removed, and the content are merged into the related Java files.
Note: Currently, we have not added any custom codes into the project. You can easily use Spring ToolSuite to recovery the Roo specific features if you like them. Right click the project node, select Refactor->Push Out... in the context menu, it will regenerate the AspectJ files for you. It is magic!? Open the Conference entity class, you will find the before removal did not remove @Roo annotations, it will guide the IDE to restore the AspectJ files.
-
Remove the Roo specific annotations from all classes.
If you apply the mutil layered architecture, do not forget to create a new SignupRepository for Signup entity, and move all database operations to SignupRepository, add related business methods in the ConferenceService class, and change the codes of SignupController, and call the business method from ConferenceService instead of Signup.
- Remove AJDT and Roo nature from IDE, and remove Roo related dependencies from pom.xml.
评论