如何初始化界面中的对象?

时间:2017-12-02 09:34:12

标签: java spring

我有这个MovieService.java:

@Service
public class MovieService implements MovieInterface {

    @Autowired 
    private MovieRepository movieRepository;

    @Autowired 
    private UserRepository userRepository;

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    JwtUser user = (JwtUser)authentication.getPrincipal();
    User current_user = userRepository.findOne(user.getId());   

    @Override 
    public Movie createMovie(Movie movie) {

        current_user.addMovie(movie);
        userRepository.save(current_user);

        return movie;
    }
}

这是我编译代码时遇到的错误:

  

org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为'movieController'的bean时出错:通过字段'movieService'表示的不满意的依赖关系;嵌套异常是org.springframework.beans.factory.BeanCreationException:在文件[C:\ Users \ alucardu \ Documents \ projects \ movieseat \ backend \ target \ classes \ com \ movieseat \ services \]中定义名称为'movieService'的bean时出错MovieService.class]:bean的实例化失败;嵌套异常是org.springframework.beans.BeanInstantiationException:无法实例化[com.movi​​eseat.services.MovieService]:构造函数抛出异常;嵌套异常是java.lang.NullPointerException

authenticationusercurrent_user属性移动到createMovie方法时,此问题已得到解决。但是我想在多个方法中使用current_user,所以我想将它添加为类成员。

我还实现了一个MovieInterface:

package com.movieseat.interfaces;

// Java imports
import java.util.List;
import com.movieseat.model.security.User;
// Project imports
import com.movieseat.models.Movie;
import com.movieseat.security.JwtUser;
import org.springframework.security.core.Authentication;

public interface MovieInterface {
    List<Movie> getAllmovies();
    Movie createMovie(Movie movie);
    void deleteMovie(Integer id);
}

所以我想也许代码不能编译,因为在接口中没有定义属性authenticationusercurrent_user。虽然我希望有类似的错误输出。当我将属性添加到界面时:

public interface MovieInterface {
    Authentication authentication;
    JwtUser user;
    User current_user;
    List<Movie> getAllmovies();
    Movie createMovie(Movie movie);
    void deleteMovie(Integer id);
}

我收到消息:

  

空白的最终字段验证可能尚未初始化

     

空白的最终字段用户可能尚未初始化

     

空白的最终字段current_user可能尚未初始化

此消息有意义,因为接口期望字段为final。而这些领域没有任何价值。所以我的问题是,我可以在界面中标记一个不是最终的字段吗?如果我必须初始化字段的值,我需要使用什么?

我知道你初始化一个字段String name = "name";但这些属性是对象。

User current_user = {};
  

无法从Object []转换为User

2 个答案:

答案 0 :(得分:3)

您的服务是一个bean,特别是它是一个单例。这意味着您的应用程序中只有一个此服务实例。

但它可能会被不同的用户调用。因此,您必须使用createMovie方法获取当前用户(您已将其命名为当前用户!)。

当您尝试在PostConstruct方法中初始化这些字段时,您不会拥有SecurityContext并且您不会拥有主体。如果您在服务实例中保留有关当前用户的信息,那么无论他们来自何处,都将代表这一个用户进行所有呼叫。

所以最好的方法是创建一个方法:

private getUser() {
  Authentication authentication = 
  SecurityContextHolder.getContext().getAuthentication();
  JwtUser user = (JwtUser)authentication.getPrincipal();
  User current_user = userRepository.findOne(user.getId());   
  return current_user;
}

并从您的不同方法中调用它。

答案 1 :(得分:1)

你的班级是一个豆子。这意味着,所有@Autowired字段都将从其他人(Spring或CDI)设置。问题是什么时候?您可能将bean A与自动连接的bean B作为属性,反之亦然。您需要等待,直到所有属性都已自动连线。您尝试在对象创建期间使用userRepository。那太早了。 Spring必须创建Java对象(没有办法解决这个问题),但之后会自动进行自动装配。但是通过依赖注入,如果使用@PostConstruct注释方法,则会在设置所有属性时告知您。

@PostConstruct
public void init(){
    // it is safe now to use user repository, because it is not null anymore
}