2012-04-24 2 views
2

Я хочу, чтобы изменить объект возврата из вызова в constuctorAspectJ конструктор сила завод шаблон

ОТ

public class A { 

    public A(){ 
    } 

    public String sayHello() { 
    return "hello"; 
    } 

    public String foo() { 
     return "foo"; 
    } 

} 

К

public class AWrapped extends A { 

    private A wrapped; 

    public AWrapped() { 
     super(); 
    } 


    public AWrapped(A pWrapped) { 
     wrapped=pWrapped; 
    } 

    public String foo() { 
     return wrapped.foo(); 
    } 

    public String sayHello { 
     return "gday mate"; 
    } 

} 

Что я хочу сделать для изменения объекта, возвращаемого по вызову

A a = new A(); 
a.sayHello() returns "gday mate" 

а является instaceof AWrapped

Я понимаю, что это обычно делается с рисунком фабрики, но я не имею доступа к коду или код, который делает новый в. И есть 1000 мест, которые могут быть созданы A.

Кажется, что Aspectj может сделать трюк, но я не знаю много об этом, если AspectJ будет делать трюк, как мне обойти бесконечную упаковку, мне нужно знать, что она была consturcted изнутри и в аспект, так что это doesnt оберните его снова.

Спасибо за помощь Jon

+0

Если вы создадите 'новый A()' позже, он все равно скажет «привет». Угадайте, первая строка вашего последнего примера должна читать 'A a = new AWrapped()' –

+1

Спасибо Марко, что имеет смысл, мне все еще нужно решить проблему, поэтому я собираюсь попробовать создать пользовательский загрузчик классов и посмотреть, могу ли я получить вокруг него так. Еще раз спасибо – user898333

+0

@ user898333, это похоже на путь. Пожалуйста, после того, как вы решите проблему, разместите ее здесь как ответ на свой вопрос. – Yaneeve

ответ

6

Если я вас понимаю правильно, вы можете сделать следующее:

Я создал три пакета:

package structure

  • AspectJ для аспект и AWrapped.java
  • неизвестен для A.java (также может быть b е Bytecode, но тогда вы должны использовать Load Time Weaving)
  • основной для тестирования A a = new A();

MyAspect вернуть AWrapped объект, если new() вызов сделан на класс А:

package aspectj; 

import unknown.A; 

@Aspect 
public class MyAspect { 

    @Pointcut("call(unknown.A.new(..)) && !within(aspectj..*)") 
    public static void init(ProceedingJoinPoint pjp) { 
    } 

    @Around("init(pjp)") 
    public Object initAdvice(ProceedingJoinPoint pjp) throws Throwable{ 
     Object ret = pjp.proceed(); 
     return new AWrapped((A) ret); 
     } 

} 

Для тестирования:

package main; 

import unknown.A; 

public class Main { 

    public static void main(String[] args) { 
     A a = new A(); 
     System.out.println(a.sayHello()); 
    } 
} 

В этом выходы:

gday mate 
+0

Удивительно, избили меня! –

Смежные вопросы