Hello, everyone, I am the public number: [Java xiaojie want to fuel], recently in the project, found a lot of places are used to custom annotations, according to the custom annotations, and then to do some personalized operations, very convenient, today to share with you
- Don’t say a word. Just drive
Notes overview
First, let’s declare an annotation
// Where can annotations be used
@Target({ElementType.TYPE})
// The annotation's life cycle
@Retention(RetentionPolicy.RUNTIME)
// indicates that by default, comments with type will be logged by Javadoc * and similar tools
@Documented
// Can inherit superclass annotations
@Inherited
// bean
@Component
public @interface DIYClassAnnotation {
DIYEnum diyEnum(a);
// The default age is 24
int age(a) default 24;
}
Copy the code
Notice that this annotation that we declare, he himself carries a lot of meta-annotations, so let’s interpret it accordingly, and the corresponding desirable values are as follows
- @Target: refers to where this annotation can be marked, is the field? Or class? Or method?
- TYPE: class, interface (including annotation TYPE), or enumeration declaration
- FIELD: FIELD declaration (including enumeration constants)
- METHOD: indicates the METHOD declaration
- PARAMETER: formal PARAMETER declaration
- CONSTRUCTOR: CONSTRUCTOR declaration
- LOCAL_VARIABLE: local variable declaration
- ANNOTATION_TYPE: Annotation type declaration
- PACKAGE: PACKAGE declaration
- TYPE_PARAMETER: type parameter declaration
- TYPE_USE: indicates the usage type
- @Retention: refers to the life cycle of the annotation, at which stage it exists
- SOURCE: Comments will be discarded by the compiler
- CLASS: Comments are recorded in CLASS files by the compiler, but need not be retained by the VM at run time. This is the default behavior.
- RUNTIME: Comments are recorded by the compiler in class files and held by the VM at RUNTIME * so they can be read reflectively
- Documented: Indicates that by default, annotations with types will be Documented by Javadoc * and similar tools
- @Inherited: Inherited annotations can be Inherited
- The values inside can only be annotated with the basic types Boolean, int, double, float, long, byte, short, char, String, Enum, Class, and a few other annotations
When we usually write notes. Use the properties and values highlighted above
We practice
- In fact, with this custom annotation, a thousand words are one sentence
- Start by declaring a custom annotation
- Take out this annotation through reflection and so on, and then do some custom operations based on the values set in the annotation
- This article will demonstrate the use of three types of custom annotations, which are the only types of common development (I’ve touched on them)
Custom class annotations
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Component
public @interface DIYClassAnnotation {
// Custom enumerated types
DIYEnum diyEnum(a);
// The default age is 24
int age(a) default 24;
}
Copy the code
Take a look at this enumerated type
public enum DIYEnum {
xiaoJie("Xiao jie"."Code"),
TEACHER("Teacher"."Teaching"),
CHEF("Chef"."Cook");
private String name;
private String worker;
DIYEnum(String name,String worker) {
this.name = name;
this.worker = worker;
}
public String getWorker(a) {
return worker;
}
public void setWorker(String worker) {
this.worker = worker;
}
public String getName(a) {
return name;
}
public void setName(String name) {
this.name = name; }}Copy the code
Custom field annotations
// Where is the annotation to the attribute
@Target({ElementType.FIELD})
// The annotation's life cycle
@Retention(RetentionPolicy.RUNTIME)
// indicates that by default, comments with type will be logged by Javadoc * and similar tools
@Documented
// Can inherit superclass annotations
@Inherited
// bean
@Component
public @interface DIYFieldAnnotation {
/ / gender
String sex(a);
}
Copy the code
3. Custom method annotations
// Where is the annotation to the method
@Target({ElementType.METHOD})
// The annotation's life cycle
@Retention(RetentionPolicy.RUNTIME)
// indicates that by default, comments with type will be logged by Javadoc * and similar tools
@Documented
// Can inherit superclass annotations
@Inherited
// bean
@Component
public @interface DIYMethodAnnotation {
// Whether to check
int verification(a);
// Interface name
String interfaceName(a);
}
Copy the code
- In fact, we noticed that it felt like everyone was very different. Yes, it was just that the target scope was different
Now that we’ve defined our custom annotations, it’s time to actually use them
- Define an abstract parent class Person
// Abstract superclass
public abstract class Person {
public abstract void hobby(a);
}
Copy the code
- Define Student subclasses
@DIYClassAnnotation(diyEnum = DIYEnum.xiaoJie,age=23 )
public class Student extends Person {
@diyfieldannotation (sex = "male ")
private String sex;
@Override
public void hobby(a) { System.out.println(DIYEnum.xiaoJie.getWorker()); }}Copy the code
- Define a Teacher subclass
@DIYClassAnnotation(diyEnum = DIYEnum.TEACHER,age=46 )
public class Teacher extends Person {
@diyfieldannotation (sex = "female ")
private String sex;
@Override
public void hobby(a) { System.out.println(DIYEnum.TEACHER.getWorker()); }}Copy the code
- Define the Chef Chef subclass
@DIYClassAnnotation(diyEnum = DIYEnum.CHEF,age=50 )
public class Chef extends Person {
@diyfieldannotation (sex = "male ")
private String sex;
@Override
public void hobby(a) { System.out.println(DIYEnum.CHEF.getWorker()); }}Copy the code
One more annotation utility class
public class DIYAnnotationUtils {
public static Person getPerson(Person ... persons){
for (Person person:persons) {
// Determine if the class has this annotation
if (person.getClass().isAnnotationPresent(DIYClassAnnotation.class)){
// Get this custom annotation
DIYClassAnnotation workerAnnotation = person.getClass().getAnnotation(DIYClassAnnotation.class);
// Determine if the value of the custom annotation is what we want
if (DIYEnum.xiaoJie.getName().equals(workerAnnotation.diyEnum().getName())){
// Reflection gets the properties of this object
Field[] fields = person.getClass().getDeclaredFields();
for (Field field:fields) {
// If the field has this annotation
if (field.isAnnotationPresent(DIYFieldAnnotation.class)){
// Print out the value of the annotation on the propertyDIYFieldAnnotation annotation = field.getAnnotation(DIYFieldAnnotation.class); System.out.println(annotation.sex()); }}returnperson; }}}return null; }}Copy the code
The main one is this utility class (using reflection), which determines whether the object passed in meets our requirements (annotation name is not small Jay), if so, annotation annotation on the property of the annotation out
- Let’s call it from our visual class
public class Test {
public static void main(String[] args) {
Student student =new Student();
Chef chef = new Chef() ;
Teacher teacher = new Teacher();
Person person = DIYAnnotationUtils.getPerson(student, chef, teacher);
if(person ! =null){ person.hobby(); }}}Copy the code
The output is
Men play codeCopy the code
- Let’s demonstrate how to use annotations in methods. The most common combination is custom annotations plus AOP
Now let’s look at controller
@RestController
public class Controller {
// This method requires validation
@diymethodannotation (verification = 1,interfaceName = "student hobby interface ")
@RequestMapping("/verification")
public String verificationMethod(String id){
new Student().hobby();
return "Check";
}
// This method does not require validation
@diymethodannotation (verification = 0,interfaceName = "teacher hobby interface ")
@RequestMapping("/noVerification")
public String noVerificationMethod(String id){
new Teacher().hobby();
return "Non-check";
}
// This method has no annotations
@RequestMapping("/noAnnotation")
public String noAnnotationMethod(String id){
new Chef().hobby();
return "No notes."; }}Copy the code
This article focuses on annotations. This section class has many refinements but is outside the scope of this article
@Component
@Aspect
public class LogAspect {
// The position of the annotation
@Pointcut("@annotation(com.example.demo.annotation.DIYMethodAnnotation)")
public void diyPointCut(a){};
@Around("diyPointCut()")
public Object diyAround(ProceedingJoinPoint joinPoint){
// Get information about the enhanced method
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
// Get the method
Method method = signature.getMethod();
// Get the annotation above this method
DIYMethodAnnotation diyMethodAnnotation = method.getAnnotation(DIYMethodAnnotation.class);
// Perform custom operations based on attributes defined by annotations
if (diyMethodAnnotation.verification() == 1){
System.out.println("The current check is:"+diyMethodAnnotation.interfaceName());
System.out.println("Method name is:"+method.getName());
System.out.println("The transfer parameter is:"+JSON.toJSONString(joinPoint.getArgs()));
}
System.out.println("Aop interceptor verification:"+diyMethodAnnotation.verification() );
try {
return joinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
return null; }}}Copy the code
We run the project through two annotated interfaces
- Interface to be verified
http://localhost:8081/verification? id=1VerificationMethod (); verificationMethod ();"1"[aop interceptor verification:1A codeCopy the code
- Interfaces that do not require verification
http://localhost:8081/noVerification?id=1 aop interceptors in verification: 0 to cookCopy the code
- An interface without annotations
http://localhost:8081/noAnnotation? id=1Cook a mealCopy the code
One conclusion can be drawn from the output,
- An interface without annotations will not go to AOP, because we AOP configure only annotated interfaces for AOP validation.
- If there are annotations on the interface, there are two cases (which we set ourselves)
- verification 0This annotation does not perform any special operations
- Output “currently validates yes, the method name is, and the pass parameter is
- This annotation takes special action when verification 1 occurs
- verification 0This annotation does not perform any special operations
In general, if we have special requirements for a class/field/method in daily development, we can use a custom annotation, get the annotation through reflection, and perform our custom operations based on the custom values in the annotation
Good article recommendation
- How is the network connected from the four – layer model
- I want to talk to you about operating system memory management
- I’m confused by the various locks in mysql
- Five thousand words, yes, we do have an HTTP.
- The interviewer of JINGdong asked me: “Talk about MySql affairs,MVCC?”
The last
Here’s another quote that’s been trending all over the Internet and touched me a lot
- God helps those who help themselves
Welcome to pay attention to, I am [Java xiaojie to refueling], what you want to say want to see the welcome comment section, we will see you next time.