[Java study notes (121)] the use of scripting language, a detailed introduction of annotations

This article is published by the official account [Developing Pigeon]! Welcome to follow! ! !


Old Rules-Sister Town House:

One. script

(I. Overview

       Scripting language is a language that avoids the usual editing/compiling/linking/running cycle by interpreting program text at runtime. The advantage of scripting language is that it can be changed quickly and the running program can be modified. However, the scripting language lacks Features that benefit writing complex applications, so people usually combine the advantages of scripting languages ​​with traditional languages. The scripting API allows you to achieve this on the Java platform and call scripts directly in the Java program.

(Two) script engine

1 Overview

       The script engine is a class library that can execute scripts written in a specific language. When the virtual machine starts, it will find available script engines. In order to enumerate these engines, you need to construct a ScriptEngineManager and call the getEngineFactories method. Each engine factory asks the engine name, MIME type and file extension that they support, and obtains the engine through these three parameters.

ScriptEngine engine = manager.getEngineByName(“nashorn”);

2. Script calculation and binding

       With the engine, you can call the script directly:

Object result = engine.eval(scriptString);
engine eval(“n = 1);

       Multiple scripts can be called on an engine. If a script defines variables, functions or classes, most engines will retain these definitions.

       You can directly add new variable bindings to the engine. The bindings consist of names and their associated java objects:

engine.put(“k”, 1);

       The script code reads the definition of k from the binding in the "engine scope", and can also be added to the global scope. Any binding added to the ScriptEngineManager is visible to all engines.

3. Redirect input and output

       The standard input and output of the script can be redirected by calling the setReader and setWriter methods of the script context.

var writer = new StringWriter();
engine.getContext().setWriter(new PrintWriter(writer, true));

       Then the output generated by the script will be sent to the writer.

4. Calling script functions

       For many script engines, functions of the scripting language can be called without calculating the actual script code. The script engine that provides this function implements the Invocable interface. To call a function, you need to use the function name to call the invokeFunction method, and the function parameters are followed by the function name.

engine.eval(“function greet(how, whom) {
    
    return how +,+ whom });
result = ((Invocable) engine).invokeFunction(“greet”, “hello”, “world”);

       Further, the script engine can be allowed to implement a Java interface, and then the script function can be called with the syntax of Java method calling, and a function needs to be provided for each method in the Java interface. Such as the following interface:

public interface Greeter{
    
    
	String welcome(String whom);
}

       Then, when calling, first obtain the implementation class of the given interface, and the implementation uses the function in the script engine to implement the method in the interface.

engine.eval(“function welcome(whom) {
    
    return “hello” + whom});
Greeter g = ((Invocable ) engine).getInterface(Greeter.class);
result = g.welcome(“world”);

5. Compile the script

       Some script engines compile the script code into an intermediate format for execution efficiency considerations. These engines implement the Compilable interface. Once the script is compiled, it can be executed directly. Of course, only when a script needs to be executed repeatedly. Will compile the script.


two. annotation

(I. Overview

       Annotations are tags inserted into the source code that can be processed by other tools. These tools can operate at the source code level, or can process class files in which the compiler has placed annotations. Annotations do not change the way the program is compiled. The Java compiler will generate the same virtual machine instructions for the code containing and not containing annotations.

(2) Purpose of annotations

       Automatic generation of auxiliary files, such as deployment descriptors or bean information classes;
       automatic generation of codes for testing, logs, transaction semantics, etc.;


(3) The use of annotations

In Java, the annotation is used as a modifier. It is placed before the annotation item, there is no semicolon in the middle, and the @ symbol is added before the name of each annotation, as shown below:

public class MyClass{
    
    
	@Test
	public void checkRandom();
}

       The @Test annotation does nothing by itself. It needs tool support. For example, when testing a class, the Junit4 test tool may call all methods identified as @Test.

       Annotations can also be defined as containing elements, such as:

@Test(timeout=10000)

       These elements can be processed by tools that read these annotations. In addition to methods, classes, members, and local variables can also be annotated. These annotations can exist in any place where modifiers like public can be placed. Each annotation needs to be defined by an annotation interface, and the methods in these interfaces correspond to the elements in the annotation, as shown below:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test
{
    
    
	long timeout() default 0L;
}

       The @interface declaration creates a real Java interface, and tools that process annotations will accept objects that implement the annotation interface. Such tools can call the timeout method to obtain the timeout element of a specific Test annotation.

       @Target annotation and @Retention are meta-annotations. They annotate the Test annotation, marking the Test annotation as an annotation that can only be applied to methods, and when the class file is loaded on the virtual machine, it can still be retained. Will be discussed later.

       An annotation object is defined, these annotations will only exist in the source file, the compiler will place them in the class file, and the virtual machine will load these files. We need to use a tool that can analyze annotations to accept these annotation objects. This tool class will call a processing method that will enumerate the annotation objects of all methods. If there is a corresponding annotation object, perform the object Processing, annotations really play a role.


(4) The syntax of annotations

       All annotation interfaces are implicitly extended from the java.lang.annotation.Annotaion interface, and there is no need to provide an implementation class for the annotation interface. If the value of an element in the annotation is not specified, the declared default value is used. The default value is not stored with the annotation, they are dynamically calculated.

       There are two special annotations to simplify annotations, one is mark annotations, there are no elements in the annotations or all elements use default values, as shown below:

@BugReport

       The other is a single-value annotation. If an element has a special name value and no other elements are specified, you can ignore the element name of this value and write the value directly:

@ActionLiener(“yellow”)

       An item can have multiple annotations, and if the author of the annotation declares that the annotation is repeatable, the same annotation can be reused. An annotation element can be another annotation, so annotations can be nested.

(5) The position of the annotation

       Annotations can appear in many places. These places are divided into two categories, one is declaration annotations, and the other is type usage declaration annotations. Declaration comments are placed before other modifiers, and type usage comments are placed after other modifiers.


three. Standard annotation

(I. Overview

       Java SE defines a large number of annotation interfaces, four of which are meta-annotations, used to describe the behavior attributes of the annotation interface, and the other three are rule interfaces, used to annotate items in the code.

(Two) annotations used for compilation

1. @Deprecated

       Mark the item as obsolete and the annotation will persist until runtime.


2. @SuppressWarnings

       Tell the compiler to prevent certain types of warning messages.

3. @Override

       Applied to the method, check whether this annotated method actually covers a method from the superclass.

4. @Generated

       The purpose is to be used by code generation tools, and any generated source code can be annotated to distinguish it from the code provided by the developer. Each annotation must contain a unique identifier that represents the code generator.

(3) Notes for managing resources

1. @PostConstruct and @PreDestroy

       In environments that control the life cycle of objects, such as web containers, methods marked with these annotations should be called immediately after the object is constructed or before the object is removed.

2. @Resource

       Used for resource injection, such as configuration file injection

(4) Meta-annotation

1. @Target

       Apply to annotations to limit which items the annotation can be applied to, such as methods, classes...

@Target({
    
    ElementType.TYPE, ElementType.METHOD})

       An annotation with no @Target restriction can be applied to any item.


2. @Retention

       Used to specify how long a note should be retained, the default is RetentionPolicy.CLSS:

       SOURCE: The annotations not included in the class file will neither enter the class file

       CLASS: The annotations contained in the class file, but the virtual machine does not need to load them

       RUNTIME: the annotations contained in the class file, and loaded by the virtual machine, they can be obtained through the reflection API

3. @Documented

       Provides hints for archiving tools like Javadoc for file archiving.

4. @Inherited

       It can only be used for class annotations. If a class has inheritance annotations, all its subclasses automatically have the same annotations. This annotation is especially suitable for markup interfaces such as Serializable.


four. Source-level annotation processing

(I. Overview

       Another use of annotations is to automatically process source code to generate more source code, configuration files, scripts, or anything else we want to generate.

(2) Annotation processor

       Annotation processing has been integrated into the Java compiler. The compiler will locate the annotations in the source file. Each annotation processor will execute in turn and get the annotations it is interested in. If a certain annotation processor creates a new one Source files, the above process will be repeated. If no new source files are generated in a certain processing cycle, then all source files will be compiled.

       Annotation processors usually implement the Processor interface by extending the AbstractProcessor class. The processor can declare specific annotation types, as shown below:

@SupportedAnnotationTypes(“com.horstmann.annotations.ToString”)
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class ToStringAnnotationProcessor extends AbstractProcessor{
    
    }

Fives. Bytecode engineering

(I. Overview

       Processing annotations are processed at the runtime or source code level, and can also be processed at the bytecode level. Unless the annotations are deleted at the source code level, they will always exist in the class file.

(2) Process

  1. Load the bytecode in the class file
  2. Locate all methods
  3. For each method, check whether it has a certain annotation
  4. If so, add the bytecode of some instructions to the method

Guess you like

Origin blog.csdn.net/Mrwxxxx/article/details/113666516