English 中文(简体)
AOP 或APT 适用于超级班级的压倒性方法
原标题:AOP or APT for overriding methods from super classes

我拥有一个附有习惯说明的广域网各组成部分的图书馆@ReferencedResource或另一个注释@ReferencedResources,该图书馆有ReferencedResouce[] Value(, para amount to take multi note.

这里是一部法规样本:

@ReferencedResources({
    @ReferencedResource(value = Libraries.MOO_TOOLS, type = ResourceType.JAVASCRIPT),
    @ReferencedResource(value = "behaviors/promoteSelectOptions", type = ResourceType.JAVASCRIPT) })
public class PromoteSelectOptionsBehavior extends AbstractBehavior{
 ...
}

到目前为止,我使用apt,以核实参考资源确实存在。 E.g.

@ReferencedResource(value = "behaviors/promoteSelectOptions",
                     type = ResourceType.JAVASCRIPT)

除非文件js/behaviors/promoteSelectOptions.j在班上找到,否则将造成汇编失败。 这一部分非常可行。

现在,我也是南盟的狂热人物,我也想利用同样的说明,在美帝国成立时,实际上向它们注入资源。 我利用AspectJ执行了其中一部分。

附加说明的物体通常有以下两种情况:Component AbstractBehavior

对部件而言,事情很容易,在建筑商之后就好了。 此处建议:

pointcut singleAnnotation() : @within(ReferencedResource);

pointcut multiAnnotation() : @within(ReferencedResources);

after() : execution(Component+.new(..)) && (singleAnnotation() || multiAnnotation()){
    final Component component = (Component) thisJoinPoint.getTarget();
    final Collection<ReferencedResource> resourceAnnotations =
        // gather annotations from cache
        this.getResourceAnnotations(component.getClass());
    for(final ReferencedResource annotation : resourceAnnotations){
        // helper utility that handles the creation of statements like
        // component.add(JavascriptPackageResource.getHeaderContribution(path))
        this.resourceInjector.inject(component, annotation);
    }
}

然而,为了采取行动,我需要把资源放在对策上,而不是放在行为本身上。 我使用的是:

pointcut renderHead(IHeaderResponse response) :
    execution(* org.apache.wicket.behavior.AbstractBehavior+.renderHead(*))
        && args(response);

这里的建议是:

before(final IHeaderResponse response) : 
    renderHead(response) && (multiAnnotation() || singleAnnotation()) {
    final Collection<ReferencedResource> resourceAnnotations =
        this.getResourceAnnotations(thisJoinPoint.getTarget().getClass());
    for(final ReferencedResource resource : resourceAnnotations){
        this.resourceInjector.inject(response, resource);
    }
}

如果该类别超越了 /renderHead(response),但在许多情况下,没有必要,因为超级班子已经执行基础功能,而儿童班子只增加一些。 因此,一种解决办法是让这些阶层确定这样一种方法:

@Override
public void renderHead(IHeaderResponse response){
    super.renderHead(response);
}

我会对此表示仇恨,因为这是一部死亡法典,但目前这是我所看到的唯一工作选择,因此我正在寻求其他解决办法。

EDIT:

我利用APT和Sainjavac电话建立了工作解决办法。 然而,这导致下一个问题:Running APT and AspectJ in the same project using maven

无论如何,只要我有一段自由的时间,我就将回答这个问题(或部分问题)。

最佳回答

回答我自己的问题:

这里是添加“超级呼吁”的相关法典范围:

http://download.oracle.com/javase/6/docs/api/javax/annotation/ treatment/AbstractProcessor.html#init%28javax.annotation.process.Processing Environment%29”rel=“nofollow noreferer”>_init(env)或

private static Filer filer;
private static JavacProcessingEnvironment environment;
private static Messager messager;
private static Types types;
private static JavacElements elementUtils;
private Trees trees;
private TreeMaker treeMaker;
private IdentityHashMap<JCCompilationUnit, Void> compilationUnits;
private Map<String, JCCompilationUnit> typeMap;

如果是<代码>的亚类,则此处指的逻辑。 摘要Behavior,凡有通知的,不优先于<代码>renderHead(response)方法:

private void addMissingSuperCall(final TypeElement element){
    final String className = element.getQualifiedName().toString();
    final JCClassDecl classDeclaration =
        // look up class declaration from a local map 
        this.findClassDeclarationForName(className);
    if(classDeclaration == null){
        this.error(element, "Can t find class declaration for " + className);
    } else{
        this.info(element, "Creating renderHead(response) method");
        final JCTree extending = classDeclaration.extending;
        if(extending != null){
            final String p = extending.toString();
            if(p.startsWith("com.myclient")){
                // leave it alone, we ll edit the super class instead, if
                // necessary
                return;
            } else{
                // @formatter:off (turns off eclipse formatter if configured)

                // define method parameter name
                final com.sun.tools.javac.util.Name paramName =
                    elementUtils.getName("response");
                // Create @Override annotation
                final JCAnnotation overrideAnnotation =
                    this.treeMaker.Annotation(
                        Processor.buildTypeExpressionForClass(
                            this.treeMaker,
                            elementUtils,
                            Override.class
                        ),
                        // with no annotation parameters
                        List.<JCExpression> nil()
                    );
                // public
                final JCModifiers mods =
                    this.treeMaker.Modifiers(Flags.PUBLIC,
                        List.of(overrideAnnotation));
                // parameters:(final IHeaderResponse response)
                final List<JCVariableDecl> params =
                    List.of(this.treeMaker.VarDef(this.treeMaker.Modifiers(Flags.FINAL),
                        paramName,
                        Processor.buildTypeExpressionForClass(this.treeMaker,
                            elementUtils,
                            IHeaderResponse.class),
                        null));

                //method return type: void
                final JCExpression returnType =
                    this.treeMaker.TypeIdent(TypeTags.VOID);


                // super.renderHead(response);
                final List<JCStatement> statements =
                    List.<JCStatement> of(
                        // Execute this:
                        this.treeMaker.Exec(
                            // Create a Method call:
                            this.treeMaker.Apply(
                                // (no generic type arguments)
                                List.<JCExpression> nil(),
                                // super.renderHead
                                this.treeMaker.Select(
                                    this.treeMaker.Ident(
                                        elementUtils.getName("super")
                                    ),
                                    elementUtils.getName("renderHead")
                                ),
                                // (response)
                                List.<JCExpression> of(this.treeMaker.Ident(paramName)))
                            )
                     );
                // build code block from statements
                final JCBlock body = this.treeMaker.Block(0, statements);
                // build method
                final JCMethodDecl methodDef =
                    this.treeMaker.MethodDef(
                        // public
                        mods,
                        // renderHead
                        elementUtils.getName("renderHead"),
                        // void
                        returnType,
                        // <no generic parameters>
                        List.<JCTypeParameter> nil(),
                        // (final IHeaderResponse response)
                        params,
                        // <no declared exceptions>
                        List.<JCExpression> nil(),
                        // super.renderHead(response);
                        body,
                        // <no default value>
                        null);

                // add this method to the class tree
                classDeclaration.defs =
                    classDeclaration.defs.append(methodDef);

                // @formatter:on turn eclipse formatter on again
                this.info(element,
                    "Created renderHead(response) method successfully");

            }
        }

    }
}
问题回答

暂无回答




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签