1. What is annotation?
Annotation is a kind of flag. Using annotation alone is equivalent to adding a decoration to the class, method, parameters and package. There is no function, just a flag. Then this flag can be added with some parameters defined by itself.
Just like below, create an annotation of @interface, and then you can use this annotation, which is added to the method we need to decorate, but there is no function.
public @interface AuthorityVerify { String value() default ""; }
2. Talk about the comments that come with JAVA
1. Definition
When talking about Java annotations, we have to say that @interface is the same as Class (Class), enums, interfaces, etc., used to set types. For example, the code below is an annotation class:
/** * Custom permission verification interface * * @author Mr. Yi * @date January 23, 2024 18:57:15 */ @Target({, }) @Retention() public @interface AuthorityVerify { String value() default ""; }
Remark:
- Modifier
- The access modifier must be public, and the default is pubic if not written;
- Keywords
- The keyword is @interface;
- Annotation name
- The annotation name is the name of the custom annotation. For example, the XinLinLog above is the annotation name.
- Annotation type element
- Annotation type element is the content of the annotation, and flags parameters as needed, such as the value of the annotation above;
2. Meta Note
Speaking of annotations, we have to talk about meta annotations. Meta annotations are used on the annotations and are used to describe the scope of use of the annotations. Next, let’s talk about the functions of the four major meta annotations @Target, @Retention, @Document ed, and @Inherited.
@Target
Used to describe the scope of use of annotations, where the annotations can be used
Target type | describe |
---|---|
Applied to classes, interfaces (including annotation types), enumerations | |
Applied to properties (including constants in enumerations) | |
Apply to methods | |
Formal parameters applied to methods | |
Applied to constructors | |
ElementType.LOCAL_VARIABLE | Applied to local variables |
ElementType.ANNOTATION_TYPE | Applied to annotation type |
Apply to packages |
Note: For example, @Target(), the annotation of the flag is used on the method, but if we use this annotation flag on the class, we will report an error.
@Retention
Indicates the life cycle of this annotation
Life cycle type | describe |
---|---|
Discarded during compilation and not included in class files | |
JVM is discarded when loading, included in class files, default value | |
Loaded by the JVM, included in the class file, can be retrieved at runtime |
@Documented
Indicates that the elements marked with this annotation can be documented by Javadoc or similar tools
@Inherited
is a tag annotation, @Inherited explains that a certain annotated type is inherited.
If an annotation type using @Inherited modification is used for a class, the annotation will be used for a subclass of the class.
3. What scenarios can annotations be used for?
Generally, we can implement some duplicate logic through annotations, just like an encapsulated method, which can be used in some permission verification, field verification, field attribute injection, log saving, and cache.
3. Combined with Spring AOP section to achieve functions
The definition of the annotation summarized above, but creating such annotation is just a sign, decorating classes, methods, and attributes, and has no functions. To implement the function, we need to obtain the annotation mark through interceptors and AOP sections, and then implement our functions.
1. What is AOP?
The full name is Aspect Oriented Programming, which is famous when translated."System-oriented programming", it is a supplement and improvement for object-oriented.
Scene:
Data source switching, transaction management, permission control, log printing, etc.
Features:
- ① It is less intrusive and can add new logic to the business without changing the original logic.
- ② It is convenient to implement, and can be achieved with a few annotations, making the system easier to expand.
- ③ Better reuse code, such as transaction log printing, simple logic is suitable for all situations.
2. The meaning of the annotation
annotation | describe |
---|---|
@Aspect | section. Represents an object that cuts across the business. It contains Pointcut and Advice. |
@Pointcut | Point of entry. It indicates the location you need to enter, such as some classes or some methods, that is, to determine a range first. |
@Before | Advice (notification) is executed before the point-cutting method body is executed. |
@Around | Advice (notification) is a kind of execution surrounding the entry point, that is, wrapping the entry point into execution. |
@After | A type of Advice, executed after the normal operation of the entry point is completed. |
@AfterReturning | Advice (notification) is executed after the normal operation of the entry point is completed, and exceptions are not executed. |
@AfterThrowing | A type of Advice, executed when the entry point is running exception. |
- The normal execution order is: @Around ->@Before->Main method body ->@Around()->@After->@AfterReturning
- The exception execution order is (before Around()): @Around -> @After -> @AfterThrowing
- The exception execution order is (after Around()): @Around ->@Before->Main method body ->@Around()->@After->@AfterThrowing
Extension: Pointcut point-cut syntax
/** * 1. Use within expression to match * The following example shows a method that matches all classes under the package */ @Pointcut("within(..*)") public void pointcutWithin(){ } /** * 2. This matches the method specified by the target, here is the HelloController method */ @Pointcut("this()") public void pointcutThis(){ } /** * 3. Target matches the target object that implements the UserInfoService interface */ @Pointcut("target()") public void pointcutTarge(){ } /** * 4. The bean matches all the methods in beans ending with Service. * Note: When using automatic injection, the default implementation of the class's id with lowercase bean's first letter is implemented. */ @Pointcut("bean(*ServiceImpl)") public void pointcutBean(){ } /** * 5. The method of matching the first entry parameter of args is String type */ @Pointcut("args(String, ..)") public void pointcutArgs(){ } /** * 6. @annotation matching is a method of type @Controller */ @Pointcut("@annotation()") public void pointcutAnnocation(){ } /** * 7. @within matches the method under @Controller annotation, requiring the @Controller level of the annotation to be @Retention() */ @Pointcut("@within()") public void pointcutWithinAnno(){ } /** * 8、@targetThe matching is@ControllerThe following method of class,Requested annotation@ControllerLevel is@Retention() */ @Pointcut("@target()") public void pointcutTargetAnno(){ } /** * 9. Methods for @args matching annotation marked as @Sevice in the parameter */ @Pointcut("@args()") public void pointcutArgsAnno(){ } /** * 10. Use excution expressions * execution( * modifier-pattern? // Used to match public, private and other access modifiers * ret-type-pattern // Used to match the return value type, cannot be omitted * declare-type-pattern? // Used to match package types * name-pattern(param-pattern) // Used to match methods in classes, cannot be omitted * throws-pattern? //Methods used to match throw exceptions * ) * * The following expression is interpreted as: the modifier starting with hello in the class is arbitrary method of the public return type */ @Pointcut(value = "execution(public * *(..))") public void pointCut() { }
Note: The above matching types support or (||) and (&&) non-(!) operations.
3. Small Demo
①Introduce dependency packages
<!--springsectionaoprely--> <dependency> <groupId></groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
②Create a section to implement the function (here we take permission verification as an example)
ⅠCreate one of our facets
/** * Permission verification Face-section implementation * * @author: Moxi * @create: 2020-03-06-19:05 */ @Aspect @Component @Slf4j public class AuthorityVerifyAspect { }
@Aspect:section. Represents an object that cuts across the business. It contains Pointcut and Advice.
Ⅱ Create an annotation in the facet class to scan the above
@Pointcut(value = "@annotation(authorityVerify)") public void pointcut(AuthorityVerify authorityVerify) { }
@Pointcut:Point of entry. It indicates the location you need to enter, such as some classes or some methods, that is, to determine a range first.
Ⅲ Creating a notification method
@Around(value = "pointcut(authorityVerify)") public Object doAround(ProceedingJoinPoint joinPoint, AuthorityVerify authorityVerify) throws Throwable { ServletRequestAttributes attribute = (ServletRequestAttributes) (); HttpServletRequest request = (); //Get request path String url = (); // parse the requester's ID and username String adminUid = (SysConf.ADMIN_UID).toString(); // The path that the administrator can access String visitUrlStr = (RedisConf.ADMIN_VISIT_MENU + + adminUid); LinkedTreeMap<String, String> visitMap = new LinkedTreeMap<>(); if ((visitUrlStr)) { // Get it from Redis visitMap = (LinkedTreeMap<String, String>) (visitUrlStr, ); } else { // Query the database to obtain Admin admin = (adminUid); String roleUid = (); Role role = (roleUid); String caetgoryMenuUids = (); String[] uids = ("[", "").replace("]", "").replace("\"", "").split(","); List<String> categoryMenuUids = new ArrayList<>((uids)); // Here you only need to query the access button QueryWrapper<CategoryMenu> queryWrapper = new QueryWrapper<>(); (, categoryMenuUids); (SQLConf.MENU_TYPE, ); (, ); List<CategoryMenu> buttonList = (queryWrapper); for (CategoryMenu item : buttonList) { if ((())) { ((), ()); } } //Storage access URLs into Redis (RedisConf.ADMIN_VISIT_MENU + SysConf.REDIS_SEGMENTATION + adminUid, (visitMap), 1, ); } // Determine whether the role can access the interface if ((url) != null) { ("User has operation permissions,The path to access: {},Permission interface owned:{}", url, (url)); //Execute business return (); } else { ("The user does not have operation permissions,The path to access: {}", url); return (ECode.NO_OPERATION_AUTHORITY, MessageConf.RESTAPI_NO_PRIVILEGE); } }
@Around:Advice (notification) is a kind of execution surrounding the entry point, that is, wrapping the entry point into execution.
Summarize
The above is personal experience. I hope you can give you a reference and I hope you can support me more.