day045 annotation & dynamic proxy

1 Junit test

Junit test unit is a test tool provided by a third party. You can use the main method to directly execute the specified method;

There are three comments in junit test unit:

1: @ Test @ means to Test this method

2: @ Before indicates that the method containing @ Before needs to be executed Before executing the tested method (the method containing @ Test)

3: @ After , indicates that the method containing @ After needs to be executed After executing the tested method (the method containing @ Test)

Use steps of junit:

1: Import JUnit Jar package (it has been built in eclipse and can be imported directly)

2: Directly add corresponding comments on the tested method;

Premise of use:

Requirements for tested methods:

1: Must be public permission

2: Must be a void return value

3: Must be a list of empty parameters

1 Notes

1.1 general

 what is Annotation: Annotation is a code level description. It is jdk1 A feature introduced in version 5 and later is at the same level as class, interface and enumeration

 comparative notes: notes are for developers to read, and notes provide corresponding information to the computer.

 function of annotation:

1. Compilation check: the compiler can realize basic compilation check by identifying comments in the code. For example: @ Override

2. Code analysis: analyze the code by identifying comments in the code, so as to replace xml.

3. Writing documents: help to generate the corresponding contents of the help documents by identifying comments in the code

1.2 notes provided by JDK

1. @Deprecated indicates that the modified method is outdated. Outdated methods are not recommended, but can still be used. (there will be one more line when using this modified method in the future)

 generally, the methods marked with outdated bits have different defects: 1. Security problems; 2 new API replacement

2. @Override  JDK5.0 represents the method of copying the parent class; jdk6.0 can also represent the method of implementing the interface

3. @SuppressWarnings means suppress warnings. If the modified class or method has a compilation warning, it will be ignored by the compiler (string value can be passed in it)

The values that can be transferred are:

Depredation, or slightly outdated

rawtypes, ignoring type safety

unused, ignore not used

unchecked, ignore security check

Null, ignore null pointer

All, ignore all

 @Deprecated

//#1 method expired
class Parent1_1{
    @Deprecated
    public void init(){
        
    }
}

 @ Override replication parent method

//#2.1 JDK5.0 replication parent method
class Parent1_2{
    public void init(){
        
    }
}
class Son1_2 extends Parent1_2{
    @Override
    public void init() {
    }
}

 @ Override implementation interface method

//#2.2 JDK6.0 implements the parent interface method
interface Parent1_3{
    public void init();
}
class Son1_3 implements Parent1_3{
    @Override
    public void init() {
        
    }
}

 @SupperssWarings

//#3 suppression warning
// Serial: implements the serial number interface, but there is no production serial number
@SuppressWarnings("serial")
class Parent1_4 implements java.io.Serializable{
    
    //Null: null pointer
    @SuppressWarnings("null")
    public void init(){
        
        //rawtypes: type safe, no generics used
        //unused: not used
        @SuppressWarnings({ "rawtypes", "unused" })
        List list = new ArrayList();
        
        
        String str = null;
        
        str.toString();
        
    }
    
}

1.3 user defined annotation: definition - basic syntax

Generally, it will be used when extracting tools or optimizing.

Keyword: @ interface

Write only properties:

Format of attribute:

public abstract data type: attribute name () default attribute value;

Supported data types:

Basic type, String, Class, annotation, enumeration, and one-dimensional array of the above types (Note: wrapper types of basic data types are not supported)

 define the keyword used for annotation: @ interface

1. Definition class: Class

2. Define interface: Interface

3. Definition enumeration: enum

// #1 definition notes
@interface MyAnno1{
    
}

 define annotations with attributes

//#2 define annotations with attributes
@interface MyAnno2{
    public String username() default "jack";
}

 attribute format: modifier  return value type  attribute name () [default default]

1. Modifier: the default value is public abstract, and can only be public abstract.

2. Return value type: basic type, String, Class, annotation, enumeration, and one-dimensional array of the above types

3. Attribute name: user defined

4. default: can be omitted

 complete case

//#3. Complete attribute annotation
@interface MyAnno3{
    int age() default 1;
    String password();
    Class clazz();
    MyAnno2 myAnno(); // annotation
    Color color(); // enumeration
    String[] arrs();
}
enum Color{
    BLUE,RED;
}

1.4 user defined annotation: use

 use format: @ annotation class name (attribute name = value, attribute name = value,...)

@MyAnno1
@MyAnno2(username="rose")
@MyAnno3(
        age=18 , 
        password="1234" ,
        clazz=String.class , 
        myAnno=@MyAnno2 , 
        color = Color.RED , 
        arrs = {"itcast","itheima"} 
)
public class TestAnno2 {

 notes on the use of annotations:

 annotations can have no attributes. If there are attributes, they need to be enclosed in parentheses. For example: @ MyAnno1 or @ MyAnno1()

 attribute format: attribute name = attribute value, and multiple attributes are separated by commas. For example: @ MyAnno2(username="rose")

 if the attribute name is value and there is only one attribute at present, value can be omitted.

 if multiple attributes are used, the name of k is value and cannot be omitted

 if the attribute type is array, set the content format as: {1,2,3}. For example: arrs = {"itcast","itheima"}

 if the attribute type is array, only one {} value can be omitted. For example: arrs = "itcast"

 annotations can only be used once on an object and cannot be reused.

(insert:

* customize a class for enumerating data types:

*  

*Keywords: enum

*Data type: it belongs to reference data type;

*Function: it is equivalent to defining a constant array. Each element in the array is a constant. The data type of the constant value is this enumeration type;

*Constant definition format: you can write constant names directly, and multiple constant names are separated by commas

*Constant name format: class name Constant name

give an example:

public enum Color {
    //Define constants  
    RED,GREEN;
}
public @interface MyAn2 {
    //Define attributes
    public abstract Color yanSe() default Color.GREEN;
}

)

1.5 user defined annotation: definition - meta annotation

Like reflection, annotations only exist at compile time by default (they exist in. java and will be compiled and erased when compiled into. class)

Meta annotation: an annotation used to modify an annotation. (annotations provided by JDK for modifying custom annotations)

JDK provides four meta annotations:

@retention is used to determine the life cycle of the modified custom annotation

RetentionPolicy.SOURCE the modified annotation can only exist in the source code, and the bytecode class does not exist. Purpose: provide for compiler.

RetentionPolicy. The annotations modified by class can only exist in the source code and bytecode, but not in the runtime memory. Purpose: JVM java virtual machine usage

RetentionPolicy.RUNTIME modified annotations exist in source code, bytecode, memory (runtime) (commonly used). Purpose: replace xml configuration

@Target is used to determine where the modified custom annotation is used

ElementType.TYPE decoration class and interface

ElementType.CONSTRUCTOR modifier construction

ElementType.METHOD modification method

ElementType.FIELD decorated field

@Documented whether this annotation is included when generating api documents using javaDoc (understand)

@Inherited if the parent class uses the modified annotation, whether the child class inherits. (understand)

 modify the annotation class, run the test instance, and the output result is: true.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno1{
    
}

give an example:

MyAn3.java

/*
 * Use meta annotations to make MyAn3 survive when the code is running
 */

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(value=RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAn3 {
    public abstract String abc() default "abc Default value for";
}

MyAn3Test.java

import java.lang.reflect.Method;

import org.junit.Test;

@SuppressWarnings("all")
public class MyAn3Test {
    @MyAn3
    @Test
    public void m1() throws Exception{
        //1: Parse m1 the abc attribute value of the MyAn3 annotation on the method header
        //1: Judge whether there is MyAn3 annotation on m1
        Class c1 = MyAn3Test.class;
        Method m = c1.getMethod("m1");
        boolean b = m.isAnnotationPresent(MyAn3.class);
        System.out.println(b);
        //2: Get an object of MyAn3 annotation type from the m object
        MyAn3 a3 = m.getAnnotation(MyAn3.class);
        //3: Call the property name () to get the property value
        String abc = a3.abc();
        System.out.println(abc);
    }
}

1.6 user defined annotation: parsing

 

 if you add annotations to classes and methods, and if you need to obtain the data set on the annotation, we must parse the annotation, and JDK provides Java lang.reflect. The annotatedelement interface allows annotations to be obtained at run time through reflection.

 common methods:

• boolean isAnnotationPresent(Class annotationClass) whether the current object has annotations

 t getannotation (class < T > annotationclass) gets the annotation specified on the current object

 Annotation[] getAnnotations() obtains all annotations of the current object and its inheritance from the parent class

 annotation [] getdeclaraedannotations() gets all annotations on the current object

 test

@MyAnno1
public class TestAnno2 {
    public static void main(String[] args) {
        boolean b = TestAnno2.class.isAnnotationPresent(MyAnno1.class);
        System.out.println(b);  //false
    }
}

After running the above program, we hope the output result is true, but it is actually false. There is @ MyAnno1 annotation on the testano2 class, but it cannot be obtained after running, because each custom annotation needs to be modified with the meta annotation provided by JDK before it can be really used.

1.7 simulation @ Test function exercise

MyTest.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyTest {

}

Demo.java

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Demo {
    @MyTest
    public void m1(){
        System.out.println("m1...");
    }
    public void m2(){
        System.out.println("m2...");
    }
    public void m3(){
        System.out.println("m3...");
    }
    @MyTest
    public void m4(){
        System.out.println("m4...");
    }
    
    //Write the main method to identify which methods M1, M2, m3 and M4 above have MyTest, which can be executed directly, otherwise it cannot be executed
    public static void main(String[] args) throws Exception{
        //1: Reflection acquisition m1,m2,m3,m4 method object
        Class c=Demo.class;
        Method[] ms = c.getMethods();
        //2: Iterate over all method objects and judge. If there is MyTest on the method, it can be executed directly, otherwise it cannot be executed
        for (Method m : ms) {
            boolean b = m.isAnnotationPresent(MyTest.class);
            if(b){
                m.invoke(c.newInstance());
            }
        }
    }
}

2 dynamic agent of JDK

The dynamic proxy of jdk requires that the target class must have an interface.

Agent process dynamic analysis

2.1 java.lang.reflect.Proxy

A tool class used to create dynamic proxy objects. In the future, users can directly face this tool class to obtain a dynamic proxy object, and face the dynamic proxy object to operate the method of Andy Lau object.

 

To create a dynamic proxy object:

JDK oriented Proxy tool class can directly call static methods to obtain a dynamic Proxy object.

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)  

Returns a proxy class instance of the specified interface that can assign method calls to the specified call handler.  

Parameter Description:

(1) : loader, which is the class loader of the target class.

(2) : interfaces are all interfaces implemented by the target class.

(3) : h, call handler, which is specially used to tell the generated dynamic proxy object how to handle the methods in the target class.

Return value Description:

The newProxyInstance method of Proxy returns a dynamic Proxy object. This dynamic Proxy object is created by the Proxy tool class. It is a brother object of the target class and needs to be received using the interface type of the target class.

           

Methods in InvocationHandler interface:

Object invoke(Object proxy, Method method, Object[] args)  

Process method calls on proxy instances and return results.  

Parameter Description:

1: Proxy # is the dynamic proxy object to be generated. It cannot be used here, otherwise the syntax will report an error.

2: Method represents the method object in the target class that the user wants to call.

3: args represents the actual parameters required for method execution.

Return value Description:

Invokehandler's invoke method. What is returned is the enhanced processing result. Generally, the result of the invoke execution of the method method method will be returned directly.

2.3 practice examples

YiRen.java

public interface YiRen {
    public void sing();
    public void dance();
}

LDH.java

public class LDH implements YiRen{
    public void sing(){
        System.out.println("Andy Lau singing practice...");
    }
    public void dance(){
        System.out.println("Andy Lau's space walk...");
    }
}

MyUtils.java

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyUtils {
    //Create an object of Andy Lau
    private static LDH l = new LDH();
    //Static method, direct manufacturing
    public static Object getDongTaiDaiLi(){
        //For JDK tool class, you can directly create a dynamic proxy object
        YiRen y=(YiRen)Proxy.newProxyInstance(l.getClass().getClassLoader(),l.getClass().getInterfaces(),new InvocationHandler(){   //y is created temporarily in memory, and l is a brother, which implements the same interface
            //The programmer is only responsible for writing the invoke method, which is called by the generated dynamic proxy object
            public Object invoke(Object proxy, Method method, Object[] args){
                //Here you can write the call processing flow
                System.out.println("Andy Lau began to implement "+method.getName()+" before,Processes to be implemented.........");
                try {
                    //Let Andy Lau's method be implemented
                    Object in = method.invoke(l, args);
                    //Post execution control method
                    System.out.println("Andy Lau's"+method.getName()+"After method execution..........");
                    return in;
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RuntimeException();
                } 
            }
        });
        //2: Returns the dynamic proxy object y
        return y;
    }
}

Test.java

/*
 * Fans
 */
public class Test {

    public static void main(String[] args) {
        //1> Get a broker object
        YiRen y = (YiRen) MyUtils.getDongTaiDaiLi();
        //2: Agent object oriented, calling specific methods
        y.sing();
        y.dance();
    }

}

Class 3 loader

 class loader: class loader is the object responsible for loading classes. Load the class file (hard disk) into memory to generate a class object.

All class loaders are Java Subclass of lang.classloader

 use class class.getClassLoader() gets the class loader that loads itself

 class loader loading mechanism: overall responsibility delegation mechanism

Overall responsibility: if class A wants to use class B (does not exist), class A loader C must be responsible for loading class B.

Delegation mechanism: if the class A loader wants to load resource B, it must ask the parent class whether to load it.

If loaded, it will be used directly.

If there is no mechanism, load it yourself.

 the overall responsibility delegation mechanism is adopted to ensure that a class file will be loaded only once to form a class object.

 attention:

If a class file is loaded by two class loaders, it will be two objects.

Tip com itheima. Hello , can't be forced to com itheima. Hello

             h.getClass() -->A                 h.getClass()  -->B

Custom class loading, you can load a class file multiple times.

practice:

import sun.security.ec.SunEC;

/*
 * Class loader exercise:
 * 
 *  
 */
public class Test {

    public static void main(String[] args) {
        //1: Get boot class loader
        ClassLoader l1 = String.class.getClassLoader();
        System.out.println(l1);
        //2: Get extension class loader
        ClassLoader l2 = SunEC.class.getClassLoader();  //SunEC is a class at the end of ext
        System.out.println(l2);
        //3: Get application class loader
        ClassLoader l3 = Test.class.getClassLoader();
        System.out.println(l3);
        System.out.println("---------------------");
        ClassLoader l4 = l3.getParent();
        System.out.println(l4);
        System.out.println(l4.getParent());
    }

}

Output result:

null

sun.misc.Launcher$ExtClassLoader@1b6d3586

sun.misc.Launcher$AppClassLoader@6d06d69c

---------------------

sun.misc.Launcher$ExtClassLoader@1b6d3586

null

 

be careful:

1: Boot class loader (root class loader): it is written in c and c + +, so it can't be obtained in Java. java. He is responsible for loading the things under Lang package.

2: Extension class loader: the java package with ext suffix is loaded by the extension class loader.

3: Application class loader: only third-party jar packages and classes written by programmers are loaded.

4: Parent class loader: Pronunciation: parent class loader, emphasizing the calling relationship rather than inheritance relationship.

5: When using, the application class loader is often used, and the acquisition method should be remembered. Class class.getClassLoader()

6: When typing the above code, it may occur that eclipse does not guide the package to SunEC. This is because by default, eclipse does not have permission to use the packages of Sun company and cannot use the packages starting with sun. The operations required at this time are:

(1) Right click the project and select Properties.

(2) Find Java Build Path

(3) Find Libraries

(4) Find JRE System Library, expand, find Access rules:, edit, add,

(5) Select Accessible in the Resolution and add a "sun / * *" in the Rule Pattern.

4 comprehensive exercise: dynamic agent solves a parameter garbled problem

MyEncodingFilter.java

package 

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Use dynamic agent to complete the problem of Chinese coding filtering
 */
public class MyEncodingFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        /*
         * Idea:
         *      If it is a get request, create a proxy object dynamically and release the proxy object,
         *      If it is a post request, set the code directly and release it
         */
        //1: Convert to sub interface type
        final HttpServletRequest r = (HttpServletRequest)request;
        HttpServletResponse res = (HttpServletResponse)response;
        //2: Resolve response garbled code
        res.setContentType("text/html;charset=utf-8");
        //3: Get request method
        String m = r.getMethod();
        if("get".equalsIgnoreCase(m)){
            //4: Create proxy object and release
            HttpServletRequest req=(HttpServletRequest)Proxy.newProxyInstance(r.getClass().getClassLoader(),r.getClass().getInterfaces(),new InvocationHandler() {
                boolean flag = true;
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    //Write the processing flow here
                    //Get the method name according to the method object
                    String name = method.getName();
                    //Let the method object execute
                    Object o=method.invoke(r, args);
                    if(name.equals("getParameter")){
                        //Note that the method at this time is getParameter method
                        String s =(String)o;
                        if(s==null){
                            return null;
                        }
                        s=new String(s.getBytes("iso8859-1"),"utf-8");
                        return s;
                    }else if(name.equals("getParameterValues")){//Note: each time you call getParameterValues, you will get a new array, so you can't use enhanced for (see the debug mode diagram below for details)
                        //Note the method at this time is getParameterValues
                        String[] s =(String[])o;
                        if(s!=null){
                            for (int i=0;i<s.length;i++) {
                                s[i] = new String(s[i].getBytes("iso8859-1"),"utf-8");
                            }
                        }
                        return s;
                    }else if(name.equals("getParameterMap")){//Note: each time you call getParameterMap, you will get the same map, so you can use enhanced for. Because it is the same map, you can only turn it once. You need to define a boolean variable flag to control it. (see the debug mode diagram below for details)
                        //Note the method at this time is getParameterValues
                        Map<String,String[]> map =(Map<String,String[]>)o;
                        if(flag){
                            Set<String> set = map.keySet();
                            for (String key : set) {
                                String[] s = map.get(key);
                                for (int i=0;i<s.length;i++) {
                                    s[i] = new String(s[i].getBytes("iso8859-1"),"utf-8");
                                }
                            }
                            flag=false;
                        }
                        return map;
                    }
                    //Other methods, directly return the original value
                    return o;
                }
            });
            //5: Release req object
            chain.doFilter(req, res);
        }else{
            //Set the code, And release
            r.setCharacterEncoding("utf-8");
            chain.doFilter(r, res);
        }
    }
    public void destroy() {
    }
    public void init(FilterConfig fConfig) throws ServletException {
    }

}

Hello.java

package 

import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * servlet to validate parameters
 */
public class Hello extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String n = request.getParameter("name");
        String[] values2 = request.getParameterValues("hobby");
        String[] values = request.getParameterValues("hobby");
        Map<String, String[]> map2 = request.getParameterMap();
        Map<String, String[]> map = request.getParameterMap();
        System.out.println("One parameter:"+n);
        System.out.println("An array:"+Arrays.toString(values));
        Set<String> set = map.keySet();
        for (String key : set) {
            System.out.println("map:"+key+"====>"+Arrays.toString(map.get(key)));
        }
        response.getWriter().println("How do you do");
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

Test:

Browser input:

localhost:/day45/Hello?name = Zhang San & Hobby = smoking & Hobby = drinking

 

Keywords: Java

Added by xxATOMxx on Tue, 08 Feb 2022 03:52:18 +0200