ThreadLocal保存用户登录信息

目录结构:

ThreadLocal保存用户登录信息_第1张图片

 1.编写注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Target  用于描述注解的使用范围   ElementType.METHOD 用于描述方法   ElementType.TYPE 用于描述类、接口(包括注解类型) 或enum声明
 * @Retention  定义被它所注解的注解保留多久
 * source:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;被编译器忽略
 * class:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期
 * runtime:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExposeUserInfo {
}

2.编写类user,ThreadLocal存放user类

import lombok.Data;

@Data
public class User {
    String id;

    String name;
}
public class UserContext {
    private static ThreadLocal threadLocal = new ThreadLocal<>();

    public static void set(User user) {
        threadLocal.set(user);
    }

    public static User get() {
        return threadLocal.get();
    }

    public static void remove(){
        threadLocal.remove();
    }
}

3.编写切面

import com.example.aopannotation.threadlocal.User;
import com.example.aopannotation.threadlocal.UserContext;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
public class UserInfoAspect {
    public Logger logger = LoggerFactory.getLogger(UserInfoAspect.class);

    /**
     * 切点放在注解上,通过注解实现aop切面
     */
    @Pointcut("@annotation(com.example.aopannotation.annotation.ExposeUserInfo)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        User user = new User();
        //1.从请求头获取用户的信息
        HttpServletRequest request = null;
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        request = requestAttributes.getRequest();
        // 2.获取用户的id
        String id = request.getHeader("id");
        //此处可以查库,得到user对象的其他信息
        user.setId(id);
        UserContext.set(user);
        try {
            // 3.设置用户上下文
            UserContext.set(user);
            // 执行并返回
            return joinPoint.proceed();
        } catch (Throwable throwable) {
            throw throwable;
        } finally {
            // 4.移除(防止内存泄漏)
            UserContext.remove();
        }
    }
}

4.编写controller

import com.example.aopannotation.annotation.ExposeUserInfo;
import com.example.aopannotation.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class ExposeController {
    @Autowired
    UserInfoService userInfoService;

    @ExposeUserInfo
    @PostMapping("/userinfo")
    public String test() {
        return userInfoService.getUserInfo();
    }
}

5.编写service

import com.example.aopannotation.threadlocal.User;
import com.example.aopannotation.threadlocal.UserContext;
import org.springframework.stereotype.Service;

@Service
public class UserInfoService {
    public String getUserInfo(){
        User user= UserContext.get();
        return user.getId();
    }
}

6.postman请求

ThreadLocal保存用户登录信息_第2张图片

你可能感兴趣的:(threadlocal,spring,java)