注解与反射 ---Spring与Mybatis等框架的实现原理

Java中各大框架,无论是AOP 还是 IoC 其基本实现思路都是源自Java 运行时支撑的反射功能,

而反射最基本的一点就是 任何一个类 其在JVM环境中,都有一个对象的Class对象,这个对象提供一些方面描述了类的 方法 构造函数 注解 等等等

 

下面就是一个反射跟注解的小例子,是一个比较好入门的小demo

理解之后,几乎所有的框架都是依照这个思路来实现的

package pw.jonwinters.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;



@Documented//生成javadoc会包含注解信息
@Inherited//允许子类注解继承
@Target({ElementType.METHOD,ElementType.CONSTRUCTOR,ElementType.TYPE})//注解作用的位置 method为方法上的注解 constructor为构造器上的注解 TYPE则是针对类型以及接口等上的注解
@Retention(RetentionPolicy.RUNTIME)//注解的生存周期,这里注明runtime运行时,也就是说这个注解在编译成class文件 运行在虚拟机的时候 这个注解信息依然存在
public @interface Description {
    String desc() default "winter";//default 默认没有赋值的话 则为winter
}
package pw.jonwinters.annotation;

import java.lang.reflect.Method;

import org.junit.Test;

import static org.junit.Assert.assertNotNull;
@Description
public class Man implements Person {

    @Override
    @Description
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("I am run() method!");
    }
    
    @Test
    public  void testAnnotation() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
        Class clazz = Class.forName("pw.jonwinters.annotation.Man");//首先通过Class.forName加载我们的Man类
        assertNotNull("can't find class",clazz);//找不到就提示
        Method[] methods = clazz.getDeclaredMethods();//获得clazz对象之后,获取Man类的所有方法 
        for (Method method:methods){
            if(method.isAnnotationPresent(Description.class)){//针对每一个方法 判断它是否存在Description注解
                System.out.println("method: "+method.getName()+"() has Description annotation!");
                System.out.println(method.getAnnotation(Description.class).desc());//打印注解的desc字段 默认是winter
            }
            if(method.isAnnotationPresent(Override.class))
                System.out.println("method: "+method.getName()+" has Override annotation!"); //overrider注解是 RetentionPolicy.SOURCE 只针对源码存在,在JVM运行时环境不存在 所以我们是无法找到run()方法上面的override注解的
        }
        if ( clazz.isAnnotationPresent(Description.class))
        {
            ((Man)clazz.newInstance()).run();//最后如果类 也存在Description注解的话 则实例化一 clazz对象 向下转型为Man方法 调用其run方法打印 I am run method
        }
    }

}

 

posted on 2016-09-25 18:28  winters86  阅读(438)  评论(0编辑  收藏  举报