3

各クラス内で(静的なfinal)Loggerインスタンスを宣言するInter-Type宣言を作成したいと思います。

コンストラクターには、それを囲むクラスKlazz.class値を渡す必要があります。

@Aspect
public class LoggerAspect {

    public interface Logger {
    }

    public static class LoggerImpl implements Logger {
        private static final Logger logger = 
          new Logger(thisJoinPoint.getTarget().getClass()/*.getName()*/);
    }

    @DeclareParents(value="com.my.api..*",defaultImpl=LoggerImpl.class)
    private Logger implementedInterface;
}

thisJoinPoint上記のソリューションを作成しましたが、AspectJの外部では使用できませんadvice

Loggerのデフォルト実装がクラスKlazzに適用されている場合、上記のコードを変更して、Klazz.classをLoggerコンストラクターに正常に渡すにはどうすればよいですか?

4

2 に答える 2

7

タイプ間宣言を介して、任意の単一クラスで静的メンバーを宣言できます。

public aspect LoggingAspect {
    static Logger MyClass.someField = Logger.getLogger(MyClass.class.getName());
}

ただし、これは単一のクラスごとに行う必要があるため、あまり柔軟ではありません。私はそれについて言及したかっただけです。

技術的にではなく効果的に静的メンバーであるものをクラスに追加するには、ロギングの側面にタイプごとの関連付けを使用するだけです。

public aspect LoggingAspect
    pertypewithin(org.foo..*)              // per-type association
{
    Logger logger;

    after() : staticinitialization(*) {    // run 1x after class-loading
        logger = Logger.getLogger(
            getWithinTypeName()            // type associated with aspect instance
        );
    }

    pointcut logged() :                    // what to log, e.g. public methods
        execution(public * *(..));         // (pointcut could also be abstract
                                           // and refined in sub-aspects)

    before() : logged() {
        logger.log(...);                   // logging action
    }
}

これに似た例(これは一般的なパターンです)は、ラムニヴァス・ラダッドの優れた本AspectJ in action(2nd edition)の6.2.4章にあります。これは、 AspectJのドキュメントにも記載されています。

于 2012-08-26T02:38:11.293 に答える
3

この回答は、便宜上以下に投稿された正しい解決策を提供します。さらに、現在推奨されている表記法である AspectJ アノテーションを使用します。

開発者は最近注釈 API を追加しました。これは、Spring のような他の多くの人気のあるライブラリも行っているように、マークアップを標準化する意図があると推測されます。

@Aspect("pertypewithin(com.something.*))")
public abstract class TraceAspect {

    Logger logger;

    @Pointcut
    public abstract void traced();

    @Pointcut("staticinitialization(*)")
    public void staticInit() {
    }

    @After(value = "staticInit()")
    public void initLogger(JoinPoint.StaticPart jps) {
        logger = Logger.getLogger(jps.getSignature().getDeclaringTypeName());
    }

    @Before(value = "traced()")
    public void traceThatOne(JoinPoint.StaticPart jps) {
        logger.log(jps.getSignature().getName());
    }
}
于 2012-08-26T14:57:42.733 に答える