1.何为注解
简单来说,注解就是元数据,何为元数据,元数据就是对数据(这里所说的数据也可以说是对象)的一种描述数据。
但是只描述数据并没有什么意思,对于此类描述性数据做出相应的操作才是我们真正想要的。
所以下面我们了解一下注解的具体工作形式。
2.注解工作流程
-
定义 注解类
相当于定义了注解的数据结构,这只是相当于定义了对某个类附加的元数据(描述),并没有任何实际的操作,具体操作需要在注解处理器类完成。@Target(ElemenType.METHOD) @Retention(RetentionPolicy.Runtime) public @interface SqlStringt(){ public String value() default ""; } @Target(ElemenType.PARAMETER) @Retention(RetentionPolicy.Runtime) public @interface Param(){ public String value() default ""; }
-
使用注解关键字
在需要使用相关注解的地方添加注解。public Interface UserControler(){ @SqlStringt(value="select * from user where username=#{username}") public User GetUser(@Param(value=username) String username); }
-
编写 注解处理类
这里就可以实现对被描述对象的相关操作了。通过扫描用到相关注解的类,提取关键信息,实现相关方法。public class SqlAnnotationProcess{ public static void SqlExcute(Class<?> cl){ //反射获取类实例对象的方法,并解析出注解实例 for(Method m:cl.getDeclaredMethods()){ SqlString sqlStatement = m.getAnnotation(SqlString.class); if(sqlStatement !=null){ //注册数据库驱动 String driver = "com.mysql.jdbc.Driver"; String url = "jdbc:mysql://127.0.0.1:3306/mydb2"; String user = "root"; String password = "root"; Class.forName(driver); //取得数据库连接 conn = DriverManager.getConnection(url, user, password); conn .executeQuery(sqlStatement .value()); } } } }
3.注解原理
通过上面分析,其实我们可以看出,这就是通过代理模式实现的。对于添加了注解的对象,会通过注解处理类进行代理(其实这就是一个动态代理对象),它通过反射方式获得运行类的实例对象(不需要外部传入对象引用,这也是和装饰器模式的主要要区别,因为装饰器模式需要持有外部传入实例对象的引用),并根据相关注解解析方法(如上例中的getAnnotation())就可获得注解,并会执行相关注解需要的方法,同事也可代理实例对象,完成某些想要的功能。
注解使用了@方式,同样的在js和python中也使用了@,但是与Java不同的是,他们叫的是装饰器,其实这两者实现原理完全不同,Java中的@叫注解且使用的是动态代理模式,而Python、js中使用的是装饰器模式,但是虽然原理不一样,他们想要完成的功能,在我看来是类似的,都是为了减少模板代码,提高程序的可扩展性,快捷编程,在各种框架中会经常看见他们的身影。=>比如Spring中可以通过注解@bean @service等实现IOC/AOP等功能,在这些框架中,他们自定义了这些注解和相应的注解处理类,无需我们自己编写。