spring security jpa boot 注入失败

spring boot 3.0.4 整合 jpa 和 security,在UserDetailsService实现类中,无法注入JpaRepository实现类。比如

// jpa
import com.example.securitytest.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User,Integer> {
    @Query("from User where username = :username")
    User findUserByUsername(String username);
}

// security 
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
  private UserRepository userRepository;
  private RoleRepository roleRepository;
  private UserRoleRepository userRoleRepository;
  //  @Resource private UserRoleRepository userRoleRepository;  注入也为空
  @Autowired // 注入也为空
  public UserDetailsServiceImpl(UserRepository userRepository, RoleRepository roleRepository,
      UserRoleRepository userRoleRepository) {
    this.userRepository = userRepository;
    this.roleRepository = roleRepository;
    this.userRoleRepository = userRoleRepository;
  }
....
}

访问mapping后,跳转到默认的security登录页后,输入账号密码后

img

网上的说法的security的执行优先于bean的实例化。自己在学习阶段实在不知道怎么才可以注入进来。忘大家帮帮忙

项目源代码打包下载

@Autowired
UserRepository userRepository;

JPA配置提供一下

在您的代码中,您使用了构造函数注入来初始化 UserDetailsService 的实现类。这是推荐的做法,因为它可以确保您的依赖项在对象创建时被正确注入。但是,要确保 Spring Boot 正确识别并创建这些 bean,请检查以下几点:
1.确保您的 Spring Boot 项目包含了正确的依赖。在 pom.xml 文件中,您需要包含以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>


2.确保您的 @SpringBootApplication 类位于一个包含所有其他类(包括 UserRepository 和 UserDetailsServiceImpl)的父包中。这样,Spring Boot 可以自动发现并注册您的组件。如果需要,您可以使用 @ComponentScan 注解来指定包扫描的路径。
3.如果您的项目中包含多个数据源,请使用 @Primary @Qualifier 注解来指定正确的数据源。
在大多数情况下,按照以上步骤检查并配置您的项目后,应该可以正确注入 UserRepository、RoleRepository 和 UserRoleRepository。
如果仍然无法注入依赖项,请尝试在 UserDetailsServiceImpl 类上添加 @Transactional 注解,以确保事务正确绑定到您的服务:

import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class UserDetailsServiceImpl implements UserDetailsService {
    // ...
}


如果问题仍然存在,请提供更多关于项目结构和配置的信息,以便我能更准确地帮助您解决问题。

在Spring Boot中,如果您要使用JPA和Spring Security,可以按照以下步骤进行整合:

在pom.xml文件中添加JPA和Spring Security的依赖:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

2、创建一个实体类,使用JPA注解标注要映射的数据表和字段,例如:

@Entity
@Table(name = "user")
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;
    
    @Column(name = "username")
    private String username;
    
    @Column(name = "password")
    private String password;
    
    // getter和setter方法
}

3、创建一个JpaRepository接口,继承JpaRepository,并提供需要的查询方法。例如:


```java

@Repository
public interface UserRepository extends JpaRepository<User, Integer> {

    User findByUsername(String username);
}

4、创建一个实现UserDetailsService接口的类,用来在登录时获取用户信息。在该类中注入UserRepository接口。例如:

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User not found");
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
                new ArrayList<>());
    }
}

在上述例子中,我们使用了@Autowired注解将UserRepository接口注入到了UserDetailsServiceImpl类中。如果注入失败,可以检查是否在UserDetailsServiceImpl类上添加了@Service注解,是否在UserRepository类上添加了@Repository注解。

希望以上解决方案对您有所帮助。

懒加载试试,解决这类问题最简单的一种方案

添加@Lazy注解来将你的UserDetailsServiceImpl类标记为延迟初始化试试看

@Service
@Lazy
public class UserDetailsServiceImpl implements UserDetailsService {
  // ...
}