AspectJ中的类型间声明的简短示例是什么,它证明了该方法的有用性?

时间:2011-09-13 14:14:09

标签: java logging types aspectj

我首先考虑使用ITD为某些不相关的案例定义private static final Logger logger = ...,但看起来不像是一个明显的改进,将其用作演示示例。

是否有一些标准/建议的ITD使用示例,人们应该将其用于教学目的?

3 个答案:

答案 0 :(得分:15)

我想在Adam的回答中添加另一个例子。

使用aspect是一种改进软件模块化的方法,以及OOP,除了OOP“垂直”应用,而AOP“水平”应用。

因此,虽然可以使用建议来“水平”修改响应某些条件的所有方法的行为,但建议中的代码也需要一些数据,而ITD可以在“水平”时添加这些字段。同时包含在单个编译单元(方面)中的相关数据和代码。

由于您是通过ITD字段添加数据,因此您可能还想提供一些操作这些字段的方法,例如setter / getter。

我试过几次改写,我希望它很容易理解。

举个例子,假设您有一个图形编辑程序,用户可以在其中创建,删除和显示多个形状(非常规范的呃?:D)。

形状有很多数据,例如它们有颜色,坐标等......它们正确地属于类本身。但是,由于这是一个Web 3.0应用程序,您希望用户能够在单个绘图上进行协作,这意味着每个形状必须知道它何时被更改,如果已经与其他用户通知形状已更改,那么它被一些实际拖动它的用户锁定..

你可以在简单的OOP中实现它,在Shape中实现相关的部分或者你的根类是什么,但是你将使用“this.setDirty(true)”或类似的东西来调查你所有的setter。

相反,你决定去AOP并在一个方面实现它。在这种情况下,您可以在所有setter之后轻松添加建议,但是如果要优化网络协议仅发送更改的增量,则还需要存储“脏”布尔值,甚至是更改的属性列表。

您可以像

一样实现它
public aspect ShapesAreDirtyThings {

   private boolean Shape.dirty;

   after(Shape s) : execution(* Shape+.set*(..)) {
       s.dirty = true;
       // Set some other global field, start a thread to communicate 
       // to other users about the change, whatever .. 
   } 

   public boolean Shape.isDirty() {
       return s.dirty;
   }

   public boolean Shape.findDirtyChildren() { // whatever
} 

对于常见的AOP来说,这是你无法做到的,只是封装在单个编译单元的建议,该建议所需的数据以及最终将对该数据进行操作的方法。

答案 1 :(得分:9)

Java不支持多重继承或mixin。但是对于ITD,你可以像{}}那样制作Scala like Traits或Ruby。

以下是利用JPA和Spring的可配置的示例:

接口:

package com.evocatus.aop;

public interface DomainNotify {

    public void postPersist();

    public void postUpdate();

    public void postRemove();

}

AspectJ ITD:

package com.evocatus.aop;

import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.Transient;

import org.codehaus.jackson.annotate.JsonIgnore;
import org.springframework.beans.factory.annotation.Autowired;

import com.evocatus.service.DomainNotifyService;


    privileged aspect DomainNotifyAdvice {

        @JsonIgnore
        @Transient
        @Autowired
        transient DomainNotifyService DomainNotify.domainNotifyService;

        @PostPersist
        public void DomainNotify.postPersist() {
            this.domainNotifyService.publishSave(this);
        }

        @PostUpdate
        public void DomainNotify.postUpdate() {
            this.domainNotifyService.publishUpdate(this);
        }

        @PostRemove
        public void DomainNotify.postRemove() {
            this.domainNotifyService.publishRemove(this);
        }

    }

现在任何实现 DomainNotify的类都将获得编织的ITD方法。

@Entity
@Configurable
public class MyJPAObject implements DomainNotify {
}

答案 2 :(得分:3)

看看Spring ROO。这是一个快速的开发。使用Spring的env。我将其视为Ruby on Rails,但在带有Spring的java中; - )

根据您在创建类时定义的属性,它会使用ITD来生成getter,setter,toString等。

Spring Roo