`
bxf12315
  • 浏览: 27154 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Annotation & Reflection 学习 及 问题

    博客分类:
  • java
阅读更多

最近在学习Anntation和Reflection,一直希望能做一个实际的应用.

所以,假象了一个例子,比如说在方法前加上Annotation来表明方法是否要进行事务处理,然后通过动态代理来执行.

1 MyAnnotationI

java 代码
  1. public interface MyAnnotationI {   
  2.     public void printString();   
  3.   
  4.     public void printString1();   
  5. }   

java 代码
  1. public class MyAnnotationImpl implements MyAnnotationI {   
  2.     @MyAnnotation(isTransaction ="yes")   
  3.     public void printString() {   
  4.         System.out.print("\n"+" don some thing");   
  5.     }   
  6.        
  7.     @MyAnnotation(isTransaction="yes")   
  8.     public void printString1() {   
  9.         System.out.print("\n"+" good work");   
  10.     }   
  11.        
  12. }  

 

3 然后是定义的Annotation

java 代码
  1. @Retention(java.lang.annotation.RetentionPolicy.RUNTIME)   
  2. public @interface MyAnnotation {   
  3.     String isTransaction();   
  4. }   

 

我希望能在执行 MyAnnotationImpl 的;两个方法是做一个判断,来看是否执行事务代码. 下面是我写的代理类

 

java 代码
  1. public class MyHandler implements InvocationHandler {   
  2.     private Object o;   
  3.   
  4.     public MyHandler(Object delegate) {   
  5.         o = delegate;   
  6.     }   
  7.   
  8.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {   
  9.         Object a = null;   
  10.         try{   
  11.         System.out.print("\n"+"Start transaction ");   
  12.         a = method.invoke(o, args);   
  13.         System.out.print("\n"+"end transaction ");   
  14.         }   
  15.         catch(Exception e)   
  16.         {   
  17.             System.out.print("\n"+"Exception");   
  18.         }   
  19.         return null;   
  20.     }   
  21.   
  22. }  

 

也就是希望在方法上有isTransaction ="yes"的方法前后执行两行代码.

下面是运行代码

 

java 代码
  1. public class MyAnnotationTest {   
  2.   
  3.     
  4.   
  5.     public  void dynamicProxy()   
  6.     {   
  7.            
  8.     }   
  9.     public static void main(String[] args) {   
  10.         try {   
  11.             Class bean = Class.forName("com.my.annotation.one.MyAnnotationImpl");   
  12.             Method method[] = bean.getMethods();   
  13.             for (int i = 0; i < method.length; i++) {   
  14.                 if (method[i].getName().equals("printString1")) {   
  15.                     MyAnnotation an = method[i].getAnnotation(MyAnnotation.class);   
  16.                     if(an.isTransaction().equals("yes"))   
  17.                     {   
  18.                       Object o =   bean.newInstance();   
  19.                         InvocationHandler handler = new MyHandler(bean.newInstance());   
  20.                         MyAnnotationI proxy = (MyAnnotationI) Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(),   
  21.                                 handler);   
  22.                         Method m =     proxy.getClass().getDeclaredMethod("printString1"null);   
  23.   
  24.                         m.invoke(proxy, new Object[]{});   
  25.                     }   
  26.                 }   
  27.   
  28.             }   
  29.   
  30.         } catch (Exception e) {   
  31.             System.out.println(e.toString());   
  32.         }    
  33.   
  34.     }   
  35.   
  36. }  

 

输出结果如下:

Start transaction
 good work
end transaction

 这样看似通过Annotation和Reflection 实现了一个事物,但是我有些问题.

1 这里是我指明了要调用哪个方法的,如果我也不知道具体执行那个方法.需要在运行时动态的去判定,我该怎么做?

2 我在 proxy.getClass().getDeclaredMethod("printString1"null)中调用的无参数的方法,如果我的执行方法有参数, 程序怎么知道有那些 参数,如果得到要调用的方法?

希望明白的朋友给我指点一二.

分享到:
评论
7 楼 bxf12315 2007-11-29  
calmness 写道
bxf12315 写道
calmness 写道
这段代码应该是没问题的,最好能把测试的代码以及出错的详细信息都发上来。

这是我的测试代码
 Class bean = Class.forName("com.my.annotation.two.MyAnnotationImpl");
            // Method method[] = bean.getMethods();
            Object o = bean.newInstance();
            InvocationHandler handler = new MyHandler(bean.newInstance());
            MyAnnotationI proxy = (MyAnnotationI) Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(), handler);
            Method method[] = proxy.getClass().getMethods();
            for (int i = 0; i < method.length; i++) {
                    Object oo = method[i].invoke(proxy, new Object[] {});
            }


如果我直接通过proxy调用具体的方法时,是没有问题的。
另外,我把annotation写到interface里面了。
然后出现哪个异常,不知道原因了。


晕,看到这么长串测试代码我的头也晕了,你为什么要用invoke来测试?你直接用代理的类来call方法就可以了啊,
proxy.printString();
这样就行了。我就搞不懂你为什么还要绕个大圈最后用invoke来调用,郁闷。


其实,后来我也发现我这样做意义不大了。我本意就是想把我的实现类里面的2个方法都执行一下,看看输出。出了这个异常就像看看怎么回事,呵呵。
其实,就像你说的那样完全可以call了。
目的主要是想搞清楚这个异常为什么出,我觉得可能我在对Annotation和Reflection了解上还存在问题。
多谢了
6 楼 calmness 2007-11-28  
bxf12315 写道
calmness 写道
这段代码应该是没问题的,最好能把测试的代码以及出错的详细信息都发上来。

这是我的测试代码
 Class bean = Class.forName("com.my.annotation.two.MyAnnotationImpl");
            // Method method[] = bean.getMethods();
            Object o = bean.newInstance();
            InvocationHandler handler = new MyHandler(bean.newInstance());
            MyAnnotationI proxy = (MyAnnotationI) Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(), handler);
            Method method[] = proxy.getClass().getMethods();
            for (int i = 0; i < method.length; i++) {
                    Object oo = method[i].invoke(proxy, new Object[] {});
            }


如果我直接通过proxy调用具体的方法时,是没有问题的。
另外,我把annotation写到interface里面了。
然后出现哪个异常,不知道原因了。


晕,看到这么长串测试代码我的头也晕了,你为什么要用invoke来测试?你直接用代理的类来call方法就可以了啊,
proxy.printString();
这样就行了。我就搞不懂你为什么还要绕个大圈最后用invoke来调用,郁闷。
5 楼 bxf12315 2007-11-28  
calmness 写道
这段代码应该是没问题的,最好能把测试的代码以及出错的详细信息都发上来。

这是我的测试代码
 Class bean = Class.forName("com.my.annotation.two.MyAnnotationImpl");
            // Method method[] = bean.getMethods();
            Object o = bean.newInstance();
            InvocationHandler handler = new MyHandler(bean.newInstance());
            MyAnnotationI proxy = (MyAnnotationI) Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(), handler);
            Method method[] = proxy.getClass().getMethods();
            for (int i = 0; i < method.length; i++) {
                    Object oo = method[i].invoke(proxy, new Object[] {});
            }


如果我直接通过proxy调用具体的方法时,是没有问题的。
另外,我把annotation写到interface里面了。
然后出现哪个异常,不知道原因了。
4 楼 calmness 2007-11-27  
这段代码应该是没问题的,最好能把测试的代码以及出错的详细信息都发上来。
3 楼 bxf12315 2007-11-27  
calmness 写道
仔细来看LZ的两个问题其实都是因为代码没有写好的缘故造成的,其实LZ应该在InvocationHandler 的实现invoke方法中获取方法注解声明,然后判断是否需要进行事务处理,如果有声明则在invoke中将该方法的调用放入到事务中,否则则直接调用,不知道这样说LZ明白么?应该将事务处理逻辑放到invoke中。


ok,非常感谢。我按照3楼的建议。做了些修改,把是否执行事务的判断放到invoke中执行,这样我说的问题解决了。
但是现在会抛出一个异常--java.lang.reflect.InvocationTargetException(对带有指定参数的指定对象调用由此 Method 对象表示的基础方法。实在不明白什么意思)

是在invoke执行后抛出的,望3楼在帮我解答一下。
对了忘了贴出代码
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object a = null;
        try {
            
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation an = method.getAnnotation(MyAnnotation.class);
                if (an.isTransaction().equals("yes") && an != null) {
                    System.out.print("\n" + "Start transtion");
                    a = method.invoke(o, args);
                    System.out.print("\n" + "end transtion");
                } else {
                    a = method.invoke(o, args);
                }
            }
            return null;
        } catch (Exception e) {
            System.out.print("\n" + "invoke Exception");
        }
        return a;
    }
2 楼 calmness 2007-11-27  
仔细来看LZ的两个问题其实都是因为代码没有写好的缘故造成的,其实LZ应该在InvocationHandler 的实现invoke方法中获取方法注解声明,然后判断是否需要进行事务处理,如果有声明则在invoke中将该方法的调用放入到事务中,否则则直接调用,不知道这样说LZ明白么?应该将事务处理逻辑放到invoke中。
1 楼 bxf12315 2007-11-26  
自己顶一下,那位帮我看看啊

相关推荐

    浙大软件学院培训课件java reflection annotation

    【标题】"浙大软件学院培训课件java reflection annotation"主要涵盖了Java编程语言中的两个重要概念:反射(Reflection)和注解(Annotation)。这两个概念在Java开发中具有深远的影响,尤其是在进行元编程、动态...

    Annotation--学习:限定使用、文档、继承

    在Java编程语言中,注解(Annotation)是一种元数据,它提供了在代码中附加信息的能力,这些信息可以被编译器或运行时环境用来验证、处理或增强代码的行为。本篇我们将深入探讨“限定使用、文档、继承”这三个关键...

    annotation.zip

    在Java编程语言中,注解(Annotation)和反射(Reflection)是两个非常重要的特性,它们在实际开发中扮演着不可或缺的角色。"annotation.zip"文件很可能包含了一组关于这两个主题的教程或示例代码,用于帮助学习者...

    study-annotation:Annotation学习

    本项目"study-annotation"旨在深入学习和理解Java注解的使用和实现机制。 首先,我们了解Java内置的注解类型,例如`@Override`、`@Deprecated`和`@ SuppressWarnings`。`@Override`确保方法重写了父类的方法,`@...

    反射Reflection小应用

    在Java编程语言中,反射(Reflection)是一种强大的工具,它允许程序在运行时检查和操作类、接口、字段和方法的信息。通过反射,我们可以动态地创建对象、调用方法、访问字段,甚至处理私有成员,这在某些情况下非常...

    java基础学习过程练习代码

    在这个"java基础学习过程练习代码"中,我们看到涉及了几个关键的Java概念和技术,包括Bean、FileUpload、IO流、Annotation、Reflection和Thread。下面将详细阐述这些知识点。 1. **Bean**:在Java中,Bean通常指的...

    1java初学者学习源代码.zip

    13. **注解(Annotation)**:学习如何使用注解来提供元数据,以及预定义的和自定义的注解。 14. **反射(Reflection)**:探索如何在运行时检查类、接口、字段和方法的信息,以及动态调用方法。 15. **枚举(Enum...

    java学习的demo

    学习如何创建自定义注解及如何使用预定义的注解,如@Override、@Deprecated等,有助于提高代码的可读性和可维护性。 9. **反射(Reflection)**:反射允许在运行时检查和修改类、接口、字段和方法的信息。它是实现...

    学习java的朋友必学的东西

    Java是世界上最流行的编程语言之一,尤其在企业级应用开发中占据主导地位。"学习java的朋友必学的东西"这个标题暗示了我们...在学习过程中,理论结合实践是非常重要的,不断尝试解决问题,才能真正掌握这些核心概念。

    JAVA帮助文档,为用户学习JAVA带来方便

    通过这份Java帮助文档,用户不仅可以查找特定类和方法的详细信息,还能学习到如何有效地使用这些工具来解决实际问题。无论是新手还是经验丰富的开发者,都能从中受益,提升自己的Java编程技能。在学习过程中,结合...

    Java学习部分代码

    14. **Java 8及以后的新特性**:包括Lambda表达式、Stream API、Optional类、方法引用和日期时间API等,这些新特性极大地提升了Java的简洁性和效率。 通过这个"Java学习部分代码"的资源,你可以找到关于上述知识点...

    java学习手册好好学习他

    14. **注解(Annotation)**:注解是元数据的一种形式,提供了一种安全的方法来关联信息和代码,编译器和JVM可以使用这些信息。 15. **反射(Reflection)**:反射允许程序在运行时检查类、接口、字段和方法的信息...

    java 学习代码这些是一些基础例子

    12. **注解(Annotation)**:注解是一种元数据,可以提供编译器或运行时系统使用的信息,如用于代码分析、测试或性能优化。 13. **反射(Reflection)**:反射允许在运行时检查和操作类、接口、字段和方法,提供了动态...

    java课件(各章都有) 含实例

    除了基础知识,这个压缩包可能还包含了高级主题,如反射(reflection)、注解(annotation)、泛型(generics)、枚举(enum)、Lambda表达式和Stream API,这些都是Java 5及以上版本引入的新特性。此外,对于Java ...

    狂神说笔记,个人觉得不赖

    在Java的学习过程中,注解(Annotation)和反射(Reflection)是两个非常关键且高级的主题。 注解是Java提供的一种元数据机制,它允许程序员在代码中嵌入额外的信息,这些信息可以被编译器或者运行时环境用来执行...

    注解和反射机制的学习笔记

    在Java编程语言中,注解(Annotation)和反射(Reflection)是两个强大的工具,它们极大地扩展了代码的灵活性和动态性。这篇学习笔记将深入探讨这两个主题,帮助开发者更好地理解和运用它们。 首先,我们来了解注解...

    注解与反射-狂神说Java学习笔记

    在Java编程语言中,注解(Annotation)和反射(Reflection)是两个非常重要的高级特性,它们为程序提供了元数据信息和运行时动态操作类的能力。本文将深入探讨这两个概念及其在实际开发中的应用。 首先,让我们了解...

    java 基础代码知识,很好的入门学习资料

    8. **反射(Reflection)**: - 反射允许在运行时动态获取类的信息(如类名、方法名)并调用方法,提供了强大的动态性。 9. **注解(Annotation)**: - 注解是元数据的一种形式,用于向编译器或JVM提供额外信息...

    良葛格java jdk 5.0学习笔记

    - 注解(Annotation)是元数据的一种形式,Java 5.0引入了变量级别的注解,比如`@Deprecated`,用于标记过时的变量。 5. **增强的for循环(For-Each Loop)**: - Java 5.0引入的增强for循环简化了遍历数组和集合...

Global site tag (gtag.js) - Google Analytics