elasticsearch入門系列">elasticsearch入門系列
816
2022-05-30
一、注解
1.概述
概述
對我們的程序進行標注和解釋
注解和注釋的區別
注釋: 給程序員看的
注解: 給編譯器看的
使用注解進行配置配置的優勢
代碼更加簡潔,方便
2.自定義注解
格式
public @interface 注解名稱 { public 屬性類型 屬性名() default 默認值 ; }
屬性類型
基本數據類型
String
Class
注解
枚舉
以上類型的一維數組
代碼演示
public @interface Anno2 { } public enum Season { SPRING,SUMMER,AUTUMN,WINTER; } public @interface Anno1 { //定義一個基本類型的屬性 int a () default 23; //定義一個String類型的屬性 public String name() default "itheima"; //定義一個Class類型的屬性 public Class clazz() default Anno2.class; //定義一個注解類型的屬性 public Anno2 anno() default @Anno2; //定義一個枚舉類型的屬性 public Season season() default Season.SPRING; //以上類型的一維數組 //int數組 public int[] arr() default {1,2,3,4,5}; //枚舉數組 public Season[] seasons() default {Season.SPRING,Season.SUMMER}; //value。后期我們在使用注解的時候,如果我們只需要給注解的value屬性賦值。 //那么value就可以省略 public String value(); } //在使用注解的時候如果注解里面的屬性沒有指定默認值。 //那么我們就需要手動給出注解屬性的設置值。 //@Anno1(name = "itheima") @Anno1("abc") public class AnnoDemo { }
注意
如果只有一個屬性需要賦值,并且屬性的名稱是value,則value可以省略,直接定義值即可
自定義注解案例
需求
自定義一個注解@Test,用于指定類的方法上,如果某一個類的方法上使用了該注解,就執行該方法
實現步驟
自定義一個注解Test,并在類中的某幾個方法上加上注解
在測試類中,獲取注解所在的類的Class對象
獲取類中所有的方法對象
遍歷每一個方法對象,判斷是否有對應的注解
代碼實現
//表示Test這個注解的存活時間 @Retention(value = RetentionPolicy.RUNTIME) public @interface Test { } public class UseTest { //沒有使用Test注解 public void show(){ System.out.println("UseTest....show...."); } //使用Test注解 @Test public void method(){ System.out.println("UseTest....method...."); } //沒有使用Test注解 @Test public void function(){ System.out.println("UseTest....function...."); } } public class AnnoDemo { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException { //1.通過反射獲取UseTest類的字節碼文件對象 Class clazz = Class.forName("com.itheima.myanno3.UseTest"); //創建對象 UseTest useTest = (UseTest) clazz.newInstance(); //2.通過反射獲取這個類里面所有的方法對象 Method[] methods = clazz.getDeclaredMethods(); //3.遍歷數組,得到每一個方法對象 for (Method method : methods) { //method依次表示每一個方法對象。 //isAnnotationPresent(Class extends Annotation> annotationClass) //判斷當前方法上是否有指定的注解。 //參數:注解的字節碼文件對象 //返回值:布爾結果。 true 存在 false 不存在 if(method.isAnnotationPresent(Test.class)){ method.invoke(useTest); } } } }
3.元注解
概述
元注解就是描述注解的注解
元注解介紹
示例代碼
@Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD}) //指定注解使用的位置(成員變量,類,方法) @Retention(RetentionPolicy.RUNTIME) //指定該注解的存活時間 //@Inherited //指定該注解可以被繼承 public @interface Anno { } @Anno public class Person { } public class Student extends Person { public void show(){ System.out.println("student.......show.........."); } } public class StudentDemo { public static void main(String[] args) throws ClassNotFoundException { //獲取到Student類的字節碼文件對象 Class clazz = Class.forName("com.itheima.myanno4.Student"); //獲取注解。 boolean result = clazz.isAnnotationPresent(Anno.class); System.out.println(result); } }
4.改寫服務器
需求
目前項目中Servlet和url對應關系,是配置在xml文件中的,將其改為在Servlet類上通過注解配置實現
實現步驟
定義一個注解(@WebServlet),注解內有一個屬性urlPatterns
在servlet類上去使用該注解,來指定當前Servlet的訪問路徑
創建一個注解解析類(AnnoParseServletConfig),該類實現ParseServletConfig接口
實現parse方法
代碼實現
@Target(ElementType.TYPE) //指定該注解可以使用在類上 @Retention(RetentionPolicy.RUNTIME)//指定該注解的存活時間 --- 為運行期 public @interface WebServlet { //讓用戶去指定某一個Servlet在進行訪問的時候所對應的請求uri public String urlPatterns(); } // 這里只給出了LoginServlet的配置,其他Servlet同理 @WebServlet(urlPatterns = "/servlet/loginservlet") public class LoginServlet implements HttpServlet{ @Override public void service(HttpRequest httpRequest, HttpResponse httpResponse) { //處理 System.out.println("LoginServlet處理了登錄請求"); //響應 httpResponse.setContentTpye("text/html;charset=UTF-8"); httpResponse.write("登錄成功"); } } public class AnnoParseServletConfig implements ParseServletConfig { //定義一個servlet路徑所對應的常量 public static final String SERVLET_PATH = "http-dynamic-server\\src\\com\\itheima\\myservlet"; //定義包名 public static final String SERVLET_PACKAGE_NAME = "com.itheima.myservlet."; @Override public void parse() { //獲取類名 // 1.獲得servlet所在文件夾的路徑,并封裝成File對象 File file = new File(SERVLET_PATH); // 2.調用listFiles方法,獲取文件夾下所有的File對象 File[] servletFiles = file.listFiles(); // 3.遍歷數組,獲取每一個File對象 for (File servletFile : servletFiles) { // 4.獲取File對象的名字(后綴名) String servletFileName = servletFile.getName().replace(".java", ""); // 5.根據包名 + 類名 得到每一個類的全類名 String servletFullName = SERVLET_PACKAGE_NAME + servletFileName; try { // 6.通過全類名獲取字節碼文件對象 Class servletClazz = Class.forName(servletFullName); // 7.判斷該類是否有WebServlet注解 if(servletClazz.isAnnotationPresent(WebServlet.class)){ // 8.判斷該Servlet類是否實現HttpServlet接口 //獲取該類所實現的所有的接口信息,得到的是一個數組 Class[] interfaces = servletClazz.getInterfaces(); //定義一個boolean類型的變量 boolean flag = false; //遍歷數組 for (Class clazzInfo : interfaces) { //判斷當前所遍歷的接口的字節碼對象是否和HttpServlet的字節碼文件對象相同 if(clazzInfo == HttpServlet.class){ //如果相同,就需要更改flag值.結束循環 flag = true; break; } } if(flag){ // 9.如果滿足,則獲取注解中的urlPattrens的值, WebServlet annotation = (WebServlet) servletClazz.getAnnotation(WebServlet.class); String uri = annotation.urlPatterns(); // 10.創建當前Servlet類對象存入值位置 HttpServlet httpServlet = (HttpServlet) servletClazz.newInstance(); // 11.存入集合的鍵位置 ServletConcurrentHashMap.map.put(uri,httpServlet); // }else{ // 12.如果不滿足,拋出異常 //false就表示當前的類還沒有實現HttpServlet接口 throw new NotImplementsHttpServletException(servletClazz.getName() + "Not Implements HttpServlet"); } } } catch (NotImplementsHttpServletException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } } } public class LoaderResourceRunnable implements Runnable { @Override public void run() { // //執行parse方法 // ParseServletConfig parseServletConfig = new PropertiesParseServletConfig(); // parseServletConfig.parse(); // ParseServletConfig parseServletConfig = new XMLParseServletConfig(); // parseServletConfig.parse(); ParseServletConfig parseServletConfig = new AnnoParseServletConfig(); parseServletConfig.parse(); } }
5G教育 Java
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。