Java Spring Boot VS .NetCore (一)來一個簡單的 Hello Worldhtml
Java Spring Boot VS .NetCore (二)實現一個過濾器Filterjava
Java Spring Boot VS .NetCore (三)Ioc容器處理sql
Java Spring Boot VS .NetCore (四)數據庫操做 Spring Data JPA vs EFCore數據庫
Java Spring Boot VS .NetCore (五)MyBatis vs EFCore編程
Java Spring Boot VS .NetCore (六) UI thymeleaf vs cshtmlapp
Java Spring Boot VS .NetCore (七) 配置文件框架
Java Spring Boot VS .NetCore (八) Java 註解 vs .NetCore Attribute函數
Java Spring Boot VS .NetCore (九) Spring Security vs .NetCore Security工具
Java Spring Boot VS .NetCore (十) Java Interceptor vs .NetCore Interceptor性能
Java Spring Boot VS .NetCore (十一)自定義標籤 Java Tag Freemarker VS .NetCore Tag TagHelper
繼續前面的章節,這裏我介紹下註解,其實Java註解跟.NetCore的特性標籤相似,下面咱們經過代碼來講明
首先我先說下Java註解須要使用的註解
@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
Taget:指定註解在什麼地方生效,做用於什麼對象上,參數不少這裏把源碼拉出來了,每個的意思就不過多介紹,一看就明白
public enum ElementType { /** 類、接口(包括註釋類型)或枚舉聲明 */ TYPE, /** 字段聲明(包括枚舉常量) */ FIELD, /** 方法聲明 */ METHOD, /** 形式參數聲明 */ PARAMETER, /** 構造函數聲明 */ CONSTRUCTOR, /** 局部變量聲明 */ LOCAL_VARIABLE, /** 註釋類型聲明 */ ANNOTATION_TYPE, /** 程序包聲明 */ PACKAGE, /** * 類型參數聲明 * * @since 1.8 */ TYPE_PARAMETER, /** * 使用類型 * * @since 1.8 */ TYPE_USE }
public enum RetentionPolicy { /** 註解將被編譯器丟棄 */ SOURCE, /** 註解將由編譯器記錄在類文件中,但在運行時不須要由VM保留。這是默認的行爲。 */ CLASS, /** 註解將由編譯器記錄在類文件中,並在運行時由VM保留,所以能夠經過反射讀取當前註解。*/ RUNTIME }
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Documented { /* 註解代表這個註解應該被 javadoc工具記錄 */ }
下面就來模擬一個自定義的註解,同時簡單並模擬MyBatis中的像以下寫法,解析下面代碼的實現原理
@Select("SELECT username,email,newname,nick_name FROM user_model") @Results({ @Result(property = "username", column = "username"), @Result(property = "email", column = "email"), @Result(property = "newname", column = "newname"), @Result(property = "nickName", column = "nick_name") }) List<UserModel> getAll();
這裏定義一個自定義的註解接口 代碼以下,註解要做用於方法上
Target(value = ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CustomSelect { String Sql() default ""; }
這一步也很是簡單,定義一個操做接口,使用自定義的註解,添加好相關的Sql語句
public interface ReflectorDao { @CustomSelect(Sql = "select * from user_model where id=1") int InsertModel(); }
接下來就是怎麼使用了,固然這裏仍是要用到反射 ,這裏我添加了一個測試方法,裏面模擬實現了一個JDBC的操做方法
@Test public void testReflectorDao() throws Exception { Class<?> c= ReflectorDao.class; Method method=c.getMethod("InsertModel"); CustomSelect customSelect=method.getAnnotation(CustomSelect.class); String strsql= customSelect.Sql(); System.out.print(strsql+"\r\n"); //調用JDBC完成操做 JDBCHelper.ExcuteQuery(strsql); }
這裏反射裏面的方法就不特殊說明了,這裏說下 獲取註解的方法把,以下
// // 獲取某個類型的註解 // public <A extends Annotation> A getAnnotation(Class<A> annotationClass); // // 獲取全部註解(包括父類中被Inherited修飾的註解) // public Annotation[] getAnnotations(); // // 獲取聲明的註解(可是不包括父類中被Inherited修飾的註解) // public Annotation[] getDeclaredAnnotations(); // // 判斷某個對象上是否被某個註解進行標註 // public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) // // // 獲取某個類聲明的全部字段 // public Field[] getDeclaredFields() throws SecurityException; // // 獲取某個方法 // public Method getMethod(String name, Class<?>... parameterTypes);
執行下單元測試: OK
Java中有的 .NetCore同樣能實現,這裏就要介紹.NetCore總的特性了,就是Attribute類,怎麼來使用這個呢?不要急,經過帶來是解釋,自定義的特性須要繼承Attribute類,且類名能夠以Attribute結尾,這樣在使用的時候就能夠經過前面的名稱來寫,代碼以下
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] public class CustomAttribute : Attribute { public string Sql { get; set; } }
看到這裏,就有一種熟悉感,看下源碼,這裏什麼Class 等等更Java用法同樣標識該特性做用於什麼對象上,AllowMultiple :標識是否能夠指定屢次,同一個對象上屢次使用特性,Inherited:當前特性是否能夠被繼承
// // 摘要: // Specifies the application elements on which it is valid to apply an attribute. [Flags] public enum AttributeTargets { // // 摘要: // Attribute can be applied to an assembly. Assembly = 1, // // 摘要: // Attribute can be applied to a module. Module = 2, // // 摘要: // Attribute can be applied to a class. Class = 4, // // 摘要: // Attribute can be applied to a structure; that is, a value type. Struct = 8, // // 摘要: // Attribute can be applied to an enumeration. Enum = 16, // // 摘要: // Attribute can be applied to a constructor. Constructor = 32, // // 摘要: // Attribute can be applied to a method. Method = 64, // // 摘要: // Attribute can be applied to a property. Property = 128, // // 摘要: // Attribute can be applied to a field. Field = 256, // // 摘要: // Attribute can be applied to an event. Event = 512, // // 摘要: // Attribute can be applied to an interface. Interface = 1024, // // 摘要: // Attribute can be applied to a parameter. Parameter = 2048, // // 摘要: // Attribute can be applied to a delegate. Delegate = 4096, // // 摘要: // Attribute can be applied to a return value. ReturnValue = 8192, // // 摘要: // Attribute can be applied to a generic parameter. GenericParameter = 16384, // // 摘要: // Attribute can be applied to any application element. All = 32767 }
下面咱們一樣用接口來實現,代碼以下,前面說了 自定義屬性已Attribute結尾的類名,寫的時候直接寫Custom
public interface RelactorDao { [Custom(Sql = "select * from user_model where id=1")] void InsertModel(); }
這裏我寫一個測試類是看下,因爲時間的關係,這裏就不寫SqlHelper 來執行了,輸入下Sql就好了,這個跟Java同樣須要使用反射,思想同樣,只是使用方法名稱不一樣而已,具體的方法就不作介紹..有興趣本身瞭解下
public class TestClass { public void TestMethod() { var type = typeof(RelactorDao); MethodInfo methodInfo= type.GetMethod("InsertModel"); var atrrs = methodInfo.GetCustomAttributes(typeof(CustomAttribute), false) as CustomAttribute[]; var strSql = atrrs.First().Sql; //固然這裏也能夠執行 Console.WriteLine(strSql); } }
接下來咱們在看下執行效果 OK
這裏只是簡單的模擬下,其實要實現MyBatis中的註解的功能,其實還須要其餘的知識,面向切面編程的技術AOP
Java中的 @Aspect 註解 ,.NetCore 能夠經過動態代理來實現,可是反過來想下,.NetCore中同樣能夠實現相似於MyBait同樣使用方式的ORM框架,可能.NetCore中考慮到大量應用反射會致使性能問題