Java 字段初始化后的方法执行

Java 字段初始化后的方法执行,java,aop,aspectj,Java,Aop,Aspectj,我有一个定义数据库行访问的类 public abstract class DBRow { int index; DBConnection connection; public DBRow(DBConnection con, int id) { connection = con; index = id; } public DBRow(DBConnection con) { this(con, -1);

我有一个定义数据库行访问的类

public abstract class DBRow {
    int index;

    DBConnection connection;

    public DBRow(DBConnection con, int id) {
        connection = con;
        index = id;
    }

    public DBRow(DBConnection con) {
        this(con, -1);
    }

    public abstract String getTableName();

    private static String getFieldName(Field field) {
        ...
    }

    public void save() {
        ... (Reads all fields that are annotated with @InDB and saves them
    }

    public void load() {
        ... (Will load a row from the database or create a new one if index == -1)
    }
}
数据库中的特定行扩展了这个DBRow类。 例如:

public class Test extends DBRow {
    @InDB
    public String vct;

    @InDB
    public int intt;

    public Test(DBConnection con, int id) {
        super(con, id);     

        vct = "test";
        intt = 123;
    }

    @Override
    public String getTableName() {
        return "test";
    }
}
在构造函数被调用之后,应该调用“load”,这样就可以从数据库中加载行,或者正确地创建和保存行

public aspect DBRowLoadSave {
    pointcut load() : execution(DBRow.new(*, *));

    after() : load() {
        ((DBRow)thisJoinPoint.getThis()).load();
    }
}

我的问题是,此时字段将不会初始化,因为切入点在测试的母类中侦听构造函数调用,而不是在测试本身中。有没有一种方法可以侦听子类的所有构造函数,或者有没有另一种方法可以在类完全初始化后执行load方法?

我不确定到底发生了什么,因为您的构造函数没有调用任何方法,所以初始化对象应该没有问题。一些猜测可能是:

public Test(DBConnection con, int id) {
    vct = "test";
    intt = 123;
    super(con, id);
}
在调用超级构造函数之前设置值,或

public String vct = "test";

public int intt = 123;

public Test(DBConnection con, int id) {
    super(con, id);
}
将值直接设置为字段。如果这些都不起作用,那么初始化就没有问题,问题就在别处。

执行(DBRow+.new(..)
匹配所有子类构造函数,但包括基类。因此,您需要通过
排除它!执行(DBRow.new(..)

此外,您可以通过
this()
将创建的对象直接绑定到变量,从而避免
getThis()
调用和通知中的强制转换

公共方面DBRowLoadSave{
切入点负载(DBRow DBRow):
执行(数据库行+新(..)&&
!执行(DBRow.new(..)&&
这(dbRow);
之后(DBRow DBRow):加载(DBRow){
System.out.println(此连接点);
load();
}
}

您的第一个建议不是有效的Java代码。由于Java被编译成字节码的方式,您的秒解决方案也无法工作。