Java|使用Java注解

这个注解完成了一个 Servlet 代理多个请求。

ServletMapping 注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface ServletMapping {
    String value() default "";
}

注解使用

import cn.liuqichun.annotation.ServletMapping;
import cn.liuqichun.dao.UserDao;
import cn.liuqichun.entity.User;
import cn.liuqichun.utils.Result;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Description: 处理用户相关请求,通过反射+注解代理所有用户相关方法
 *
 * @author: liuqichun
 */
@WebServlet(urlPatterns = {"/user", "/user/*"})
public class UserServlet extends HttpServlet {

    private final ObjectMapper json = new ObjectMapper();

    private final UserDao userDao = new UserDao();

    private final static ConcurrentHashMap<String, Method> uriMap;

    @ServletMapping("/user/register")
    private void registerUser(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 业务逻辑
    }

    @ServletMapping("/user/login")
    private void login(HttpServletRequest request, HttpServletResponse response) throws IOException{
       // 业务逻辑
    }

    @ServletMapping("/user/del")
    private void del(HttpServletRequest request, HttpServletResponse response) throws IOException{
        // 业务逻辑
    }

    @ServletMapping("/user/modify")
    private void modify(HttpServletRequest request, HttpServletResponse response) throws IOException{
        // 业务逻辑
    }

    @ServletMapping("/user/list")
    private void userList(HttpServletRequest request, HttpServletResponse response) throws IOException{
        // 业务逻辑
    }


    // config operate  -----------------------------------------------------------------
    static{
        uriMap = new ConcurrentHashMap<String, Method>();
        Method[] methods = UserServlet.class.getDeclaredMethods();

        for (Method m : methods) {
            ServletMapping annotation = m.getAnnotation(ServletMapping.class);
            if (annotation != null) {
                String uri = annotation.value();
                System.out.println("annotation.value() = " + annotation.value());
                if (uri.length() > 0) {
                    uriMap.put(uri, m);
                } else {
                    System.err.println("[ERROR] 存在非法的注解");
                }
            }
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String uri = request.getRequestURI();
        Method method = uriMap.get(uri);
        if (method != null) {
            try {
                method.invoke(this, request, response);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            response.setStatus(400);
            json.writeValue(response.getOutputStream(), Result.error("请求异常"));
            System.err.println("[ERROR] 处理方法异常");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

总结

在 Java 项目中(多是基于 Spring)大量用到了注解,注解提供了方法额外的信息,例如可以放置方法的备注,这些备注可以在程序运行时获取,这对于日志系统很有帮助,还有放置方法的访问权限,目前绝大多数鉴权框架都是用注解进行标记,注解为类或方法提供了额外信息的解耦,而且用起来很方便。

讲注解的一些文章:

[1] https://blog.csdn.net/javazejian/article/details/71860633 [2] https://ifeve.com/java-annotations/ [3] https://www.runoob.com/w3cnote/java-annotation.html [4] https://www.liaoxuefeng.com/wiki/1252599548343744/1265102413966176