abstract class Identifiable<T, K extends Comparable<K>> implements Comparable<Identifiable<T, K>> {
@Retention(RetentionPolicy.RUNTIME)
public @interface Identifier { }
private static Method getMethodAnnotatedWith(final Class<?> type) {
return Arrays.stream(type.getDeclaredMethods())
.filter(m -> m.isAnnotationPresent(Identifier.class))
.findFirst()
.orElse(null);
}
private K id;
@SuppressWarnings("unchecked")
public Identifiable(Class<T> clazz) {
var m = getMethodAnnotatedWith(clazz);
if (m == null) throw new IllegalArgumentException(
clazz.toString() + " does not have a method annotated by @Identifier"
);
try {
id = (K) m.invoke(this);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public int compareTo(@NotNull Identifiable<T, K> i) {
return id.compareTo(i.id);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Identifiable<?, ?> that = (Identifiable<?, ?>) o;
return id == that.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
class Foo extends Identifiable<Foo, Integer> {
private final int i;
Foo(int i) {
super(Foo.class);
this.i = i;
}
@Identifier
int getI() {
return i;
}
}
但是,由于某种原因,ID
总是0
,所以我不确定这是identifier
注释类的问题还是我使用反射的方式的问题。我很确定是后者,因为在调试时,我发现它能够访问带有注释的方法。如有任何帮助,不胜感激,谢谢!
不要在构造过程中调用带注释的方法。
如果标识符值是不可变的(final
),只需将该值传递给超级构造函数即可。
public Identifiable(K id) {
this.id = id;
}
Foo(int i) {
super(i);
this.i = i;
}
如果标识符值是可变的,则需要更改逻辑以便在需要该值时调用方法,而不是在构造期间缓存该值。
abstract class Identifiable<T, K extends Comparable<K>> implements Comparable<Identifiable<T, K>> {
@Retention(RetentionPolicy.RUNTIME)
public @interface Identifier {/**/}
private Method idGetter;
protected Identifiable(Class<T> type) {
this.idGetter = Arrays.stream(type.getDeclaredMethods())
.filter(m -> m.isAnnotationPresent(Identifier.class))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(type.getName() + " does not have a method annotated by @Identifier"));
}
@SuppressWarnings("unchecked")
private final K getIdentifiableKey() {
try {
return (K) this.idGetter.invoke(this);
} catch (IllegalAccessException e) {
throw new IllegalAccessError(e.getMessage());
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
@Override
public int compareTo(Identifiable<T, K> that) {
return this.getIdentifiableKey().compareTo(that.getIdentifiableKey());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Identifiable<?, ?> that = (Identifiable<?, ?>) o;
return this.getIdentifiableKey().equals(that.getIdentifiableKey()); // Call equals(), don't use ==
}
@Override
public int hashCode() {
return Objects.hash(this.getIdentifiableKey());
}
}
abstract class Identifiable<T extends Identifiable<T, K>, K extends Comparable<K>> implements Comparable<Identifiable<T, K>> {
private Function<T, K> idGetter;
protected Identifiable(Function<T, K> idGetter) {
this.idGetter = Objects.requireNonNull(idGetter);
}
@Override
@SuppressWarnings("unchecked")
public int compareTo(Identifiable<T, K> that) {
return this.idGetter.apply((T) this).compareTo(that.idGetter.apply((T) that));
}
@Override
@SuppressWarnings("unchecked")
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Identifiable<T, K> that = (Identifiable<T, K>) o;
return this.idGetter.apply((T) this).equals(that.idGetter.apply((T) that));
}
@Override
@SuppressWarnings("unchecked")
public int hashCode() {
return Objects.hash(this.idGetter.apply((T) this));
}
}
class Foo extends Identifiable<Foo, Integer> {
private final int i;
Foo(int i) {
super(Foo::getI);
this.i = i;
}
int getI() {
return i;
}
}
我正在尝试在数据库中保存对象。正在执行代码并创建实体的Id,但实体未持久化到数据库(未插入行): 从三行(beginTransation,flush,commit)中删除注释解决了问题,但是为什么注释在这里不起作用呢? spring XML: POM xml文件:
我在玩和 这是我的应用程序上下文文件 以下是我的Java类 HelloWorld1。JAVA 住址JAVA 这里是我尝试运行东西的地方-应用程序。JAVA 我一直在得到这个异常-理想情况下我不应该,因为我已经定义了id为'address1'的@Qualifier注释-所以它不应该抛出异常 警告:上下文初始化过程中遇到的异常-取消刷新尝试:org.springframework.beans.fact
我的spring应用程序有点小问题。下面是我的代码: (存储库) 下面是我的简单服务类: 更新:配置
我将Spring 3.2.4与JavaFX结合使用,并希望实现一种方法,其中操作将在事务中执行。我在控制器中的代码如下所示: 以及我的应用程序上下文: 尝试运行时,我收到以下错误消息: 该方法存在。删除注释,或者将方法从public更改为private,或者从配置中删除bean,程序就会运行,但事务注释根本不起作用。删除代理目标会导致另一个错误。
你好,朋友,我正在开发基于spring(4.0.3)和hibernate(4.3.6)的应用程序。在会话工厂中保存任何对象时,我遇到以下错误: 下面是我在application-context.xml中使用的条目 还有一件事我想带到这里,如果我在事务管理器属性中使用了任何值,而不是实际的transactionManager作为bean引用,那么这不是抛出错误。所以我认为它没有参考价值<请帮帮我!!