Oleg Atamanenko
@Entity //1
@RooJavaBean //2
@RooToString //3
@RooEntity(finders = { "findActionsByName" }) //4
public class Action {
@NotNull
@Size(min = 1, max = 80)
private String name;
@Size(max = 1024)
private String description;
}
Мы видим, что:
@RooJavaBean
говорит, что этот класс - обычный Java-бин.@RooToString
говорит, что у этого класса есть перегруженный метод toString().@RooEntity
говорит что класс является JPA-сущностью.privileged aspect Action_Roo_Configurable {
declare @type: Action: @org.springframework.beans.factory.annotation.Configurable;
}
package org.academ.uthark.research.roo.domain;
privileged aspect Action_Roo_Entity {
@javax.persistence.PersistenceContext
transient javax.persistence.EntityManager Action.entityManager;
@javax.persistence.Id
@javax.persistence.GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
@javax.persistence.Column(name = "id")
private java.lang.Long Action.id;
@javax.persistence.Version
@javax.persistence.Column(name = "version")
private java.lang.Integer Action.version;
public java.lang.Long Action.getId() {
return this.id;
}
public void Action.setId(java.lang.Long id) {
this.id = id;
}
public java.lang.Integer Action.getVersion() {
return this.version;
}
public void Action.setVersion(java.lang.Integer version) {
this.version = version;
}
@org.springframework.transaction.annotation.Transactional
public void Action.persist() {
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
this.entityManager.persist(this);
}
@org.springframework.transaction.annotation.Transactional
public void Action.remove() {
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
this.entityManager.remove(this);
}
@org.springframework.transaction.annotation.Transactional
public void Action.flush() {
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
this.entityManager.flush();
}
@org.springframework.transaction.annotation.Transactional
public void Action.merge() {
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
Action merged = this.entityManager.merge(this);
this.entityManager.flush();
this.id = merged.getId();
}
public static long Action.countActions() {
return (Long) new Action().entityManager.createQuery("select count(o) from Action o").getSingleResult();
}
public static java.util.List<org.academ.uthark.research.roo.domain.action> Action.findAllActions() {
return new Action().entityManager.createQuery("select o from Action o").getResultList();
}
public static org.academ.uthark.research.roo.domain.Action Action.findAction(java.lang.Long id) {
if (id == null) throw new IllegalArgumentException("An identifier is required to retrieve an instance of Action");
return new Action().entityManager.find(Action.class, id);
}
public static java.util.List<org.academ.uthark.research.roo.domain.action> Action.findActionEntries(int firstResult, int maxResults) {
return new Action().entityManager.createQuery("select o from Action o").setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
}
}
Как легко видеть, этот аспект добавляет классу Action CRUD-методы, поля id и version.
privileged aspect Action_Roo_Finder {
public static javax.persistence.Query Action.findActionsByName(java.lang.String name) {
if (name == null) throw new IllegalArgumentException("The name argument is required");
javax.persistence.Query q = new Action().entityManager.createQuery("FROM Action AS action WHERE action.name = :name");
q.setParameter("name", name);
return q;
}
}
privileged aspect Action_Roo_JavaBean {
public java.lang.String Action.getName() {
return this.name;
}
public void Action.setName(java.lang.String name) {
this.name = name;
}
public java.lang.String Action.getDescription() {
return this.description;
}
public void Action.setDescription(java.lang.String description) {
this.description = description;
}
}
package org.academ.uthark.research.roo.domain;
privileged aspect Action_Roo_JavaBean {
public java.lang.String Action.getName() {
return this.name;
}
public void Action.setName(java.lang.String name) {
this.name = name;
}
public java.lang.String Action.getDescription() {
return this.description;
}
public void Action.setDescription(java.lang.String description) {
this.description = description;
}
}
toString()
privileged aspect Action_Roo_ToString {
public java.lang.String Action.toString() {
StringBuilder sb = new StringBuilder();
sb.append("id: ").append(getId()).append(", ");
sb.append("version: ").append(getVersion()).append(", ");
sb.append("name: ").append(getName()).append(", ");
sb.append("description: ").append(getDescription()).append(", ");
return sb.toString();
}
}
ActionEditor
import org.springframework.roo.addon.property.editor.RooEditor;
@RooEditor(providePropertyEditorFor = Action.class)
public class ActionEditor {
}
privileged aspect ActionEditor_Roo_Editor {
declare parents: ActionEditor implements java.beans.PropertyEditorSupport;
org.springframework.beans.SimpleTypeConverter ActionEditor.typeConverter = new org.springframework.beans.SimpleTypeConverter();
public java.lang.String ActionEditor.getAsText() {
Object obj = getValue();
if (obj == null) {
return null;
}
return (String) typeConverter.convertIfNecessary(((org.academ.uthark.research.roo.domain.Action) obj).getId() , String.class);
}
public void ActionEditor.setAsText(java.lang.String text) {
if (text == null || "".equals(text)) {
setValue(null);
return;
}
java.lang.Long identifier = (java.lang.Long) typeConverter.convertIfNecessary(text, java.lang.Long.class);
if (identifier == null) {
setValue(null);
return;
}
setValue(org.academ.uthark.research.roo.domain.Action.findAction(identifier));
}
}
Легко заметить, что Spring Roo забыл ещё про один важный аспект - про реализацию методов equals()
и hashCode()
. К релизу, я думаю, эта недоработка будет исправлена.
Как видно, код скрипта для генерации весьма и весьма лаконичен, а получающий java-код наглядно показывает всю многословность языка Java.
Spring Roo при создании проекта создаёт pom.xml, хорошо знакомый всем работавшим с maven. Кроме того, консоль позволяет добавлять и удалять зависимости, не правя файл вручную.
Spring Roo поддерживает расширения, что ещё больше даёт возможностей. На сегодняшний день написано уже как минимум одно расширение - Sitemesh Addon.
В первую очередь критика относится к текущему релизу, а так как он ещё в глубокой альфе, то все может измениться к официальному релизу.
<select>
В целом, Spring Roo достойное начинание, но пользоваться им в Production можно будет ещё нескоро.