Guice: AOP类没有获得超类的注释

创建于 2014-07-07  ·  17评论  ·  资料来源: google/guice

_从anthony.muller于2008年5月30日05:41:03_

@ ME:
我很惊讶...我注释了方法@ MyAnnotation,
拦截此方法的调用。 我的问题是当我实例化一个对象时
使用guice有这样的注释。 当我搜索带注释的方法时
通过反射,我叫isAnnotationPresent(MyAnnotation.class),
此方法返回false!

@ jesse @ swank.ca:在后台,Guice创建了TotoImpl的子类
为了执行方法拦截。

在大多数情况下,这对于
开发人员,但有一些后果。 getClass()
不返回TotoImpl.class。 这限制了您
equals()方法必须实现。

我也希望Serializable不会与
方法拦截。

在这种情况下,解决方法是使用TotoImpl.class
而不是toto.getClass()对您的内省
类型。

_原始问题: http :

Component-AOP Priority-Medium bug imported

最有用的评论

是的,这已经持续了6年,我也对此感到有些震惊。我正试图添加AOP来拦截Dropwizard服务中的方法,这完全扼杀了这个想法。

所有17条评论

_从anthony.muller于2008年5月30日02:41:16_

包装吉士;

导入静态com.google.inject.matcher.Matchers.annotatedWith;
导入静态com.google.inject.matcher.Matchers.any;

导入java.lang.annotation.ElementType;
导入java.lang.annotation.Retention;
导入java.lang.annotation.RetentionPolicy;
导入java.lang.annotation.Target;
导入java.lang.reflect.Method;

导入org.aopalliance.intercept.MethodInterceptor;
导入org.aopalliance.intercept.MethodInvocation;

导入com.google.inject.AbstractModule;
导入com.google.inject.Guice;
import com.google.inject.ImplementedBy;
导入com.google.inject.Inject;
导入com.google.inject.Injector;

公共类AnnotationTest {

@ Target(ElementType.METHOD)
@保留(RetentionPolicy.RUNTIME)
@接口MyAnno {

}

@ ImplementedBy(TotoImpl.class)
界面Toto {
字符串getBidule();

setBidule(String bidule);
}

TotoImpl类实现Toto {

私有弦式双瓣;

@注入
公共TotoImpl(){}

公共字符串getBidule(){
返体
}

@ MyAnno
public void setBidule(String bidule){
this.bidule =脉络;
}
}

静态类MyInterceptor实现了MethodInterceptor {

公共对象invoke(MethodInvocation mi)抛出Throwable {
返回mi.proceed();
}

}

静态类MyModule扩展了AbstractModule {
公共无效的configure(){
//注释或取消注释此行以查看问题:
//当取消绑定时,下面的main方法
//将显示“ false”,否则显示“ true”
bindInterceptor(any(),annotatedWith(MyAnno.class),新
MyInterceptor());
}
}

公共静态void main(String [] args)抛出Throwable {
注入器注入器= Guice.createInjector(new MyModule());
Toto toto =喷射器.getInstance(Toto.class);
方法设置器= toto.getClass()。getMethod(“ setBidule”,
new Class [] {String.class});
boolean isPresent = setter.isAnnotationPresent(MyAnno.class);
System.out.println(“ Present:” + isPresent);
}
}

_从limpbizkit在2008年6月3日02:49:41_

我想了解更多-是否有特定的用例,工具或库需要此功能?

简介: AOP类没有获得超类的注释

_从robbie.vanbrabant于2008年6月3日10:13:19_

正如我在邮件列表中指出的那样,有一种解决方法:

您可以在类级别使用@继承已启用的注释,然后
像这样的课程:

@保留(运行时间)
@目标(TYPE)
@继承
公共@接口TheType {
Class <?> value();
}

@ TheType(TotoImpl.class)
静态类TotoImpl实现Toto {
...
}

方法设置器=
toto.getClass()。getAnnotation(TheType.class).value()
.getMethod(“ setBidule”,new Class [] {String.class});
boolean isPresent = setter.isAnnotationPresent(MyAnno.class);
System.out.println(“ Present:” + isPresent);

我也很好奇看看用例是什么。

_从anthony.muller于2008年6月3日12:26:08_

我的用例非常简单,我在业务类中添加了一些注释,例如
@属性, @ GenerateEvent, @子级, @父级,...这样可以添加额外的内容
信息以简化使用,执行一些测试以打印出有关
对象模型结构...

_从limpbizkit在2008年6月3日17:19:54_

克里斯-我对cglib的API一无所知,所以我问你。 解决这个问题需要大量代码吗?

抄送: chris.nokleberg

_来自chris.nokleberg ,2008年6月3日17:49:45_

它将需要代码将注释从超类复制到子类。 它
将是一项巨大的努力,并且必须是可选的,因为它不是
向后兼容,这意味着该选项必须传播到
Guice API不知何故,这很难看。 通常,只需修改您的
应用程序代码在与代理打交道时看起来“一级”。 有可能
如果Guice有一个静态方法可以告诉您对象是否来自代理,则该方法很有帮助
班级,或者也许可以让您退回无代理的班级。

_从limpbizkit在2008年6月8日16:28:43_

另请参见第101期。

_从botteaap于2008年6月29日07:18:33_

集成到现有框架时,对子类的注释继承为
很有用。 例如,swing应用程序框架对方法使用@ Action
您可以绑定到JButton。 要使其与Guice一起使用,您必须明确
传递包含动作的类,而不是克里斯建议的“ this”。
这行得通,但也暗示您不能在没有AOP方面启用某些功能
冒着破坏现有代码的风险。

_从gili.tzabari于2008年11月24日08:19:07_

仅供参考,泽西岛有一个新的挂钩,允许我将其传递给未经代理的课程,然后
检查类新泽西州的特殊注解。

_来自2008年11月24日09:28:00_的pavel.jbanov

在我的特定用例中,我遇到了Struts2 @ SkipValidation操作方法的问题
当我使用其他拦截器时使用注解...当时我确信
未在代理类方法上设置@ SkipValidation。 http://struts.apache.org/2.x/struts2-core/apidocs/org/apache/struts2/interceptor/validation/SkipValidation.html

_从roger.gonzalez在2009年9月16日18:31:19_

我认为此问题还意味着参数注释未复制到代理?

我尝试拦截一些使用注释定义参数的服务方法
JSON-RPC客户端的名称,但所需的注释均已消失。 向上看
在这种情况下,“级别”似乎不是一个可行的选择。

_从joshgr于2010年8月21日17:44:43_

我对自己的缺点感到非常沮丧:我的团队正在通过Guice使用JPA / Hibernate。 为了促进“丰富的域模型”(即直接在我们的实体类中的域逻辑),我使用了Hibernate拦截器来增强Hi​​bernate的Entity-instantiation,并使用Guice Injector构造实体实例。 这将在我们的Entity实例中启用Guice AOP和注入:我们可以使用@事务性(a-la warp-persist)注释模型方法,并且可以@直接将依赖项注入到我们的实体中。 甜!

这很不错,除了在Guice增强的实体实例上没有保留针对生命周期事件观察者的标准JPA方法注释( @ PrePersist, @ PreUpdate等)之外。 惊喜! 这导致了一个细微的错误,该错误仅在我们向现有的实体类中添加guice MethodInterceptor时才会出现...突然,我们的实体生命周期回调停止了! 谢天谢地,我进行了集成测试。

我当前正在构建一个涉及类级别EntityListener的变通方法,该方法将在树上查找以查找和调用持久性事件注释,但这非常麻烦,而且更重要的是,不认为这应该成为

如果默认情况下执行方法注释保留太昂贵,那么似乎框架应该至少应请求支持它作为绑定配置是合适的。

基于注释的工具和功能继续变得越来越普遍。 我预计,这种微妙的失败的影响对于增强功能的开发人员可能会变得更加普遍和昂贵。 请修复。

_ 2012年7月16日从[email protected]发送至

(未对此更改输入评论。)

状态:已确认
标签: Component-AOP

_从leitao.otavio于2014年2月16日09:50:33_

我正面临着joshgr所描述的相同问题,这确实令人沮丧。 我只添加了一个方法注释,Guice停止将一些(其他)注释“复制”到代理对象。 请修复它!

是的,这已经持续了6年,我也对此感到有些震惊。我正试图添加AOP来拦截Dropwizard服务中的方法,这完全扼杀了这个想法。

我认为我已经通过编写自定义方法匹配器解决了此问题-请参阅https://codingcraftsman.wordpress.com/2018/11/11/google-guice-aop-with-interface-annotations/并提供反馈(如果它是为您解决。

@ashleyfrieze的解决方案的基础上,下面是一些寻找“真实”方法的代码。 幸运的是,在我们的代码中,我们能够在特定情况下用代理方法代替真实方法:

private Method findRealMethod(Method proxiedMethod) {
    try {
        return proxiedMethod.getDeclaringClass().getSuperclass().getMethod(proxiedMethod.getName(), proxiedMethod.getParameterTypes());
    } catch (NoSuchMethodException e) {
        return proxiedMethod;
    }
}
此页面是否有帮助?
0 / 5 - 0 等级

相关问题

prasanthgithub picture prasanthgithub  ·  14评论

Cybermaxke picture Cybermaxke  ·  7评论

nathanmerrill picture nathanmerrill  ·  5评论

laurentmartelli picture laurentmartelli  ·  11评论

avoss picture avoss  ·  17评论