[ApectJ] declare parents

TommyMo

Erfahrenes Mitglied
Hi Leute!

Ich bin grade dabei mit ApsectJ ein wenig herumzutüfteln. Ich möchte ein paar Klassen, genauergesagt alle in einem bestimmten Package, um eine Methode erweitern, eigentlich um zwei ... . Auf jedenfall muss ich ja dafür im Aspekt selbst die parents Declaration durchühren.

Meine Frage nun: Wie kann ich bei der Declaration jetzt das gesammte Package, also alle Subklassen, Interfaces, etc., miteinbeziehen?

Mein Code sieht mal wie folgt aus:

Code:
declare parents: (org.omg.uml.behavioralelements+) extends Object;

Extends Object ist noch nicht das Gelbe vom Ei, aber für Testzwecke reichts mal. Ich bekomme dann aber folgende Meldung:

no match for this type name: org.omg.uml.behavioralelements [Xlint:invalidAbsoluteTypeName]

Ich komm einfach nicht weiter. Wäre nett, wenn Ihr mir da unter die Arme greifen könntet.

Gruß
TOM
 
Hallo!

Also ich würde eine Alternative vorziehen, bei der man gar keine speziellen Interfaces implementieren oder gezwungener Maszen von ableiten müsste... leider bekomme ich das im moment noch nicht hin...

Person
Code:
  /**
   * 
   */
  package de.tutorials.aspectj.domain;
  
  /**
   * @author Tom
   * 
   */
  public class Person implements IDomainType{
  	private String name;
  
  	public Person(String name) {
  		this.name = name;
  	}
  
  	public String getName() {
  		return name;
  	}
  
  	public void setName(String name) {
  		System.out.println("setName");
  		this.name = name;
  	}
  
  	public String toString() {
  		return super.toString() + "->" + this.name;
  	}
  }

IDomainType:
Code:
  /**
   * 
   */
  package de.tutorials.aspectj.domain;
  
  /**
   * @author Tom
   *
   */
  public interface IDomainType {}

IntroductionAspect:
Code:
  package de.tutorials.aspectj.aspects;
  
  import de.tutorials.aspectj.domain.IDomainType;
  
  /**
   * @author Tom
   * 
   */
  public aspect IntroductionAspect perthis(withinDomainPackage()){
  	pointcut withinDomainPackage(): within(de.tutorials.aspectj.domain.*);
  
  	public void IDomainType.foo() {
  		System.out.println("Foo: " + this);
  	}
  }
mit withinDomainPackage habe ich versucht den Aspect auf das domain package zu beschränken, was leider noch nicht wirklich funktioniert... Weiterhin verwende ich das IDomainType interface als eine Art Hook um die neue Methode foo introducen zu können...

AspectJTest:
Code:
  /**
   * 
   */
  package de.tutorials.aspectj;
  
  import de.tutorials.aspectj.domain.Person;
  
  /**
   * @author Tom
   * 
   */
  public class AspectJTest {
  
  	/**
  	 * @param args
  	 */
  	public static void main(String[] args) {
  		Person person = new Person("Thomas");
  		person.foo();
  
  		person = new Person("Stefan");
  		person.foo();
  
  		person = new Person("Dietmar");
  		person.foo();
  	}
  }

Ausgabe:
Code:
  Foo: de.tutorials.aspectj.domain.Person@110b053->Thomas
  Foo: de.tutorials.aspectj.domain.Person@a83b8a->Stefan
  Foo: de.tutorials.aspectj.domain.Person@dd20f6->Dietmar

So muss das Interface zumindest mal keine Methoden definieren und trotzdem sind die Methoden im (AspectJ Eclipse Editor) sichtbar und werden auch zur Laufzeit gefunden.
Das zeigt jedoch, wei viel Konfusion Aspect Orientierte Programmierung hervorrufen kann, wenn man keine anstaendige IDE hat die einen bei der Entwicklung von AOP basierten Anwendungen unterstuetzt.

Weiterhin wuerde ich es vorziehen Introduction nur so zu benuzten, dass es die "advised"-ten Objekte davon nichts wissen muessen...

Gruß Tom
 
Hi Tom!

Hab jetzt eine Möglichkeit gefunden die Interfaces mit einer Methode zu erweitern. Allerdings bringt mir das herzlich wenig für meine Anwendung, leider. Hat was damit zu tun, dass die Implementierklassen dynamisch zur Laufzeit erzeugt werden ... . Daher greift mein Aspekt nicht.

Ich stelle mal hier vor wie ich das Interface erweitert habe (Testcode):

Zunächst die Klasse:
Code:
public class TestClass implements TestInterface {

	public void testMethod() {
		System.out.println("testmethod");
	}
	
}

Das Interface TestInterface:

Code:
public interface TestInterface {
	public void testMethod();
}

der Aspekt:

Code:
public aspect TestAspect {
	public void TestInterface.foo() { System.out.println("fooooooo"); };
	
	pointcut testpointcut(TestClass t) : call (* TestClass.testMethod(..) ) && target(t);
	
	after(TestClass t) : testpointcut(t) {
		t.foo();
	}
}

Die Main:

Code:
public class TestMain {
	public static void main(String[] args) {
		TestClass t = new TestClass();
		t.testMethod();
	}
}

Der Output:

Code:
testmethod
fooooooo

Gruß
TOM
 
Hallo!

Hab da doch fast das gleiche gemacht ;-)
Wie waers wenn wir hier im Forum ein wenig AspectJ ping pong spielen und so ein wenig lernen?
Jemand stellt ne Aufgabe und anschliessend werden Loesungen gepostet. Im Gegenzug postet jeder Teilnehmer eine neue Aufgabe... etc.

Gruss Tom
 
Jo, fänd ich eigentlich ganz nett :)

Ich bin aber leider nicht der Könner in AspectJ ... genauer gesagt ... ich hatte zum ersten mal damit zu tun, und zum Glück eine nette Arbeitskollegin die mir da unter die Arme gegriffen hat.

Gruß
TOM
 

Neue Beiträge

Zurück