字段初始化后的方法执行
Method execution after fields are initialized
我有一个 class 定义了数据库的行访问权限。
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 class。
例如:
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();
}
}
我的问题是,此时字段不会被初始化,因为切入点在 Test 的母体 class 中监听构造函数调用,而不是在 Test 本身中。有没有一种方法可以听取子 classes 的所有构造函数,或者有另一种方法可以在 class?
完全初始化后执行加载方法
我不确定到底发生了什么,因为您的构造函数没有调用任何方法,所以初始化对象应该没有问题。一些猜测修复是:
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);
}
直接将值设置为字段。如果这些都不起作用,则初始化没有问题,问题出在其他地方。
execution(DBRow+.new(..))
匹配所有子class 构造函数,但包括基础class。所以你需要通过 !execution(DBRow.new(..))
.
排除它
此外,您可以通过 this()
将创建的对象直接绑定到变量,避免在建议中调用 getThis()
和强制转换。
public aspect DBRowLoadSave {
pointcut load(DBRow dbRow) :
execution(DBRow+.new(..)) &&
!execution(DBRow.new(..)) &&
this(dbRow);
after(DBRow dbRow) : load(dbRow) {
System.out.println(thisJoinPoint);
dbRow.load();
}
}
我有一个 class 定义了数据库的行访问权限。
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 class。 例如:
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();
}
}
我的问题是,此时字段不会被初始化,因为切入点在 Test 的母体 class 中监听构造函数调用,而不是在 Test 本身中。有没有一种方法可以听取子 classes 的所有构造函数,或者有另一种方法可以在 class?
完全初始化后执行加载方法我不确定到底发生了什么,因为您的构造函数没有调用任何方法,所以初始化对象应该没有问题。一些猜测修复是:
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);
}
直接将值设置为字段。如果这些都不起作用,则初始化没有问题,问题出在其他地方。
execution(DBRow+.new(..))
匹配所有子class 构造函数,但包括基础class。所以你需要通过 !execution(DBRow.new(..))
.
此外,您可以通过 this()
将创建的对象直接绑定到变量,避免在建议中调用 getThis()
和强制转换。
public aspect DBRowLoadSave {
pointcut load(DBRow dbRow) :
execution(DBRow+.new(..)) &&
!execution(DBRow.new(..)) &&
this(dbRow);
after(DBRow dbRow) : load(dbRow) {
System.out.println(thisJoinPoint);
dbRow.load();
}
}