Spring的@Bean注解小总结

之前写的一个Spring Security的配置里面的@Bean总结

package com.manong.config.security;

import com.manong.config.security.filter.CheckTokenFilter;
import com.manong.config.security.handler.AnonymousAuthenticationHandler;
import com.manong.config.security.handler.CustomerAccessDeniedHandler;
import com.manong.config.security.handler.LoginFailureHandler;
import com.manong.config.security.handler.LoginSuccessHandler;
import com.manong.config.security.service.CustomerUserDetailsService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

@Configuration
@EnableWebSecurity //启用 Spring Security 的 Web 安全支持。
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Resource
    //处理登录成功的逻辑
    private LoginSuccessHandler loginSuccessHandler;
    @Resource
    //处理登录失败的逻辑
    private LoginFailureHandler loginFailureHandler;
    @Resource
    //处理匿名用户无权限访问的情况
    private AnonymousAuthenticationHandler anonymousAuthenticationHandler;
    @Resource
    //处理已认证用户无权限访问的情况
    private CustomerAccessDeniedHandler customerAccessDeniedHandler;

    @Resource
    //定义的用户详细信息服务,用于加载用户信息
    private CustomerUserDetailsService customerUserDetailsService;

    @Resource
    //自定义的过滤器,用于检查 JWT 令牌
    private CheckTokenFilter checkTokenFilter;

    /**
     * 注入加密类
     * @return
     */
    @Bean  //标记该方法返回的对象为一个 Bean,由 Spring 管理
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();//用于对密码进行加密和解密,提高安全性
    }

    /**
     * 处理登录认证
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //登录前进行过滤
        http.addFilterBefore(checkTokenFilter, UsernamePasswordAuthenticationFilter.class);
        //登录过程处理
        http
                .formLogin()//表单认证
                .loginProcessingUrl("/api/user/login")//登录请求url地址
                .successHandler(loginSuccessHandler)//认证成功处理器
                .failureHandler(loginFailureHandler)//认证失败处理器
                .and()
                .csrf().disable()  //禁用 CSRF 保护,适用于无状态的 API
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)//设置会话管理策略为无状态( Stateless ),不创建会话
                .and()
                .authorizeRequests()//开始配置授权请求。
                .antMatchers("/api/user/login").permitAll()//登录请求放行不进行拦截 允许所有用户访问 /api/user/login 路径
                .anyRequest().authenticated()
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(anonymousAuthenticationHandler)   //匿名无权限访问
                .accessDeniedHandler(customerAccessDeniedHandler)  //认证用户无权限访问
                .and()
                .cors();//启用 CORS(跨域资源共享)支持
    }

    /**
     * 配置认证处理器
     * @param auth
     * @throws Exception
     */
    /*
    当用户提交登录请求时,Spring Security 会使用这个密码编码器对用户输入的密码进行编码,
    并与数据库中存储的编码后的密码进行比较,以验证用户身份。
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(customerUserDetailsService)
                .passwordEncoder(passwordEncoder());
    }
}

@Bean 注解在 Spring 框架中用于声明一个方法将返回一个对象,并且该对象将被注册为 Spring 容器中的一个 Bean。这意味着 Spring 容器将管理该对象的生命周期,并且可以在需要的地方自动注入该 Bean。

为什么要在 passwordEncoder 方法上使用 @Bean 注解?

  1. 注册为 Spring Bean

    • 使用 @Bean 注解后,Spring 容器会将 passwordEncoder 方法返回的 BCryptPasswordEncoder 实例注册为一个 Bean。这意味着你可以在其他地方通过依赖注入(DI)来使用这个 BCryptPasswordEncoder 实例。
  2. 依赖注入

    • 通过将 BCryptPasswordEncoder 注册为一个 Bean,你可以在其他类中通过 @Autowired 注解自动注入它,而不需要手动创建实例。例如,在 SpringSecurityConfig 类中,你可以这样注入 PasswordEncoder

      @Autowired
      private PasswordEncoder passwordEncoder;
  3. 单例模式

    • 默认情况下,Spring 容器会以单例模式管理 @Bean 注解的方法返回的对象。这意味着在整个应用中只会有一个 BCryptPasswordEncoder 实例,从而节省内存并提高性能
  4. 配置灵活性

    • 使用 @Bean 注解可以让你在配置类中灵活地管理和配置 Bean。例如,你可以在方法中添加额外的配置逻辑,而不仅仅是简单地返回一个对象。
@Configuration
public class SecurityConfig {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        // 创建一个内存中的用户详情服务
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("user")
                .password(passwordEncoder().encode("password"))
                .roles("USER")
                .build());
        return manager;
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests(authorize -> authorize
                .antMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
            )
            .formLogin(formLogin -> formLogin
                .loginPage("/login")
                .permitAll()
            )
            .logout(logout -> logout
                .permitAll()
            );
        return http.build();
    }
}
  1. passwordEncoder 方法

    • 使用 @Bean 注解,将 BCryptPasswordEncoder 实例注册为一个 Bean。
    • 这个 Bean 可以在其他地方通过 @Autowired 注解自动注入。
  2. userDetailsService 方法

    • 使用 @Bean 注解,将 InMemoryUserDetailsManager 实例注册为一个 Bean。
    • 在创建用户时,使用 passwordEncoder().encode("password") 方法对密码进行编码。
  3. filterChain 方法

    • 使用 @Bean 注解,将 SecurityFilterChain 实例注册为一个 Bean。
    • 配置了 HTTP 安全规则,包括授权请求、表单登录和注销等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值