- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在网上找了好久。但没有用。请帮忙或尝试给出一些如何实现这一目标的想法
在我的客户端中,我可以使用真实对象而不是代理对象来获取方法上的注释。
我曾经以为是因为我自己的Annotation上缺少Retention Annotation。但这不起作用。这是代码:
注释:
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}
界面:
public interface UserDao {
void save();
void update();
}
实现:
public class UserDaoImpl implements UserDao{
@Override
@MyAnnotation
public void save() {
System.out.println("save");
}
@Override
public void update() {
System.out.println("update");
}
}
客户端+驱动程序应用程序:
public class Client {
public static void main(String[] args) {
final UserDaoImpl dao = new UserDaoImpl();
Method[] methods = dao.getClass().getMethods();
for (Method m : methods){
if(m.getAnnotation(MyAnnotation.class) != null)
System.out.println("save method is enhanced");
}
UserDao proxy = (UserDao) Proxy.newProxyInstance(
dao.getClass().getClassLoader(),
dao.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
obj = dao;
if(method.getAnnotation(MyAnnotation.class) != null)
System.out.println("save method is enhanced2");
Object result = method.invoke(obj, args);
return result;
}
}
);
proxy.save();
System.out.println("-----------");
proxy.update();
}
}
最佳答案
动态代理直接实现给定的接口(interface),它不会像您假设的那样扩展实现类。我已经修复了您的非编译代码,添加了更多日志输出,并将所有类移至我的一个包中,因为 Java 编译器不喜欢默认包。
驱动程序应用程序(已更新):
package de.scrum_master.so;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) {
final UserDaoImpl dao = new UserDaoImpl();
Method[] methods = dao.getClass().getMethods();
for (Method method : methods) {
if (method.getAnnotation(MyAnnotation.class) != null) {
System.out.println(method + " -> " + method.getDeclaringClass());
System.out.println("impl method is enhanced");
}
}
System.out.println("-----------");
UserDao proxy = (UserDao) Proxy.newProxyInstance(
dao.getClass().getClassLoader(),
dao.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
obj = dao;
System.out.println(method + " -> " + method.getDeclaringClass());
if (method.getAnnotation(MyAnnotation.class) != null)
System.out.println("proxy method is enhanced");
Object result = method.invoke(obj, args);
return result;
}
});
proxy.save();
System.out.println("-----------");
proxy.update();
}
}
控制台日志:
public void de.scrum_master.so.UserDaoImpl.save() -> class de.scrum_master.so.UserDaoImpl
impl method is enhanced
-----------
public abstract void de.scrum_master.so.UserDao.save() -> interface de.scrum_master.so.UserDao
save
-----------
public abstract void de.scrum_master.so.UserDao.update() -> interface de.scrum_master.so.UserDao
update
在这里您可以看到UserDaoImpl
和动态UserDao
代理之间的区别。
我不确定你为什么用 spring
和 aop
标记这个问题,因为在你的示例代码中没有 AOP 也没有 Spring,但我想你想使用 Spring AOP也是基于动态代理的。您可以选择强制将实现接口(interface)的组件创建为 CGLIB 代理,即代理直接扩展其基类。也许它可以工作,但我不确定 CGLIB 代理的详细工作原理。如果它们要重写每个方法,则会应用 JVM 限制:重写方法永远不会继承方法注释。
您的技术问题就这么多。但你真正想要实现的目标是什么?这是许多人在这里犯的一个错误:他们没有描述他们想要实现的目标,但心中已经有了一个可能不合适的技术解决方案。这样他们就错过了解决问题的其他选择。通常,应用程序设计是基于他们的错误假设而存在缺陷的,如果他们不那么执着于他们的解决方案偏差,那么很容易修复。也许如果这对您没有帮助,您可以创建一个新问题,将其链接到这个问题,其中显示您的 Spring AOP 问题并描述您想要实现的目标。
<小时/>更新:如果您想从代理的调用处理程序访问原始(“真实”)对象,您可以这样做:
改进的驱动程序应用程序:
package de.scrum_master.so;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) {
final UserDaoImpl dao = new UserDaoImpl();
Method[] methods = dao.getClass().getMethods();
for (Method method : methods) {
if (method.getAnnotation(MyAnnotation.class) != null) {
System.out.println(method + " -> " + method.getDeclaringClass());
System.out.println("impl method is enhanced");
}
}
System.out.println("-----------");
UserDao proxy = (UserDao) Proxy.newProxyInstance(
dao.getClass().getClassLoader(),
dao.getClass().getInterfaces(),
new MyInvocationHandler(dao)
);
proxy.save();
System.out.println("-----------");
proxy.update();
}
private static class MyInvocationHandler implements InvocationHandler {
private Object realObject;
public MyInvocationHandler(Object realObject) {
this.realObject = realObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method + " -> " + method.getDeclaringClass());
if (method.getAnnotation(MyAnnotation.class) != null)
System.out.println("proxy method is enhanced");
if (realObject.getClass().getMethod(method.getName(), method.getParameterTypes()).getAnnotation(MyAnnotation.class) != null)
System.out.println("real object method is enhanced");
return method.invoke(realObject, args);
}
}
}
控制台日志:
public void de.scrum_master.so.UserDaoImpl.save() -> class de.scrum_master.so.UserDaoImpl
impl method is enhanced
-----------
public abstract void de.scrum_master.so.UserDao.save() -> interface de.scrum_master.so.UserDao
real object method is enhanced
save
-----------
public abstract void de.scrum_master.so.UserDao.update() -> interface de.scrum_master.so.UserDao
update
请注意行增强了真实对象方法
。
关于java - 无法从JDK动态代理获取方法注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43152221/
所以`MKAnnotation's。有趣的东西。 我的问题: 注释的标题和副标题有什么区别?这对注释的视觉组件有何影响? MKPinAnnotationView 和 MKAnnotationView
我正在使用 JBoss 工具将 DB 模式反向工程到 POJO 中。具体来说,我在 hibernatetool ANT 任务中使用了 hbm2java 选项。在 hbm2java 选项下,您可以指定
假设我有这段文字: cat file /* comment */ not a comment /* another comment */ /* delete this * /* multiline
我明白,如果你///在类、字段、方法或属性上方 Visual Studio 将开始为您建立 XML 样式的注释。 但是,我在哪里可以为我的命名空间和/或库添加 XML 注释... 例如: .NET F
int API_VERSION = 21; @TargetApi(API_VERSION)在Android中用于指定该方法/类支持API_VERSION及以下。 我们是否可以镜像类似的东西,指定仅支持
Closed. This question needs to be more focused。它当前不接受答案。
假设我有一个界面如下。 public interface MyInterface{ /** * This method prints hello */ void sayHello();
我已将 Jboss 应用程序迁移到 WebSphere Liberty。我必须删除所有 Jboss 引用库。在这样做的同时,我在某些注释中面临问题。 Jboss 应用程序使用 @SecurityDom
在本教程中,您将了解 JavaScript 注释,为什么要使用它们以及在示例的帮助下如何使用它们。 JavaScript 注释是程序员可以添加的提示,以使代码更易于阅读和理解。JavaScri
我正在建立一个博客,为了发表评论,我有这个 CSS。 #comments { position:absolute; border: 1px solid #900; border-width: 1
我正在尝试在单元格中插入评论。我正在尝试按照代码进行评论,但它没有在创建的 excel 中显示评论。我正在创建 .xls 扩展名。 $objPHPExcel->getActiveSheet()->ge
我正在使用 TS 在 MarionetteJS 上编写项目,我想使用注释来注册路由。例如: @Controller class SomeController { @RouteMapping("so
我有一个应用程序可以在页面上生成大量注释。用户可以单击页面上的任意位置以创建快速注释(例如 Acrobat Pro)可以在一般 中使用一些 javascript 行添加和删除这些注释
是否有 JavaScript 注释? 当然 JavaScript 没有它们,但是是否有额外的库或建议的语言扩展,例如 @type {folder.otherjsmodule.foo} function
Java 中注解的目的是什么?我有一个模糊的想法,认为它们介于注释和实际代码之间。它们在运行时会影响程序吗? 它们的典型用法是什么? 它们是 Java 独有的吗?有 C++ 等价物吗? 最佳答案 注解
其实我们在 Ruby 基础语法 已经比较详细的介绍了 Ruby 语言中的注释 Ruby 解释器会忽略注释语句 注释会对 Ruby 解释器隐藏一行,或者一行的一部分,或者若干行。 Ruby 中的注
我正在 try catch VBA 注释。到目前为止,我有以下内容 '[^";]+\Z 它捕获以单引号开头但在字符串结尾之前不包含任何双引号的任何内容。即它不会匹配双引号字符串中的单引号。 dim s
有没有办法在'svn commit'上将提交注释添加到更改的文件中。有人告诉我有一种方法可以用 cvs 做到这一点,但我们使用 svn。目前,我们使用“$Revision”关键字将修订号添加到更改的文
我正在尝试通过 ManyToMany 注释自动对报告的结果进行排序 @OrderBy : /** * @ORM\ManyToMany(targetEntity="Artist", inversedB
我正在使用 JBoss 5 GA,我创建了一个测试 session bean 和本地接口(interface)。我创建了一个 servlet 客户端。我尝试使用 @EJB 将接口(interface)
我是一名优秀的程序员,十分优秀!