aspects_具有Aspects的Java中的Mixin –用于Scala特性示例

aspects

Scala特征允许将新行为混合到一个类中。 考虑两个特征,可以向JPA实体添加审核和与版本相关的字段:

package mvcsample.domain

import javax.persistence.Version
import scala.reflect.BeanProperty
import java.util.Date

trait Versionable {
  @Version
  @BeanProperty
  var version: Int = _
}

trait Auditable {
  @BeanProperty
  var createdAt: Date = _

  @BeanProperty
  var updatedAt: Date = _
}

现在将“ Versionable”和“ Auditable”及其成员实体中的字段和行为混合在一起:

@Entity
@Table(name = 'members')
class Member(f: String, l: String) extends BaseDomain with Auditable with Versionable {

  def this() = this(null, null)

  @BeanProperty
  var first: String = f

  @BeanProperty
  var last: String = l

  @OneToMany(fetch = FetchType.EAGER, mappedBy = 'member')
  @BeanProperty
  var addresses: java.util.List[Address] = _
}

trait BaseDomain {
  @BeanProperty
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = 'id')
  @Id
  var id: Long = 0
}

现在,上面的Member类将具有BaseDomain类的行为,并且将具有Versionable特性和Auditable特性的行为。 普通的Java无法实现这种混合,因为具有字段和行为的特征等同于一个抽象(或具体)类,而Java只允许从1个基类派生。 但是,使用AspectJ可以实现等效的mixin。 考虑使用Aspectj语言定义的以下方面:

package mvcsample.aspect;

import javax.persistence.Column;
import javax.persistence.Version;
import mvcsample.annot.Versioned;

public interface Versionable {

    static aspect VersionableAspect {
        declare parents: @Versioned  mvcsample.domain.* implements Versionable;

        @Version
        @Column(name = 'version')
        private Integer Versionable.version;    

        public Integer Versionable.getVersion() {
        return this.version;
            }

        public void Versionable.setVersion(Integer version) { 
        this.version = version;
        }
    }
}

package mvcsample.aspect;

import java.util.Date;
import javax.persistence.Column;

import mvcsample.annot.Audited;
public interface Auditable {
    static aspect AuditableAspect {
        declare parents: @Audited mvcsample.domain.* implements Auditable ;

        @Column(name='created_at')
        private Date Auditable.createdAt;

        @Column(name='updated_at')
        private Date Auditable.updatedAt;

        public Date Auditable.getCreatedAt(){
            return this.createdAt;
        }

        public void Auditable.setCreatedAt(Date createdAt) {
            this.createdAt = createdAt;
        }

        public Date Auditable.getUpdatedAt(){
            return this.updatedAt;
        }

        public void Auditable.setUpdatedAt(Date updatedAt) {
            this.updatedAt = updatedAt;
        }
    }
}

“声明父母:@Versioned mvcsample.domain。*实现了Versionable;” Aspectj构造将'Versionable'接口作为父级添加到包'mvcsampple.domain'中以@Versioned注释的任何类的父类中,类似于用于'Auditable'的类。 然后,该方面着手将字段添加到Versionable接口中,该接口随后又将字段添加(混合)到目标实体类中,这样,与Audit相关和Version相关的字段和方法就混合到了实体类中。 定义了这两个方面之后,目标实体类将如下所示:

@Entity
@Table(name="members")
@Access(AccessType.FIELD)
@Versioned
@Audited
public class Member extends BaseDomain{
 
 public Member(){}
 
 public Member(String first, String last){
  this.first = first;
  this.last = last;
 }
 
 private String first;
 
 @Size(min=1)
 private String last;
 
 @OneToMany(fetch=FetchType.EAGER, mappedBy="member")
 private List<address>addresses = new ArrayList<>();
        .....
}
</address>

在Versionable和Auditable方面中定义的字段和行为将混入该实体(更一般地,混入具有@Versioned和@Audited批注的任何实体)。 可能不如Scala特质那么干净,但效果很好。

参考: Java与Aspects中的Mixin –all和其他博客上获取我们JCG合作伙伴 Biju Kunjummen 的Scala特性示例

翻译自: https://www.javacodegeeks.com/2013/01/mixin-in-java-with-aspects-for-a-scala-traits-sample.html

aspects

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值