我们如何在特定的java类行中应用面向方面的编程?

时间:2017-04-25 15:03:41

标签: aspectj

How can we apply aop on the last line of main method ?

下面是java中按值调用的测试类。我在一次采访中被要求在课程的最后一行应用面向方面的编程。是否可以在任何java类的特定行上应用AOP,如果是,那么请给出一些示例代码。

public class TestCallByValue {

    public static void main(String[] args) {
        Student st = new Student("Sanjeev", 1);

        changeName(st);

        System.out.println(st.getName());//apply aop on this line to stop printing sysout
    }

    public static void changeName(Student st) {
        st = new Student("Rajeev", 2);
        st.setName("Amit");
    }

}

class Student {
    String name;
    Integer id;

    public Student(String name, Integer id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

}

2 个答案:

答案 0 :(得分:0)

可以在特定的java代码行上应用的内容称为 joinpoint

link列出了您可以在代码中使用aspectj设置的可能连接点。如您所见,只能将构造函数调用,方法调用,字段初始化等定义为连接点

唯一的方法是在System.out#println上应用切入点。您也可以将System.out.println(st.getName());封装在专用方法

答案 1 :(得分:0)

AspectJ不对源代码进行操作,它在Java程序的语义结构上运行。因此,它没有" line"的概念。面试官意味着您应该阻止特定方法调用的发生,并告诉您该方法调用的位置,在这种特殊情况下,它是main方法的最后一个语句。

此声明位于TestCallByValue.main()方法中,并在println()上调用System.out,即PrintStream。虽然我们无法向AspectJ表明我们只想阻止" last"执行声明,我们可以缩小到

  

方法调用println类的PrintStream方法,在String方法中包含的代码中接受TestCallByValue.main()并返回void一个字符串数组并返回void

要阻止方法调用的发生,您需要一个 around advice ,它不会调用proceed()。我们还可以检查方法调用的目标是否实际为System.out,因此我们仅在System.out.println(String)的其他实例上阻止println(String),而不是PrintStream调用。

以上可以通过以下方面实现:

aspect DummyAspect {

    pointcut printlnStatementInMain(): withincode(void TestCallByValue.main(String[])) 
        && call(void java.io.PrintStream.println(String));

    void around(): printlnStatementInMain() {
        if (thisJoinPoint.getTarget() != System.out) {
            proceed();
        }
    }

}