Java学习笔记(八)

AuthorizationManager

AuthorizationManager 是 Spring Security 中用于处理授权的核心接口之一。它负责决定某个特定请求是否被允许访问特定资源。Spring Security 通过这个接口来实现复杂的授权逻辑,以确保用户在系统中拥有适当的权限。

AuthorizationManager接口在Spring Security 5.5版本中被引入,是Spring Security中的一个重要接口,它主要用于统一处理授权决策,它取代了之前的AccessDecisionManagerAccessDecisionVoter,用于做出最终的访问控制决策。

通过AuthorizationManager,开发者可以灵活地定义各种授权规则,这些规则可以基于用户的认证状态、角色、权限等因素。

常见实现类

AuthenticatedAuthorizationManager:用于授权所有经过认证的用户。只要用户已经登录,无论其角色或权限如何,都可以访问某些资源。
AuthorityAuthorizationManager:用于基于用户角色或权限进行授权。它可以使用hasRole或hasAuthority来检查用户的角色或权限,适用于需要基于用户角色或权限进行访问控制的场景。
WebExpressionAuthorizationManager:基于Spring Security表达式进行授权控制。它使用SpEL(Spring Expression Language)来定义灵活的授权规则,适用于需要更灵活或复杂的授权规则的场景。

工作原理

AuthorizationManager接口包含两个主要方法:AuthorizationDecision check和defaultAuthorizationDecision verify。
check方法用于传递授权决策所需的所有相关信息,并返回一个AuthorizationDecision对象,表示授权结果。
verify方法则在check方法之后调用,用于验证授权决策。如果访问被拒绝,将抛出AccessDeniedException异常。
在Spring Security中,AuthorizationManager是通过基于请求、基于方法和基于消息的授权组件来调用的,并负责做出最终的访问控制决策。

优势与应用

AuthorizationManager提供了更灵活和统一的授权机制,使得开发者可以更容易地定义和管理授权规则。
它支持多种授权方式,包括基于角色的授权、基于权限的授权以及基于表达式的授权等,满足了不同应用场景的需求。
通过AuthorizationManager,开发者可以实现细粒度的访问控制,提高应用程序的安全性和可维护性。

总结

综上所述,AuthorizationManager是Spring Security中一个重要的授权接口,它提供了灵活且统一的授权机制,使得开发者可以更容易地定义和管理授权规则。在实际应用中,开发者可以根据具体需求选择合适的AuthorizationManager实现类来定义授权规则,并实现细粒度的访问控制。

AuthorizationManager 和 AuthenticationManager 属于同级别接口,一个负责授权一个负责认证

AuthorizationManager和AuthenticationManager确实属于同级别的接口,它们各自在Spring Security框架中扮演着不可或缺的角色,但职责分明:一个负责授权(AuthorizationManager),另一个负责认证(AuthenticationManager)。

AuthenticationManager

AuthenticationManager是认证相关的核心接口,也是发起认证的出发点。在实际应用中,用户可能会使用多种方式进行登录,如用户名+密码、邮箱+密码、手机号码+密码等,甚至可能使用指纹等生物识别方式。AuthenticationManager一般不直接进行认证,而是依赖于其常用实现类ProviderManager,该类内部会维护一个列表,存放多种认证方式(即AuthenticationProvider)。当AuthenticationManager接收到认证请求时,它会依次调用这些提供者来验证用户的凭据。如果认证成功,Authentication对象会被存储在SecurityContextHolder中,以便后续的安全决策;如果认证失败,则会抛出AuthenticationException异常。

AuthorizationManager

AuthorizationManager则主要用于处理授权决策。在Spring Security中,授权通常涉及到确定用户是否可以访问特定的资源。AuthorizationManager提供了更灵活和统一的授权机制,使得开发者可以更容易地定义和管理授权规则。这些规则可以基于用户的认证状态、角色、权限等因素进行制定。当用户尝试访问受保护的资源时,AuthorizationManager会根据预设的规则进行决策,如果访问被允许,则用户可以继续操作;如果访问被拒绝,则会抛出AccessDeniedException异常。

总结

AuthorizationManager和AuthenticationManager虽然都是Spring Security框架中的核心接口,但它们的职责截然不同。AuthenticationManager主要负责用户的身份认证,确保用户是其所声称的人;而AuthorizationManager则负责基于用户的角色和权限来控制对资源的访问,确保用户只能访问其有权访问的资源。两者相互协作,共同维护了应用程序的安全性。

ObjectProvider

ObjectProvider<T> 是 Spring Framework 中的一个接口,主要用于获取 Spring 容器中的 bean 实例。它是 Spring 5 引入的,旨在提供更灵活和延迟加载的方式来访问 beans。与 ApplicationContext.getBean() 方法相比,ObjectProvider 提供了更丰富的功能,包括支持懒加载、条件检查等。

1. 定义

ObjectProvider<T> 接口位于 org.springframework.beans.factory.ObjectProvider 包中,它允许你以一种更加灵活和动态的方式获取 beans。该接口包含以下主要方法:

  • getIfAvailable():返回指定类型的 bean,如果没有可用的 bean,则返回 null。

  • getIfUnique():返回唯一类型的 bean,如果没有或有多个相同类型的 bean,则返回 null。

  • getObject():每次调用时都会返回一个新的实例(如果是原型 scoped 的 bean)。

  • stream():返回所有匹配类型的 beans 的流,可以进行进一步处理。

2. 使用场景

2.1 懒加载

使用 ObjectProvider 可以实现懒加载,这意味着只有在真正需要的时候才会创建对象。这对于资源密集型对象尤其有用。

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Component;

@Component
public class MyService {

    private final ObjectProvider<HeavyResource> heavyResourceProvider;

    public MyService(ObjectProvider<HeavyResource> heavyResourceProvider) {
        this.heavyResourceProvider = heavyResourceProvider;
    }

    public void doSomething() {
        HeavyResource resource = heavyResourceProvider.getIfAvailable();
        if (resource != null) {
            resource.performAction();
        }
    }
}
2.2 条件注入

通过 ObjectProvider,可以根据条件选择性地注入某个 bean。

@Component
public class ConditionalService {

    private final ObjectProvider<OptionalFeature> optionalFeatureProvider;

    public ConditionalService(ObjectProvider<OptionalFeature> optionalFeatureProvider) {
        this.optionalFeatureProvider = optionalFeatureProvider;
    }

    public void execute() {
        OptionalFeature feature = optionalFeatureProvider.getIfAvailable();
        if (feature != null) {
            feature.execute();
        } else {
            // 默认行为
        }
    }
}

3. 示例代码

下面是一个完整示例,演示如何使用 ObjectProvider 获取不同类型的 beans。

Bean 定义
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public HeavyResource heavyResource() {
        return new HeavyResource();
    }

    @Bean
    public OptionalFeature optionalFeature() {
        return new OptionalFeature();
    }
}
Service 类
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    private final ObjectProvider<HeavyResource> heavyResourceProvider;
    
    private final ObjectProvider<OptionalFeature> optionalFeature;

    public MyService(ObjectProvider<HeavyResource> heavyResource, 
                     ObjectProvider<OptionalFeature> optionalFeature) {
        this.heavyResource = heavyResource;
        this.optionalFeature = optionalFeature;
    }

    public void performTask() {
        HeavyResource resource = heavyResource.getIfAvailable();
        
        if (resource != null) {
            resource.performAction(); // 使用重资源
            
            OptionalFeature feature = optionalFeature.getIfAvailable();
            if (feature != null) {
                feature.execute(); // 可选特性执行
            }
        } else {
            System.out.println("No available resources.");
        }
   }
}

4. 总结

  • 灵活性:通过 ObjectProvider<T>,开发者能够以更灵活和动态的方式获取 Spring 管理的 beans。
  • 懒加载与条件注入:它支持懒加载和条件注入,使得应用程序更加高效,并且只在需要时才创建对象。
  • 流式 API 支持:通过流操作,可以对匹配类型进行批量处理,提高了代码简洁性。

总之,ObjectProvider<T> 是一个非常实用且强大的工具,在构建复杂和动态应用程序时极大地提高了灵活性和可维护性。

@Builder

@Builder注解是Lombok库提供的一个功能强大的注解,它主要用于自动生成构建器(Builder)模式的相关代码,从而简化对象的创建过程。以下是对@Builder注解的详细介绍及使用示例:

一、@Builder注解简介

Lombok是一个Java库,它通过注解来简化Java类的编写。@Builder注解是Lombok提供的一个注解,它可以为类自动生成一个构建器内部类,并生成相应的构建方法。这样,我们就可以通过链式调用的方式来设置对象的属性,并最终构建出对象实例,而无需手动编写繁琐的构造函数或setter方法。

二、@Builder注解的使用示例

以下是一个简单的示例,展示了如何使用@Builder注解来创建一个User类,并通过构建器来创建User对象:

import lombok.Builder;  
import lombok.Data;  
  
@Data  
@Builder  
public class User {  
    private String username;  
    private String email;  
    private int age;  
}  
  
// 使用构建器创建User对象  
User user = User.builder()  
    .username("John")  
    .email("john@example.com")  
    .age(25)  
    .build();

在这个示例中,我们首先在User类上添加了@Data和@Builder注解。@Data注解会自动为类生成toString()、equals()、hashCode()和getter/setter方法等常见方法。而@Builder注解则会自动生成一个包含所有属性的构建器方法。然后,我们通过调用User.builder()来获取构建器实例,并通过链式调用的方式来设置对象的属性。最后,我们调用build()方法来构建出User对象实例。

三、@Builder注解的属性

@Builder注解还支持一些属性来定制构建器的行为,例如:

  1. builderMethodName:指定创建内部静态类的方法名,默认值为“builder”。
  2. buildMethodName:指定静态类中创建实体类的方法名,默认值为“build”。
  3. builderClassName:指定内部静态的类名,默认创建的类名为外部类的类名+“Builder”。
  4. toBuilder:设置为true则可以根据这个类生成静态内部类Builder对象,然后可以根据这个builder对象来修改此类。默认为false。
  5. access:设置builderMethodName的访问权限修饰符,默认为“public”。
四、@Builder注解的注意事项

在使用@Builder注解之前,需要确保已在项目的构建工具(如Maven、Gradle)中添加了Lombok依赖,并在开发环境中安装了相应的插件以支持注解处理。
对于final字段,由于它们必须在对象创建时被初始化,因此不能通过构建器的setter方法来设置它们的值。但是,可以使用@Builder.Default注解来为final字段提供默认值。
当类中有多个构造函数时,Lombok会尝试使用最合适的构造函数来生成构建器代码。如果Lombok无法确定哪个构造函数是最合适的,或者需要更复杂的构建逻辑时,可能需要手动编写部分构建器代码或使用其他方式来创建对象。

五、@Singular注解的使用

在使用@Builder注解时,还可以结合@Singular注解来处理集合类型的字段。@Singular注解会为集合字段生成特殊的adder方法和clear方法,而不是简单的setter方法。这样,我们就可以方便地添加或删除集合中的元素,而无需替换整个集合。例如:

import lombok.Builder;  
import lombok.Data;  
import lombok.Singular;  
  
@Data  
@Builder  
public class User {  
    private String username;  
    private String email;  
    @Singular  
    private List<String> hobbies;  
}  
  
// 使用构建器创建User对象,并添加hobbies  
User user = User.builder()  
    .username("John")  
    .email("john@example.com")  
    .hobby("Reading")  
    .hobby("Swimming")  
    .build();

在这个示例中,我们使用了@Singular注解来修饰hobbies字段。这样,Lombok就会为hobbies字段生成特殊的adder方法(如hobby()),而不是简单的setter方法。我们就可以通过链式调用的方式来添加hobbies元素了。

综上所述,@Builder注解是Lombok库提供的一个非常有用的注解,它可以大大简化对象的创建过程并提高代码的可读性和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路上阡陌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值