• 注解


    注解的基本知识:

    1.示列

    @Deprecated :标注XX过时

    @SuppressWarning:抑制警告:unused:抑制的警告类型{ "unused", "rawtypes", "unchecked" }:数组,抑制的多个警告类型;all:抑制所有警告

    @Override:保证用户确实是覆盖了父类的某个方法。

    2.自定义注解

    使用@interface关键字来声明注解;public @interface MyAnn1{};声明注解的属性字段:类型   字段名()[defalut  默认值];

    注解的类型只能是下面的几个:String     Class     八个类型     注解类型     枚举类型     及以上类型的1维数组;

    特殊属性:String    value;或者String[]  value();   使用时候直接给定取值,而不用加属性名称;

    3.元注解

    服务于注解的注解就是元注解

    @Retention:指定注解的存活范围。默认是CLASS

    RetentionPolicy:SOURCE|CLASS|RUNTIME

    @Target:指定注解可以用在什么元素上

    ElementType:TYPE|METHOD|。。。

     1 import java.lang.annotation.ElementType;
     2 import java.lang.annotation.Retention;
     3 import java.lang.annotation.RetentionPolicy;
     4 import java.lang.annotation.Target;
     5 
     6 @Retention(RetentionPolicy.RUNTIME)
     7 @Target(ElementType.METHOD)
     8 public @interface MyTest {
     9     long time() default -1;
    10 }
    @Retention@Target

    @Documented: 用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档.

    @Inherited: 被它修饰的 Annotation 将具有继承性.如果某个类使用了被 @Inherited 修饰的 Annotation, 则其子类将自动具有该注解

    注解的反射

     1 import java.lang.reflect.InvocationTargetException;
     2 import java.lang.reflect.Method;
     3 
     4 //反射注解:所有注解类型都是Annotation类型的子类
     5 /*
     6 java.lang.reflect.AnnotatedElement:
     7     <T extends Annotation> getAnnotation(Class<T> annotationType):
     8         获取指定类型的注解
     9     Annotation[] getAnnotations():获取所有的注解
    10     Annotation[] getDeclareAnnotations():返回直接存在于此元素上的所有注释
    11     boolean isAnnotationPresend(Class<? extends Annotation>):有木有指定的注解
    12     
    13     Class, Constructor, Field, Method, Package都实现了该接口
    14  */
    15 public class MyTestRunner {
    16     //执行测试:
    17     /*
    18      * 获取要测试的java类:MyJunitTest
    19      * 取到其中的所有方法:Method
    20      * 看看谁的方法前面有@MyTest的注解,谁有就执行谁
    21      */
    22     public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {
    23         test2();
    24     }
    25     //反射带有属性的注解
    26     private static void test2() throws IllegalAccessException,
    27             InvocationTargetException, InstantiationException {
    28         Class clazz = MyJunitTest.class;
    29         Method ms[] = clazz.getMethods();
    30         for(Method m:ms){
    31             MyTest myTest = m.getAnnotation(MyTest.class);
    32             if(myTest!=null){
    33                 //得到注解的属性
    34                 long timeLimit = myTest.time();
    35                 if(timeLimit>-1){
    36                     //有性能测试需求
    37                     long startTime = System.nanoTime();
    38                     m.invoke(clazz.newInstance(), null);
    39                     long useTime = System.nanoTime()-startTime;
    40                     if(useTime>timeLimit){
    41                         System.out.println(m.getName()+"执行效率没有测试通过");
    42                     }
    43                 }else{
    44                     //没有性能测试需求
    45                     m.invoke(clazz.newInstance(), null);
    46                 }
    47                 
    48             }
    49         }
    50     }
    51     //注解的基本反射
    52     private static void test1() throws IllegalAccessException,
    53             InvocationTargetException, InstantiationException {
    54         Class clazz = MyJunitTest.class;
    55         Method ms[] = clazz.getMethods();
    56         for(Method m:ms){
    57             boolean b = m.isAnnotationPresent(MyTest.class);
    58 //            System.out.println(m.getName()+"方法上有木有MyTest注解:"+b);
    59             if(b){
    60                 m.invoke(clazz.newInstance(), null);
    61             }
    62         }
    63     }
    64 
    65 }
    MyTestRunner

    1. 指定运行时生命周期才能进行测试

     2.指定在指定时间内执行完,才算是测试成功

    注解

    替换传统的XML配置文件。 

    比如:映射一个Servlet

    ------------------ 
    
    public class MyServlet extends HttpServlet{
    
    ... 
    
    }
    View Code

    web.xml

    <servlet>
    
     
    
    <servlet-name>MyServlet</servlet-name>
    
     
    
    <servlet-class>com.itheima.MyServlet</servlet-class>
    
     
    
    </servlet>
    
     
    
    <servlet-mapping>
    
     
    
    <servlet-name>MyServlet</servlet-name>
    
     
    
    <url-pattern>/servlet/MyServlet</url-pattern>
    
     
    
    </servlet-mapping>
    
     
    
    --------------------------------------------------------------
    
     
    View Code
    @WebServlet(urlPattern=”/servlet/MyServlet”)
    public class MyServlet extends HttpServlet{}

     Servlet3.0的新特征 

    JavaEE5.0:Servlet2.5

    JavaEE6.0:Servlet3.0

    1、前提:

    Tomcat7.X   JDK6.X

    2、Servlet3.0比Servlet2.5多了哪些功能

    1.不用配置xml文件的设置,用注解

    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebInitParam;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @WebServlet(urlPatterns="/servlet/ServletDemo1",initParams=@WebInitParam(name="encoding",value="ANNVAUE"))
    
    //注册配置的和web.xml配置的都会实例化一次
    //建议:要么用注解,要么用web.xml
    public class ServletDemo extends HttpServlet {
        public void init() throws ServletException {
            System.out.println("初始化了");
        }
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            System.out.println(this);
            System.out.println("ServletDemo1执行了");
            String value = getServletConfig().getInitParameter("encoding");
            System.out.println(value);
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    
    }
    
    ServletDemo1
    ServletDemo.java

    2.文件上传的改变

    2.1:上传形式不变:

          

    2.2:

    import java.io.IOException;
    import java.util.Collection;
    import java.util.Collections;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.MultipartConfig;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.Part;
    @WebServlet("/servlet/UploadServlet")
    @MultipartConfig //告知处理的是multipart/form-data类型的数据
    public class UploadServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    //        Collection<Part> parts = request.getParts();
    //        for(Part p:parts)
    //            System.out.println(p);
            
            //传统方式获取参数能用了
    //        String name = request.getParameter("name");
    //        System.out.println(name);
            
            //处理文件上传
            Part part = request.getPart("photo");
            //获取上传文件的文件名
            String headerValue = part.getHeader("Content-Disposition");//  form-data; name="photo"; filename="AOP.txt"
            int index = headerValue.indexOf("filename=");
            String filename = headerValue.substring(index+10, headerValue.length()-1);
            part.write(getServletContext().getRealPath("/files")+"/"+filename);
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    
    }
    
    UploadServlet
    UploadServlet.java

    3.web片段:

    注解的引入使得web.xml变成可选的了。但是,我们还是可以使用web.xml。容器会根据web.xml中的metadata- complete元素的值来决定使用web.xml还是使用注解。如果该元素的值是true,那么容器不处理注解,web.xml是所有信息的来源。如果 该元素不存在或者其值不为true,容器才会处理注解。

    Web框架的可插入性

    我们前面说过了Servlet3.0的改进之一就是使得我们能够将框架和库插入到web应用程序中。这种可插入性减少了配置,并且提高了web应用程序的模块化。Servlet3.0是通过web模块布署描述片段(简称web片段)来实现插入性的。
    一个web片段就是web.xml文件的一部分,被包含在框架特定的Jar包的META-INF目录中。Web片段使得该框架组件逻辑上就是web应用程序的一部分,不需要编辑web布署描述文件。
    Web 片段中使用的元素和布署文件中使用的元素基本相同,除了根元素不一样。Web片段的根元素是<web-fragment>,而且文件名必须叫 做web-fragment.xml。容器只会在放在WEB-INFlib目录下的Jar包中查找web-fragment.xml文件。如果这些 Jar包含有web-fragment.xml文件,容器就会装载需要的类来处理他们。
    在web.xml中,我们要求Servlet的name必须唯一。同样的,在web.xml和所有的web片段中,Servlet的name也必须唯一。
    下面就是一个web-fragment的例子:

    <web-fragment>
    <servlet>
    <servlet-name>ControllerServlet</servlet-name>
    <servlet-class>com.app.control.ControllerServlet</servlet-class>
    </servlet>
    <listener> <listener-class>com.listener.AppServletContextListener</listener-class>
    </listener>

    框架的Jar包是放在WEB-INFlib目录下的,但是Servlet3.0提供两种方法指定多个web片段之间的顺序:
       1. 绝对顺序
       2. 相对顺序
    我 们通过web.xml文件中的<absolute-ordering>元素来指定绝对顺序。这个元素有之元素name,name的值是各个 web片段的name元素的值。这样就指定了web片段的顺序。如果多个web片段有相同的名字,容器会忽略后出现的web片段。下面是一个指定绝对顺序 的例子:

     <web-app>
    <name>DemoApp</name>
    <absolute-ordering>
    <name>WebFragment1</name>
    <name>WebFragment2</name>
    </absolute-ordering>
     </web-app>

    相对顺序通过web-fragment.xml中的<ordering>元素来确定。Web片段的顺序 由<ordering>的子元素<before>,<after>和<others>来决定。当前的 web片段会放在所有的<before>元素中的片段之前。同样的,会放在所有的<after>元素中的片段之 后。<others>用来代替所有的其他片段。注意只有当web.xml中没有<absolute-ordering>时,容器 才会使用web片段中定义的相对顺序。
    下面是一个帮助理解相对顺序的例子:

    <web-fragment>
    <name>WebFragment1</name>
    <ordering><after>WebFragment2</after></ordering>
    </web-fragment>
    <web-fragment>
    <name>WebFragment2</name>
    </web-fragment>
    <web-fragment>
    <name>WebFragment3</name>
    <ordering><before><others/></before></ordering>
    </web-fragment>

    这些文件将会按照下面的顺序被处理:

       1. WebFragment3
       2. WebFragment2
       3. WebFragment1

    包含WebFragment3的Jar文件被最先处理,包含WebFragment2的文件被第二个处理,包含WebFragment1的文件被最后处理。
    如果既没有定义绝对顺序,也没有定义相对顺序,那么容器就认为所有的web片段间没有顺序上的依赖关系。

    4.同步和异步:

    同步:

    同步的思想是:所有的操作都做完,才返回给用户。这样用户在线等待的时间太长,给用户一种卡死了的感觉(就是系统迁移中,点击了迁移,界面就不动了,但是程序还在执行,卡死了的感觉)。这种情况下,用户不能关闭界面,如果关闭了,即迁移程序就中断了。

    异步:

    将用户请求放入消息队列,并反馈给用户,系统迁移程序已经启动,你可以关闭浏览器了。然后程序再慢慢地去写入数据库去。这就是异步。但是用户没有卡死的感觉,会告诉你,你的请求系统已经响应了。你可以关闭界面了。

    同步,是所有的操作都做完,才返回给用户结果。即写完数据库之后,在相应用户,用户体验不好。
    
    异步,不用等所有操作等做完,就相应用户请求。即先相应用户请求,然后慢慢去写数据库,用户体验较好。

    异步操作例子:

    为了避免短时间大量的数据库操作,就使用缓存机制,也就是消息队列。先将数据放入消息队列,然后再慢慢写入数据库。

    引入消息队列机制,虽然可以保证用户请求的快速响应,但是并没有使得我数据迁移的时间变短(即80万条数据写入mysql需要1个小时,用了redis之后,还是需要1个小时,只是保证用户的请求的快速响应。用户输入完http url请求之后,就可以把浏览器关闭了,干别的去了。如果不用redis,浏览器不能关闭)。

    同步就没有任何价值了吗?银行的转账功能。

     

     1 import java.io.IOException;
     2 import java.io.PrintWriter;
     3 
     4 import javax.servlet.AsyncContext;
     5 import javax.servlet.ServletException;
     6 import javax.servlet.annotation.WebServlet;
     7 import javax.servlet.http.HttpServlet;
     8 import javax.servlet.http.HttpServletRequest;
     9 import javax.servlet.http.HttpServletResponse;
    10 @WebServlet(urlPatterns="/RegistServlet",asyncSupported=true)
    11 public class RegistServlet extends HttpServlet {
    12 
    13     public void doGet(HttpServletRequest request, HttpServletResponse response)
    14             throws ServletException, IOException {
    15         response.setContentType("text/html;charset=UTF-8");
    16         PrintWriter out = response.getWriter();
    17         out.write("RegistServlet开始运行了<br/>");
    18         out.flush();
    19         try {
    20             Thread.sleep(2000);
    21         } catch (InterruptedException e) {
    22             e.printStackTrace();
    23         }
    24         out.write("注册成功了<br/>");
    25         out.flush();
    26         //发送激活邮件
    27         AsyncContext ac = request.startAsync();//开始异步
    28         new Thread(new SendMail(ac)).start();//3秒
    29         out.write("RegistServlet运行结束了<br/>");
    30         out.flush();
    31     }
    32 
    33     public void doPost(HttpServletRequest request, HttpServletResponse response)
    34             throws ServletException, IOException {
    35         doGet(request, response);
    36     }
    37 
    38 }
    39 class SendMail implements Runnable{
    40 
    41     private AsyncContext ac;
    42 
    43     public SendMail(AsyncContext ac) {
    44         this.ac= ac;
    45     }
    46 
    47     public void run() {
    48         try {
    49             Thread.sleep(3000);
    50         } catch (InterruptedException e) {
    51             e.printStackTrace();
    52         }
    53         //打印信息
    54         try {
    55             PrintWriter out = ac.getResponse().getWriter();
    56             out.write("邮件发送成功!");
    57             out.flush();
    58         } catch (IOException e) {
    59             e.printStackTrace();
    60         }
    61     }
    62     
    63 }
    RegistServlet.java
    合群是堕落的开始 优秀的开始是孤行
  • 相关阅读:
    模板
    CF1271E Common Number
    模板——长链剖分
    XJOI NOIP501/511训练22 ttt学字符串
    POJ 1151 Atlantis
    BZOJ 1014 [JSOI2008]火星人prefix
    Luogu P1856 [USACO5.5]矩形周长Picture
    CF716D Complete The Graph
    Luogu P2596 [ZJOI2006]书架
    HTML 学习之JavaScript作用域
  • 原文地址:https://www.cnblogs.com/biaogejiushibiao/p/9352238.html
Copyright © 2020-2023  润新知