Spring boot 注解Annotation大全【持续更新】

        为了方便我们在日常开发注解的使用,本文将开发所需要的注解统一并进行归类起来,并结合用例进行解析,这样收藏起来以便日后使用。最主要本文将持续更新日常使用的注解,也可以评论中告知其他注解。

1依赖注入


1.1组件注解 @component

        @component,而其余 @Controller@Service@Repository都组合了@component注解,主要为便于使用者Class组件进行归类。

        默认加载IOC容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作

注解解析用法
@Component组件注解,使用了该注解会基于注释的配置和类路径扫描时,会自动扫描并加载Class到ICO容器中注释在类上
@Controller应用在MVC层(控制层)DispatcherServlet会自动扫描注解了此注解的类,然后将web请求映射到注解了@RequestMapping的方法上注释在类上
@Service应用在service层(业务逻辑层注释在类上
@Repository应用在dao层(数据访问层)注释在类上

1.2依赖注入注解

        @Autowired和@Inject、@Resource,可以与@Qualifier或者@Name配合使用,防止多实例注入时出错,以及值注入@Value。

注解解析用法
@Autowired通过AutowiredAnnotationBeanPostProcessor类实现的依赖注入,默认是根据类型进行注入的,因此如果有多个类型一样的Bean候选者,则需要限定其中一个候选者,否则将抛出异常。可注释在字段上,在方法上
@Inject作用与@Autowired一样可注释在字段上,在方法上、构造器上
@Resource默认按照名称进行装配,名称可以通过name属性进行指定可注释在字段上,在方法上
@Qualifier限定描述符除了能根据名字进行注入,更能进行更细粒度的控制如何选择候选者,可与@Autowired或者@Inject进行组合使用,进行精确注入可注释字段上,在方法上、参数上以及注解中

1.3 作用域和生命过程

        @Scope,具有4个作用域可看Scope作用域以及涉及的问题章节,以及生命周期过程处理@PostConstruct、@PreDestroy 。

注解解析用法
@Scope具有4个作用域singleton,prototype,session,request,默认为singleton单例模式可注释在Class创建时
@PostConstruct相当于init-method,使用在方法上,当Bean初始化时执行可注释在方法上
@PreDestroy相当于destory-method,使用在方法上,当Bean销毁时执行可注释在方法上

1.4 章节用例(结合1.1、1.2、1.3小节)

@Service //组件注入,注明为service组件
@Scope("prototype")//声明Scope为Prototype
public class UseFunctionService {
    
    @Autowired //默认按type注入
    @Qualifier("functionService") //精确注入
    FunctionService functionService;

    @Resource(name="baseDao")//默认按name注入,可以通过name和type属性进行选择性注入
    private BaseDao baseDao;

    @Inject
    @Qualifier("userServiceImpl") //精确注入  
    public IUserService userService;  
    
    @PostConstruct//执行完构造函数后执行
    public postConstruct(){
        System.out.println("postConstruct");
    }

    @PreDestroy//在销毁Bean前执行
    public perDestroy(){
         System.out.println("perDestroy");
    }

    @Autowired   
    public void setUserDao(@Qualifier("userDao") UserDao userDao) {   
     this.userDao = userDao;   
    }  

    public String SayHello(String word){
        return functionService.sayHello(word);
    }
}

2. 配置注解


2.1 @Configuration配置注解

        @Configuration可替换xml配置文件进行配置。被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。可与@PropertySource一起使用。 @Configuration作为元注解延伸了@SpringBootConfiguration

注解解析用法
@Configuration配置类注解,可以与@Beae、@PropertySource一起使用,进行配置注释在类、接口、枚举上
@SpringBootConfiguration组合注解,@Configuration配置、@EnableAutoConfiguration启用自动配置、@ComponentScan默认扫描@SpringBootApplication所在类的同级目录以及它的子目录可注解在类上
@AutoConfigureAfter在指定的自动配置类之后再配置可注解在类上

2.2扫描注解

@ComponentScan注解,被@Configuration注解标注的类上面,涉及了@filter过滤器注解

注解解析用法
@ComponentScan定义扫描的路径,默认就会加载标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中,excludeFilters 指定扫描的时候需要排除的组件,includeFilters 指定扫描的时候只包含的组件可注解在类Class
@ComponentScans包含着@ComponentScan数组可注解在类Class
@filter声明要用作包含过滤器或排除过滤器的类型过滤器可注解在@ComponentScan中

2.3 资源、值等注入注解

可以将配置文件、配置文件中的属性、以及系统属性等注入所需的字段中,或者bean中

注解解析用法
@Value值注入,可以注入普通字符,系统属性,表达式运算结果,其他Bean的属性,文件内容,网址请求内容,配置文件属性值等等可注释在字段上,方法上、参数上
@Bean声明当前方法的返回值为一个Bean,而且返回的Bean对应的类中可以定义init()方法和destroy()方法,然后在@Bean(initMethod=”init”,destroyMethod=”destroy”)定义,在构造之后执行init,在销毁之前执行destroy注解在方法上,注解上
@PropertySource指定配置文件位置,与@configuration类一起使用注解在类Class、接口上
@ImportResource加载xml配置文件注解在类Class、接口上
@ConfigurationProperties将properties属性与一个Bean及其属性相关联可注解在类上、接口上
@Import用来导入配置类的可注解在类上、接口上

2.4 条件注解 @Conditional

@Conditional根据满足某一特定条件创建特定的Bean,基于@Conditional元注解可延伸很多条件注解。

注解解析用法
@ConditionalOnBeanSpring容器中是否存在对应的实例,可以通过实例的类型、类名、注解、昵称去容器中查找(可以配置从当前容器中查找或者父容器中查找或者两者一起查找)这些属性都是数组,通过”与”的关系进行查找可注解方法上
@ConditionalOnClass类加载器中是否存在对应的类,逻辑跟@ConditionalOnBean类似可注解在方法上、类Class、接口上
@ConditionalOnExpression判断SpEL 表达式是否成立可注解在方法上、类Class、接口上
@ConditionalOnJava指定Java版本是否符合要求可注解在方法上、类Class、接口上
@ConditionalOnMissingBeanSpring容器中是否缺少对应的实例,逻辑跟@ConditionalOnBean类似可注解在方法上、类Class、接口上
@ConditionalOnMissingClassSpring容器中是否缺少对应的实例,逻辑跟@ConditionalOnBean类似可注解在方法上、类Class、接口上
@ConditionalOnNotWebApplication应用程序是否是非Web程序,没有提供属性,只是一个标识可注解在方法上、类Class、接口上
@ConditionalOnProperty应用环境中的屬性是否存在,逻辑跟@ConditionalOnBean类似可注解在方法上、类Class、接口上上
@ConditionalOnResource是否存在指定的资源文件。只有一个属性resources,是个String数组。会从类加载器中去查询对应的资源文件是否存在可注解在方法上、类Class、接口上
@Profile指定某个bean属于哪一个profile:spring.profiles.active和spring.profiles.default(默认)可注解在方法上,类class、接口上

2.5 章节用例(2.1、2.2、2.3、2.4小节)

@Configuration
//@SpringBootConfiguration
@ComponentScan(value="com.cn",ComponentDefaultFilters=true,
  includeFilters={
    @Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
    @Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class})
})
@ImportResource("classpath:condition.xml")//导入xml配置
@Import(ConditionConfig.class)//导入ConditionConfig Class,并会实例化到容器中以及ConditionConfig中的配置也一起注入
public class Config {
     @Value("I Love You!") //注入普通字符
    private String normal;
    @Value("#{systemProperties['os.name']}") //注入操作系统属性
    private String osName;
    @Value("#{ T(java.lang.Math).random() * 100.0 }") //注入表达式运算结果
    private double randomNumber;
    @Value("#{demoService.another}") //注入其他Bean的属性
    private String fromAnother;
    @Value("classpath:org/light4j/sping4/usually/el/test.txt") //注入文件内容
    private Resource testFile;
    @Value("http://www.baidu.com") //注入网址内容
    private Resource testUrl;
    @Value("${book.name}") //注入属性文件
    private String bookName;

    @Bean//加载bean
    @Conditional(WindowsCondition.class) // 通过@Conditional注解,符合Windows条件则true
    @ConditionalOnResource(resources="classpath:windows.ini")//在类路径下是否存在windows.ini文件,存在为true,最后进行注解与操作,为true实例化Bean
    public ListService windowsListService(){
        return new WindowsListService();
    }

    @Bean
    @ConditionalOnClass(LinuxCondition.class) // 通过@ConditionalOnClass注解,符合Linux条件则true
    @ConditionalOnProperty(name = "synchronize", havingValue = "true"))//如果synchronize在配置文件中并且值为true
    public ListService linuxListService(){
        return new LinuxListService();
    }
    //加载配置文件中前缀为spring.datasource的属性
     @ConfigurationProperties(prefix = "spring.datasource")
      public DataSource jwcDataSource() {
         return DataSourceBuilder.create().build();
    }

    @Bean
    @ConditionalOnMissingClass({LinuxCondition.class,WindowsCondition.class})//当容器中缺失这两个Class时为true
    @Profile("dev")//在dev环境下为true  最后结果为注解和之与,true实例化该Bean
    public ListService macListService(){
        return new MacListService();
    }
}

3. 验证注解


验证注解在javax.validation包下:

注解解析用法
@Valid启动校验,Errors参数要紧跟在带有@Valid注解的参数后面,@Valid注解所标注的就是要检验的参数可注释在字段、方法、构造器、参数上
@AssertFalse所注解的元素必须是Boolean类型,并且值为false可注释在字段、方法、构造器、参数上
@AssertTrue所注解的元素必须是Boolean类型,并且值为true可注释在字段、方法、构造器、参数上
@DecimalMax所注解的元素必须是数字,并且它的值要小于或等于给定的BigDecimalString值可注释在字段、方法、构造器、参数上
@DecimalMin所注解的元素必须是数字,并且它的值要大于或等于给定的BigDecimalString值可注释在字段、方法、构造器、参数上
@Digits所注解的元素必须是数字,并且它的值必须有指定的位数可注释在字段、方法、构造器、参数上
@Future所注解的元素的值必须是一个将来的日期可注释在字段、方法、构造器、参数上
@Max所注解的元素必须是数字,并且它的值要小于或等于给定的值可注释在字段、方法、构造器、参数上
@Min所注解的元素必须是数字,并且它的值要大于或等于给定的值可注释在字段、方法、构造器、参数上
@NotNull所注解元素的值必须不能为null可注释在字段、方法、构造器、参数上
@Null所注解元素的值必须为null可注释在字段、方法、构造器、参数上
@Past所注解的元素的值必须是一个已过去的日期可注释在字段、方法、构造器、参数上
@Pattern所注解的元素的值必须匹配给定的正则表达式可注释在字段、方法、构造器、参数上
@Size所注解的元素的值必须是String、集合或数组,并且它的长度要符合给定的范围可注释在字段、方法、构造器、参数上

4.AOP


4.1 AspectJ的注解式切面编程:

AspectJ的注解式在org.aspectj包下

注解解析用法
@Aspect声明该类是一个切面可注解在类Class、接口上
@After通知方法会在目标方法返回或抛出异常后调用可注解在方法上
@Before通知方法会在目标方法调用之前执行可注解在方法上
@Around通知方法会将目标方法封装起来可注解在方法上
@AfterReturning通知方法会在目标方法返回后调用可注解在方法上
@AfterThrowing通知方法会在目标方法抛出异常后调用可注解在方法上
@Pointcut能够在一个@AspectJ切面内定义可重用的切点,(通过@Pointcut注解声明频繁使用的切点表达式)可注解在方法上
@annotation限定匹配带有指定注解的连接点可注解在建言(advice)上,如@After等
@EnableAspectJAutoProxy开启Spring对AspectJ的支持,在配置类上可注解在类Class、接口上

4.2 AspectJ指示器

execution指示器是我们在编写切点定义时最主要使用的指示器:

注解解析用法
AspectJ指示器描  述
arg()限制连接点匹配参数为指定类型的执行方法可注释在AspectJ的注解式、如@After等
@args()限制连接点匹配参数由指定注解标注的执行方法可注释在AspectJ的注解式,如@After等
execution()用于匹配是连接点的执行方法可注释在AspectJ的注解式,如@After等
this()限制连接点匹配AOP代理的bean引用为指定类型的类可注释在AspectJ的注解式,如@After等
Target限制连接点匹配目标对象为指定类型的类可注释在AspectJ的注解式,如@After等
@target()限制连接点匹配特定的执行对象,这些对象对应的类要具有指定类型的注解可注释在AspectJ的注解式,如@After等
within()限制连接点匹配指定的类型可注释在AspectJ的注解式,如@After等
@within()限制连接点匹配指定注解所标注的类型(当使用Spring AOP时,方法定义在由指定的注解所标注的类里)可注释在AspectJ的注解式,如@After等

4.3 用例:编写切面

@Aspect //声明该类是一个切面
@Component 
public class LogAspect {
    private final String POINT_CUT ="execution(* org.sping4.ccww.aop.DemoMethodService.*(..))";
    
     @Pointcut("@annotation(org.ccww.sping4.base.aop.Action)") //声明切面
     public void annotationPointCut(){};

     @After("annotationPointCut()") //声明一个建言,并使用@Pointcut定义的切点
    public void after(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Action action = method.getAnnotation(Action.class); 
        System.out.println("注解式拦截 " + action.name()); //⑤
    }

     @Before("execution(* org.sping4.ccww.aop.DemoMethodService.*(..))")//声明一个建言,此建言直接使用拦截规则作为参数
      public void before(JoinPoint joinPoint){
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        System.out.println("方法规则式拦截,"+method.getName());
    }
    
    /**
    * 后置返回
    * 如果第一个参数为JoinPoint,则第二个参数为返回值的信息
    * 如果第一个参数不为JoinPoint,则第一个参数为returning中对应的参数
    * returning:限定了只有目标方法返回值与通知方法参数类型匹配时才能执行后置返回通知,否则不执行,
    * 参数为Object类型将匹配任何目标返回值
    */
    @AfterReturning(value = POINT_CUT,returning = "result")
    public void doAfterReturningAdvice1(JoinPoint joinPoint,Object result){
         System.out.println("第一个后置返回通知的返回值:"+result);
    }
}

5. Spring MVC


注解解析用法
@EnableWebMvc会开启一些默认配置,如一些ViewResolver或者MessageConverter等可注解在类Class、接口上
@RequestMapping用来映射Web请求(访问路径和参数),处理类和方法的(即配置URL和方法之间的映射),注解在方法上的@RequestMapping路径会继承注解在类上的路径可注解在类Class、接口上、方法上
@ResponseBody支持将返回值放在response体内可注解在返回值前或者方法上
@RequestBody允许request的参数在request体内
@PathVariable用来接收路径参数,如/ccww/003,可接收003作为参数可注解在参数前
@RestController组合注解,组合了@Controller和@ResponseBody,这就意味着当你只开发一个和页面交互数据的控制的时候,需要使用此注解。若没有此注解,要想实现上述功能,则需要自己在代码中加@Controller和@ResponseBody两个注解可注解在类Class、接口上
@ModelAttribute绑定请求参数到命令对象、暴露@RequestMapping 方法返回值为模型数据、暴露表单引用对象为模型数据可注解在方法、参数上

用例:

@Controller //声明此类是一个控制器
@RequestMapping("/ccww") //映射此类的访问路径是/ccww
//@RestController // 使用@RestController,声明是控制器,并且返回数据时不需要@ResponseBody
//@RequestMapping("/ccww")
public class DemoAnnoController {
    //此方法未标注路径,因此使用类级别的路径/anno;produces可定制返回的response的媒体类型和字符集,或返回值是json对象,则设置porduces="application/json;charset=UTF-8"
    @RequestMapping(produces = "text/plain;charset=UTF-8")  
    public @ResponseBody String index(HttpServletRequest request) { //可接受HttpServletRequest作为参数,当然也可以接受HttpServletResponse作为参数。此处的@ResponseBody用在返回值前
        return "url:" + request.getRequestURL() + " can access";
    }
    @RequestMapping(value = "/demoPathVar/{str}", produces = "text/plain;charset=UTF-8")// 
    public @ResponseBody String demoPathVar(@PathVariable String str, //接受路径参数,并在方法参数前结合@PathVariable使用,访问路径为/ccww/demoPathVar/xxx
            HttpServletRequest request) {
        return "url:" + request.getRequestURL() + " can access,str: " + str;
    }
    //常规的request参数获取,访问路径为/ccww/requestParam?id=1
    @RequestMapping(value = "/requestParam", produces = "text/plain;charset=UTF-8") 
    public @ResponseBody String passRequestParam(Long id,
            HttpServletRequest request) {
        return "url:" + request.getRequestURL() + " can access,id: " + id;
    }
    @RequestMapping(value = "/obj", produces = "application/json;charset=UTF-8")
    @ResponseBody // 可注解在方法上
    public String passObj(DemoObj obj, HttpServletRequest request) {
         return "url:" + request.getRequestURL() 
                    + " can access, obj id: " + obj.getId()+" obj name:" + obj.getName();
    }
    //映射不同的路径到相同的方法,访问路径为/anno/name1或/anno/name2
    @RequestMapping(value = { "/name1", "/name2" }, produces = "text/plain;charset=UTF-8")
    public @ResponseBody String remove(HttpServletRequest request) {
        return "url:" + request.getRequestURL() + " can access";
    }
    
     @RequestMapping(value = "/helloWorld") 
     //以“user”为名称添加到模型对象中供视图页面展示使用
    public String helloWorld(@ModelAttribute User user) { 
     return "helloWorld"; 
    } 
}

6.Spring security


Spring security用户访问认证和授权,两个关键注解:

注解解析用法
@EnableWebSecurityConfig该注解和@Configuration注解一起使用,注解 WebSecurityConfigurer类型的类,或者利用@EnableWebSecurity注解继承WebSecurityConfigurerAdapter的类,这样就构成了Spring Security的配置可注解在Class上
@EnableGlobaleMethodSecuritySpring security默认是禁用注解的,要想开启注解,需要继承WebSecurityConfigurerAdapter的类上加@EnableGlobalMethodSecurity注解,来判断用户对某个控制层的方法是否具有访问权限可注释在Class上

用@EnableGlobaleMethodSecurity的参数想要开启注解:

  • @EnableGlobalMethodSecurity(securedEnabled=true):开启@Secured注解过滤权限
  • @EnableGolablMethodSecurity(jsr250Enabled=true):开启@RolesAllowed注解过滤权限
  • @EnableGlobalMethodSecurity(prePostEnable=true):使用Spring_EL表达式控制更细粒度的访问控制

具体开启注解解析如下:

注解解析用法
@Secured认证是否有权限访问可注解方法上
@RolesAllowed该方法只要具有其参数中任意一种权限就可以访问(可以省略前缀ROLE_)可注解在方法上
@DenyAll拒绝所有访问可注解在方法上
@PermitAll允许所有访问可注解在方法上

@PreAuthorize

在方法执行之前执行,而且这里可以调用方法的参数,也可以得到参数值。

@PreAuthorize注解会在方法执行前进行权限验证,支持Spring EL表达式,它是基于方法注解的权限解决方案。只有当@EnableGlobalMethodSecurity(prePostEnabled=true)的时候,@PreAuthorize才可以使用,@EnableGlobalMethodSecurity注解在SPRING安全中心进行设置

可注解在方法上
@PostAuthorize在方法执行之后执行,而且这里可以调用方法的返回值,如果EL为false,那么该方法也已经执行完了,可能会回滚可注解在方法上
@PreFilter在方法执行之前执行,而且这里可以调用方法的参数,然后对参数值进行过滤或处理,EL变量filterObject表示参数,如果有多个参数,使用filterTarget注解参数可注解在方法上
@PostFilter在方法执行之后执行,而且这里可以通过表达式来过滤方法的结果可注解在方法上

用例:

两个关键注解@EnableWebSecurityConfig、@EnableGlobaleMethodSecurity:

@Configuration
@EnableWebSecurity//开启webSecurityConfig
@EnableGlobalMethodSecurity(prePostEnabled = true.securedEnabled = true)//可开启多个注解
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
    .....
}

其他注解:

@Secured("IS_AUTHENTICATED_ANONYMOUSLY")//@Secured注解,匿名访问
public Account readAccount(Long id){
    ...
}
 
@Secured("ROLE_TELLER")//@Secured注解具有TELLER访问
public Account readAccount(Long id){
    ...
}
@PreAuthorize("#userId==authentication.principal.userId or hasAuthority('ADMIN')")
//利用Spring Security的@P标注参数,或者Spring Data的@Param标注参数来接收@PreAuthorize的返回值
public void changPassword(@P("userId")long userId){
  ...
 }
@PreAuthorize("hasAuthority('ADMIN')")//PreAuthorize是否具有admin角色
public void changePassword(long userId){
...
}

#######################################

例子2:如何使用
①. 注解如何使用?
/**
 * 删除用户
 */
@PreAuthorize("@ss.hasPermi('system:user:remove')")
@Log(title = "用户管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{userIds}")
public Result remove(@PathVariable Long[] userIds) {
    if (ArrayUtils.contains(userIds, getUserId())) {
        return error("当前用户不能删除");
    }
    return toAjax(userService.deleteUserByIds(userIds));
}

②. 自定义权限实现
@PreAuthorize(“@ss.hasPermi(‘system:user:remove’)”)的意思是什么?

  • A. ss 是一个注册在 Spring容器中的BEAN,对应的类是cn.hadoopx.framework.web.service.PermissionService
  • B. hasPermi 是PermissionService类中定义的方法;
  • C.当Spring EL 表达式返回TRUE,则权限校验通过;
  • D. PermissionService.java的定义如下:
     

/**
 * 自定义权限实现,ss取自SpringSecurity首字母
 * @author ROCKY
 */
@Service("ss")
public class PermissionService {
    /**
     * 所有权限标识
     */
    private static final String ALL_PERMISSION = "*:*:*";

    /**
     * 管理员角色权限标识
     */
    private static final String SUPER_ADMIN = "admin";
    private static final String ROLE_DELIMETER = ",";
    private static final String PERMISSION_DELIMETER = ",";

    /**
     * 验证用户是否具备某权限
     * @param permission 权限字符串
     * @return 用户是否具备某权限
     */
    public boolean hasPermi(String permission) {
        if (StringUtils.isEmpty(permission)) {
            return false;
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) {
            return false;
        }
        return hasPermissions(loginUser.getPermissions(), permission);
    }

    /**
     * 验证用户是否不具备某权限,与 hasPermi逻辑相反
     * @param permission 权限字符串
     * @return 用户是否不具备某权限
     */
    public boolean lacksPermi(String permission) {
        return hasPermi(permission) != true;
    }

    /**
     * 验证用户是否具有以下任意一个权限
     * @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表
     * @return 用户是否具有以下任意一个权限
     */
    public boolean hasAnyPermi(String permissions) {
        if (StringUtils.isEmpty(permissions)) {
            return false;
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) {
            return false;
        }
        Set<String> authorities = loginUser.getPermissions();
        for (String permission : permissions.split(PERMISSION_DELIMETER)) {
            if (permission != null && hasPermissions(authorities, permission)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断用户是否拥有某个角色
     * @param role 角色字符串
     * @return 用户是否具备某角色
     */
    public boolean hasRole(String role) {
        if (StringUtils.isEmpty(role)) {
            return false;
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) {
            return false;
        }
        for (SysRole sysRole : loginUser.getUser().getRoles()) {
            String roleKey = sysRole.getRoleKey();
            if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role))) {
                return true;
            }
        }
        return false;
    }

    /**
     * 验证用户是否不具备某角色,与 isRole逻辑相反。
     * @param role 角色名称
     * @return 用户是否不具备某角色
     */
    public boolean lacksRole(String role) {
        return hasRole(role) != true;
    }

    /**
     * 验证用户是否具有以下任意一个角色
     * @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表
     * @return 用户是否具有以下任意一个角色
     */
    public boolean hasAnyRoles(String roles) {
        if (StringUtils.isEmpty(roles)) {
            return false;
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) {
            return false;
        }
        for (String role : roles.split(ROLE_DELIMETER)) {
            if (hasRole(role)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否包含权限
     * @param permissions 权限列表
     * @param permission  权限字符串
     * @return 用户是否具备某权限
     */
    private boolean hasPermissions(Set<String> permissions, String permission) {
        return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission));
    }
}

7. Spring Boot


注解解析用法
@SpringBootApplicationSpring Boot核心注解,组合注解(@Configuration、@EnableAutoConfiguration、@ComponentScan),主要是为了开启自动配置注解在Class,接口
@EnableAutoConfiguration让Spring Boot根据类路径中的jar包依赖为当前项目进行自动配置可注释在Class

参考:

推荐收藏系列:Spring boot 2.x注解Annotation大全(持续更新....)-阿里云开发者社区

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/631891.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【汇编】算术指令

一、加法指令 &#xff08;一&#xff09;各加法指令的格式及操作 加法指令可做字或字节运算 &#xff08;1&#xff09;加法指令 ADD 格式&#xff1a;ADD DST,SRC执行的操作&#xff1a;(DST) ← (SRC)(DST) &#xff08;2&#xff09;带进位加法指令 ADC 格式&#xf…

ENZO--Leptin (human) ELISA kit

瘦素(Leptin)是由ob基因编码、在脂肪组织中生成的一种脂肪代谢调控产物&#xff0c;在代谢和调控体重等方面发挥重要作用。它通过下丘脑中的瘦素受体发出信号&#xff0c;降低食欲&#xff0c;增加能量消耗。在外周组织中&#xff0c;瘦素能拮抗胰岛素信号传导&#xff0c;增加…

目标检测标注工具Labelimg安装与使用

目录 一、安装Labelimg与打开 二、使用 1、基本功能介绍 2、快捷键 3、状态栏的工具 4、数据准备 5、标注 三、附录 1、YOLO模式创建标签的样式 2、create ML模式创建标签的样式 3、PascalVOC模式创建标签的样式 一、安装Labelimg与打开 源码网址&#xff1a;Label…

前端通知组件封装

背景 实现如上图效果&#xff1a;点击小铃铛&#xff0c;从右侧展示通知&#xff0c;点击其中一条跳&#xff0c;转到一个新页面&#xff1b;小铃铛数目减少&#xff1b; 实现 index.vue <template><el-drawerv-if"visible":visible.sync"visible&…

C#知识|上位机子窗体嵌入主窗体方法(实例)

哈喽,你好啊,我是雷工! 上位机开发中,经常会需要将子窗体嵌入到主窗体, 本节练习C#中在主窗体的某个容器中打开子窗体的方法。 01 需求说明 本节练习将【账号管理】子窗体在主窗体的panelMain容器中打开。 账号管理子窗体如下: 主窗体的panelMain容器位置如图: 02 实现…

【找到所有数组中消失的数字】leetcode,python

很菜的写法&#xff1a; class Solution:def findDisappearedNumbers(self, nums: List[int]) -> List[int]:nlen(nums)#存1-Nnum_1[i for i in range(1,n1)]#预存数num_2[]nums.sort()for i in nums:num_1[i-1]0for i in num_1:if i!0:num_2.append(i)return num_2能过但是…

计算机毕业设计hadoop+hive+hbase学情分析 在线教育大数据 课程推荐系统 机器学习 深度学习 人工智能 大数据毕业设计 知识图谱

毕 业 设 计&#xff08;论 文&#xff09;开 题 报 告 1&#xff0e;结合毕业设计&#xff08;论文&#xff09;课题情况&#xff0c;根据所查阅的文献资料&#xff0c;每人撰写不少于1000字的文献综述&#xff1a; 一、研究背景和意义 “互联网”和大数据带来了网络教育的蓬…

Java入门——异常

异常的背景 初识异常 我们曾经的代码中已经接触了一些 "异常" 了. 例如: //除以 0 System.out.println(10 / 0); // 执行结果 Exception in thread "main" java.lang.ArithmeticException: / by zero //数组下标越界 int[] arr {1, 2, 3}; System.out.…

C语言之指针初阶

目录 前言 一、内存与地址的关系 二、指针变量 三、野指针 四、const 五、传值调用与传址调用 总结 前言 本文主要介绍C语言指针的一些基础知识&#xff0c;为后面深入理解指针打下基础&#xff0c;因此本文内容主要包括内存与地址的关系&#xff0c;指针的基本语法&…

LiveGBS流媒体平台GB/T28181用户手册-服务器概览:通道信息、负载信息、CPU使用、存储使用、带宽使用(Mbps)、内存使用

LiveGBS用户手册-服务器概览&#xff1a;通道信息、负载信息、CPU使用、存储使用、带宽使用&#xff08;Mbps&#xff09;、内存使用 1、服务器概览1.1、通道信息1.2、负载信息1.2.1、信息说明1.2.2、会话列表 1.3、CPU使用1.4、存储使用1.5、带宽使用&#xff08;Mbps&#xf…

视频下载器 - 网页视频自动嗅探2.2.4

【应用名称】&#xff1a;视频下载器 - 网页视频自动嗅探 【适用平台】&#xff1a;#Android 【软件标签】&#xff1a;#Video #Downloader 【应用版本】&#xff1a;2.2.4 【应用大小】&#xff1a;33MB 【软件说明】&#xff1a;软件升级更新。支持多种格式的看片神器&am…

java入门详细教程之集合的理解与应用

一、Collenction集合 数组和集合的区别 长度 数组的长度是不可变的,集合的长度是可变的 数据类型 数组可以存基本数据类型和引用数据类型 集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类 Collection 集合概述和使用 Collection集合概述​&#xff1a; 是单…

MacOS下载安装JDK8

一、前言 今天给苹果电脑安装JDK环境&#xff0c;后续打算把Mac系统也用起来&#xff0c;也体验一把用苹果系统开发。 JDK就不过多介绍了&#xff0c;大家都是JAVA开发&#xff0c;JDK就是JAVA开发的必要环境。目前已经更新到JDK20了&#xff0c;不过我是不会更新的&#xff0…

微服务中的鉴权怎么做?

大家好&#xff0c;我是苍何呀。 现在出去找工作&#xff0c;简历上不写上微服务的技术&#xff0c;仿佛自己跟不上时代了&#xff0c;面试官更是喜欢盯着微服务项目来提问。 但其实虽说微服务是主流&#xff0c;随着云原生架构的发展&#xff0c;微服务也是趋势&#xff0c;…

DOS学习-目录与文件应用操作经典案例-dir

欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一.前言 二.使用 三.练习 一.前言 dir是"directory"&#xff08;目录&#xff09;的缩写&#xff0c;它主要用于展示某个磁盘上的全部或特定文件目录。在DOS操作系统中&#…

ES6中数组新增了哪些扩展?

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;JavaScript篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来JavaScript篇专栏内容:ES6中数组新增了哪些扩展&#xff1f; 目录 一、扩展运算符的应用 二、构造函数新…

Web3与物联网:构建智能连接的数字世界

引言 随着互联网的不断发展&#xff0c;物联网&#xff08;Internet of Things, IoT&#xff09;作为一种新兴的信息技术&#xff0c;正在逐渐渗透到我们的生活和工作中。而随着Web3的兴起&#xff0c;物联网将迎来新的发展机遇。本文将探讨Web3与物联网的结合&#xff0c;如何…

全面解析防静电措施:保障工业安全,预防静电危害

静电是一种常见的物理现象&#xff0c;由于电荷的不平衡而产生。在特定的环境中&#xff0c;静电可能会带来危害&#xff0c;如损坏电子设备、引起火灾等。因此&#xff0c;采取适当的防静电措施是非常重要的。以下是一些常见的防静电方法&#xff1a; 增加环境湿度&#xff1a…

崆峒酥饼:佳节馈赠的美味之选

崆峒酥饼&#xff1a;佳节馈赠的美味之选 在即将到来的端午节&#xff0c;人们开始忙碌地准备着走亲访友的礼物。而崆峒酥饼&#xff0c;作为一种传统的美食&#xff0c;不仅是节日里的美味享受&#xff0c;更是传递情谊的佳品。 崆峒酥饼&#xff0c;以其酥脆的口感和独特的风…

使用httpx异步获取高校招生信息:一步到位的代理配置教程

概述 随着2024年中国高考的临近&#xff0c;考生和家长对高校招生信息的需求日益增加。了解各高校的专业、课程设置和录取标准对于高考志愿填报至关重要。通过爬虫技术&#xff0c;可以高效地从各高校官网获取这些关键信息。然而&#xff0c;面对大量的请求和反爬机制的挑战&a…