Что является кратким примером объявлений между типами в AspectJ, который демонстрирует полезность этого подхода? - PullRequest
9 голосов
/ 13 сентября 2011

Сначала я подумал об использовании ITD для определения private static final Logger logger = ... для некоторых несвязанных случаев, но это не выглядит как очевидное улучшение, чтобы использовать его в качестве демонстрационного примера.

Существует ли какой-либо стандартный / предлагаемый пример использования ITD, который люди должны использовать в учебных целях?

Ответы [ 3 ]

15 голосов
/ 13 сентября 2011

Я хотел бы добавить еще один пример к ответу Адама.

Использование аспектов - это способ улучшить модульность вашего программного обеспечения, а также ООП, за исключением того, что ООП применяется "вертикально", в то время как АОПприменяется "по горизонтали".

Таким образом, хотя совет можно использовать для изменения "по горизонтали" поведения всех методов, отвечающих некоторым критериям, для всего кода в рекомендациях также потребуются некоторые данные, а ITD позволяетдобавьте, что поля «горизонтально», в то же время содержат в одном блоке компиляции (аспекте) связанные данные и код.

Поскольку вы добавляете данные через поля ITD, вы, вероятно, также захотите предложить некоторыеметод манипулирования этими полями, например, метод установки / получения.

Я пытался перефразировать его несколько раз, я надеюсь, что это легко понять.

Для примера, предположим, у вас естьпрограмма графического редактирования, где пользователь может создавать, удалять и отображать несколько фигур (довольно канонично, а?: D).

У фигур много данных.а, например, они имеют цвет, координаты и т. д., которые правильно принадлежат самому классу.Тем не менее, поскольку это приложение Web 3.0, вы хотите, чтобы пользователи могли взаимодействовать на одном чертеже, а это означает, что каждая фигура должна знать, когда она изменяется, если она была передана другим пользователям, что фигура изменилась, не важнозаблокирован каким-то пользователем, который на самом деле его перетаскивает и т. д.«this.setDirty (true)» или подобный материал.

Вместо этого вы решаете пойти AOP и реализовать его в аспекте.В этом случае вы можете легко добавить рекомендацию после всех установщиков, но вам также нужно будет сохранить «грязный» логический параметр или даже список свойств, которые изменились, если вы хотите оптимизировать сетевой протокол, отправляя только дельты изменений.

Вы можете реализовать это как

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, это просто вопрос включения в единый совет модуля компиляции данных, необходимых для этого совета, иметоды, которые в конечном итоге будут работать с этими данными.

9 голосов
/ 13 сентября 2011

Java не поддерживает множественное наследование или смешивание. Но с помощью ITD вы можете сделать Scala как черты или Ruby как миксины.

Вот пример использования JPA и Spring Configurable:

Интерфейс:

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 {
}
3 голосов
/ 16 сентября 2011

Взгляните на Spring ROO.Это быстрый разработчик.env используя Spring.Я вижу его как Ruby on Rails, но в Java с Spring; -)

Он много использует ITD для генерации getter, setter, toString и т. Д. На основе атрибутов, которые вы определяете при создании вашего Class.

Spring Roo

...