【问题标题】:Unsatisfied dependency expressed through field 'userTokenService'通过字段“userTokenService”表示的不满足的依赖关系
【发布时间】:2019-08-03 02:11:01
【问题描述】:

homeControler

    package com.book.controller;

import java.util.Locale;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.book.entity.User;
import com.book.entity.security.UserToken;
import com.book.entity.security.service.SecurityService;
import com.book.entity.security.service.UserTokenService;

@Controller
public class HomeController {
    @Autowired
    private UserTokenService userTokenService;
    @Autowired
    private SecurityService securityService;

    @RequestMapping("/")
    public String getHome() {
        return "index";
    }

    @RequestMapping("/myaccount")
    public String myAccount() {
        return "myAccount";
    }

    @RequestMapping("/login")
    public String login(Model model) {
        model.addAttribute("classActiveLogin", true);
        return "myAccount";
    }

    @RequestMapping("/forgetPassword")
    public String forgetPassword(Model model) {
        model.addAttribute("classActiveForgetPassword", true);
        return "myAccount";
    }

    @RequestMapping("/newUser")
    public String newUser(Locale locale, @RequestParam("token") String token, Model model) {

        UserToken userToken = userTokenService.getPasswordResetToken(token);
        if (userToken == null) {
            String msg = "Invalid Token";
            model.addAttribute("msg", msg);
            return "redirect:/badRequest";
        }

        User user = userToken.getUser();
        String username = user.getUsername();

        UserDetails userDetails = securityService.loadUserByUsername(username);

        Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(),
                userDetails.getAuthorities());

        SecurityContextHolder.getContext().setAuthentication(authentication);

        model.addAttribute("classActiveEdit", true);
        return "myProfile";
    }
}

用户令牌

package com.book.entity.security;

import java.util.Calendar;
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;

import com.book.entity.User;

@Entity
public class UserToken {

    private static final int EXPIRATION = 60 * 24;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String token;

    @OneToOne(targetEntity = User.class, fetch = FetchType.EAGER)
    @JoinColumn(nullable=false, name="user_id")
    private User user;

    private Date expiryDate;

    public UserToken(final String token, final User user) {
        super ();

        this.token = token;
        this.user = user;
        this.expiryDate = calculateExpiryDate(EXPIRATION);
    }

    private Date calculateExpiryDate (final int expiryTimeInMinutes) {
        final Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(new Date().getTime());
        cal.add(Calendar.MINUTE, expiryTimeInMinutes);
        return new Date(cal.getTime().getTime());
    }

    public void updateToken(final String token) {
        this.token = token;
        this.expiryDate = calculateExpiryDate(EXPIRATION);
    }

    @Override
    public String toString() {
        return "P_Token [id=" + id + ", token=" + token + ", user=" + user + ", expiryDate=" + expiryDate + "]";
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Date getExpiryDate() {
        return expiryDate;
    }

    public void setExpiryDate(Date expiryDate) {
        this.expiryDate = expiryDate;
    }

    public static int getExpiration() {
        return EXPIRATION;
    }



}

用户令牌服务

package com.book.entity.security.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.book.entity.User;
import com.book.entity.security.UserToken;
import com.book.entity.security.repo.PasswordResetRepo;
import com.book.entity.security.repo.UserTokenRepo;

@Service("userTokenService")
public class UserTokenService implements UserTokenRepo{

    @Autowired
    private PasswordResetRepo repo;

    @Override
    public UserToken getPasswordResetToken(final String token) {
        return repo.findByToken(token);
    }

    @Override
    public void createPasswordResetTokenForUser(final User user, final String token) {
        final UserToken myToken = new UserToken(token, user);
        repo.save(myToken);
    }
}

用户令牌回购

package com.book.entity.security.repo;

import com.book.entity.User;
import com.book.entity.security.UserToken;

public interface UserTokenRepo {

    UserToken getPasswordResetToken(final String token);

    void createPasswordResetTokenForUser(final User user, final String token);

}

安全服务

package com.book.entity.security.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.book.entity.User;
import com.book.entity.security.repo.SecurityUserRepository;

@Service
public class SecurityService implements UserDetailsService {
    @Autowired
    private SecurityUserRepository securityUserRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = securityUserRepository.findByUsername(username);

        if (null == user) {
            throw new UsernameNotFoundException("Username not found");
        }

        return user;
    }
}

密码重置回购

package com.book.entity.security.repo;

import java.util.Date;
import java.util.stream.Stream;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import com.book.entity.User;
import com.book.entity.security.UserToken;


public interface PasswordResetRepo extends JpaRepository<UserToken, Long > {

    UserToken findByToken(String token);

    UserToken findByUser(User user);

    Stream<UserToken> findAllByExpiryDateLessThan(Date now);

    @Modifying
    @Query("delete from P_Token t where t.expirydate <= ?1")
    void deleteAllExpiredSince(Date now);
}

错误:--> org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为“homeController”的bean时出错:通过字段“userTokenService”表示的依赖关系不满足;嵌套异常是 org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为“userTokenService”的 bean 时出错:通过字段“repo”表示的依赖关系不满足;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“passwordResetRepo”的 bean 时出错:调用 init 方法失败;嵌套异常是 java.lang.NoClassDefFoundError: antlr/RecognitionException

【问题讨论】:

  • 能否提供 PasswordResetRepo 的代码?是否标记为组件?
  • 它是一个界面

标签: spring spring-boot spring-mvc spring-security


【解决方案1】:

查看堆栈跟踪。问题是:spring IoC 容器无法创建homeController bean;因为容器未能创建userTokenService bean;那是因为容器无法使用java.lang.NoClassDefFoundError 创建passwordResetRepo bean。

在您的配置文件中添加以下内容应该可以解决您的问题:

<jpa:repositories base-package="com.book.entity.security.repo" />

当您使用 Spring Boot 时,请在 Accessing Data with JPA 上查看本指南。

来自上述指南:

默认情况下,Spring Boot 将启用 JPA 存储库支持并查看 在 @SpringBootApplication 所在的包(及其子包)中 位于。如果您的配置有JPA 存储库接口 位于包中的定义不可见,您可以指出 使用@EnableJpaRepositories 及其类型安全的替代包 basePackageClasses=MyRepository.class参数。

【讨论】:

  • 先生,但我正在使用 Spring Boot,而且我是春季的新手……请给我宝贵的建议。非常感谢先生。请告诉我项目中的配置文件是什么?
  • @JahadulRakib,我已根据您的评论更新了答案。请看一看。
  • 非常感谢先生......当我看到你留在达卡时,我请求你在 fb 中。
【解决方案2】:

可能问题在于HomeController 波纹管代码:

@Autowired
    private UserTokenService userTokenService;

将此代码替换为以下代码:

@Autowired
        private UserTokenRepo userTokenService;

您的主要错误部分是:

通过字段'repo'表达的不满足的依赖关系;嵌套的 例外是 org.springframework.beans.factory.BeanCreationException: 创建名为“passwordResetRepo”的 bean 时出错:调用 init 方法失败;嵌套异常是 java.lang.NoClassDefFoundError: antlr/RecognitionException

这里创建bean失败passwordResetRepo原因antlr/RecognitionException

其解决方法是 java.lang.ClassNotFoundException: antlr.RecognitionException 显示 antlr lib 缺失

添加它并完成:)

您可以尝试添加以下依赖项。它将解决您的问题。

<dependency>
 <groupId>org.antlr</groupId>
 <artifactId>antlr-complete</artifactId>
 <version>3.5.2</version>
</dependency>  

另一个可能的考虑:

请检查 PasswordResetRepo 存储库上的所有 JPA 查询。有时,如果查询与实体变量名称不匹配,则 Spring 无法为该存储库创建 bean

希望这能解决您的问题。

谢谢:)

【讨论】:

    猜你喜欢
    • 2019-08-14
    • 2019-11-09
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 2022-11-13
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多