This is the 18th day of my participation in the August Genwen Challenge.More challenges in August

preface

Usually in the use of springBoot, often use @service, @compent and other annotations, simplifying our development process, improve the development efficiency. So how do you write a note yourself? Here is an introduction.

Write a note

There are two main parts to creating an annotation, one is to create an annotation class, the other is to create a facet class.

Creating an annotation class

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnn {
    String value(a) default "d";
}
Copy the code

The keyword for creating the annotation class is @interface. This annotation class sets a value variable. The default value is D;

There are also @target and @Retention annotations on top of the annotation class. Here are some of the annotations needed to create an annotation class:

@Target

To mark where this annotation can be used, with the ElementType enumeration class. What’s inside that enumeration class?

public enum ElementType {
    /** class, interface (including annotation type) or enumeration declaration */
    TYPE,

    /** Field declarations (including enumeration constants) */
    FIELD,

    /** method declaration */
    METHOD,

    /** Formal arguments (parameters - arguments passed when a method is called) declare */
    PARAMETER,

    /** The constructor declares */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** package declaration */
    PACKAGE,

    /** * Type parameter declaration * New in Java8: *@since1.8 * /
    TYPE_PARAMETER,

    /** * Any type declaration * New java8 feature: *@since1.8 * /
    TYPE_USE
}
Copy the code

@Retention

This annotation represents the life cycle of a custom annotation

public enum RetentionPolicy {
    /** * comments will be discarded by the compiler. * /
    SOURCE,

    /** * comments are recorded in class files by the compiler * but need not be retained by the VM at run time. This is the default */
    CLASS,

    /** * comments are recorded by the compiler in a class file and * are retained by the VM at run time, so they can be read reflectively. * /
    RUNTIME
}

Copy the code

Write a facet class

Because of the aspect, we will import the Spring AOP dependency package first.

<! SpringBoot project import AOP-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Copy the code

Create the section class

@Aspect
@Component
public class MyAnnAop {
    private Logger logger= LoggerFactory.getLogger(MyAnnAop.class);
    @Pointcut("@annotation(com.example.demo.annotation.MyAnn)")
    public void ann(a){}@Before("ann()")
    public void before(JoinPoint joinPoint){
        logger.info("Print: Before we start");
    }
    @AfterReturning(value = "ann()",returning = "res")
    public Object dochange(JoinPoint joinPoint,Object res){
        logger.info("AfterReturning Notification starts - Get data :{}",res);
        // Get data
        Map<String,String> map= (Map<String, String>) res;
        // Add a new value
        map.put("s1"."I'm adding a new value in AOP.");
        returnmap; }}Copy the code

Spring AOP specification

See Spring AOP for more information

annotations instructions
@Before Pre-notification, called before join point methods
@Around Surround notification, which overrides the old method but allows you to call the old method through reflection
@After Post-notification, called after join point methods
@AfterReturning Return notification, called after the join point method executes and returns normally, requiring that the join point method executes without exception
@AfterThrowing Exception notification, called when the join point method is abnormal

Use custom annotations

Here we use normal SpringBoot to use annotations, create a Service, use annotations in it, and then control the layer invocation

/ / service layer
@Service
public class TestService {
    @MyAnn
    public Map test(a){
        Map<String,String>  map=new HashMap<>();
        map.put("t1"."I set the value in Service.");
        returnmap; }}/ / control layer
@RestController
public class Test2 {
    private Logger logger= LoggerFactory.getLogger(Test2.class);

    @Autowired
    private TestService testService;

    @GetMapping("/test")
    public String test(String id){
        Map<String,String> s=testService.test();
        logger.info("Control layer output: {}",s.get("s1"));
        return "sccess"; }}Copy the code

The output

Com. Example. Demo. Aop. MyAnnAop: AfterReturning notification start - to get the data: {t1 = I am in the Service setting value} com. Example. Demo. Web. Test2: Control-layer output: I'm adding new values in AOPCopy the code

Matters needing attention

Using annotations that way is fine, but using them this way would break AOP

@RestController
public class Test2 {
    private Logger logger= LoggerFactory.getLogger(Test2.class);

    @Autowired
    private TestService testService;

    @GetMapping("/test")
    public String test(String id){
        Map<String,String> s=this.test2();
        logger.info("Control layer output: {}",s.get("s1"));
        return "sccess";
    }

    @MyAnn
    public Map test2(a){
        Map<String,String>  map=new HashMap<>();
        map.put("t1"."I set the value in the control layer.");
        returnmap; }}Copy the code

The output

Com. Example. Demo. Web. Test2: control layer output: nullCopy the code

This is supposed to be an internal method call, which calls concrete methods rather than the proxy methods generated with AOP

Specific reference materials:

  • Blog.csdn.net/Daybreak120…
  • Blog.csdn.net/u013151053/…
  • Zhewuzhou. Making. IO / 2018/09/01 /…