Understanding java annotation four

Through the previous reading, everyone must have a simple understanding of annotations and be able to carry out simple applications. Let me tell you about the use of annotations.

In fact, the ever-changing, the annotation is still like that, that is, the annotation is obtained through reflection, and then the annotation is analyzed, so as to realize the logical processing.

I don’t know if you have ever encountered it. An annotation is added to a controller class, and then all methods will perform permission filtering or authentication. When I first encountered this, there was only one feeling--- ------Awesome!

What I think in my heart is worthy of being a great god, just do everything you want!

In fact, looking back now, it is an interception and annotation analysis, which realizes request filtering or interception, and there is no particularly advanced knowledge. Still, it is not difficult for those who are meeting, and those who are difficult are not, really go deep into it. , You will find, oh, it turned out to be like this!

Next, I use the interceptor processing in Spring to realize the filtering of annotations on methods.

Create a new interceptor.

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface TestAnno {

    //多个或者多种过滤,也可以直接使用下面的单种
    String[] values() default {TestConstant.BOSS,TestConstant.STAFF};

//    String value();

}

This annotation is easy to understand, it is an array collection, define the permissions as BOSS or STAFF, for convenience, I created an interface to store constants

package com.example.demoproject.constant;

public interface TestConstant {

    String BOSS = "boss";

    String STAFF = "staff";

}

The following is to construct an interceptor, of course I need to construct an interceptor bean. Because the loading interceptor is before the ApplicationContext is loaded, directly adding @Service or @Component cannot be injected successfully. So create a configuration to load the interceptor into the Spring container.

package com.example.demoproject.filter;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport  {

    @Bean
    public TestInterceptor testInterceptor(){
        return new TestInterceptor();
    }


    @Override
    public void addInterceptors(InterceptorRegistry registry){
        // 拦截所以请求
        registry.addInterceptor(this.testInterceptor()).addPathPatterns("/**");
    }
}

This configuration class is to load a Bean of TestInterceptor, and then add this interceptor to the interceptor collection.

The next step is to implement this interceptor. Let's look at the Controller first

package com.example.demoproject.controller;

import com.example.demoproject.annotion.TestAnno;
import com.example.demoproject.constant.TestConstant;
import com.example.demoproject.emun.TestEnum;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@TestAnno(values = TestConstant.BOSS)
public class TestController {

    @PostMapping("/test")
    @TestAnno(values = TestConstant.STAFF)
    public Map<String,String> get(){
       Map<String,String> map = new HashMap();
       map.put("response","success");

        return map;
    }
}

Because this annotation can be added to methods and classes, I have added a demonstration (@Target({ElementType.TYPE,ElementType.METHOD}))

Okay, let's look at the implementation of the interceptor:

package com.example.demoproject.filter;

import com.alibaba.fastjson.JSON;
import com.example.demoproject.annotion.TestAnno;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Method;


public class TestInterceptor implements HandlerInterceptor {

    // 在业务处理器处理请求之前被调用
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{

        if(handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod)handler;

            Method method = handlerMethod.getMethod();
            System.out.println(method);
            Class<?> aClass = method.getDeclaringClass();

            TestAnno anno = aClass.getAnnotation(TestAnno.class);
            System.out.println("anno:"+ JSON.toJSONString(anno.values()));
            TestAnno anno1 = method.getAnnotation(TestAnno.class);
            System.out.println("anno1:"+ JSON.toJSONString(anno1.values()));
            System.out.println("--------------");
            String name = request.getParameter("name");
            System.out.println("name:"+name);
        }
//        System.out.println("输出request"+JSON.toJSON(request));
        return true;
    }
    // 在业务处理器处理请求完成之后,生成视图之前执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception{
    }
    // 在DispatcherServlet完全处理完请求之后被调用,可用于清理资源
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception{
    }

}

Interceptors must be known to everyone, so I won't introduce them much. The main processing here is preHandle, which is processed before the method. This method has a return value, boolean type, returns true, continues to go down, returns false, and is directly intercepted.

As you can see from the code, we can get the requested method and class, and then get their annotations, and then we can judge whether the annotations are consistent with expectations, and then the judgment logic (I didn't write this part, it needs to be dealt with according to the actual situation) , If the check fails, it returns false, if the check passes, it returns true.

In this case, an annotation interception request or filtering authority structure is complete, isn't it just that?

If it feels okay, just give it a thumbs up~

Guess you like

Origin blog.csdn.net/zsah2011/article/details/105668489