注解与反射 ---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 } } }