Spring 不会在 XML-RPC 控制器下初始化服务中的自动装配 DAO bean

Posted

技术标签:

【中文标题】Spring 不会在 XML-RPC 控制器下初始化服务中的自动装配 DAO bean【英文标题】:Spring doesn't initialize autowired DAO bean in service under XML-RPC controller 【发布时间】:2017-05-10 10:49:05 【问题描述】:

伙计们。我有一个问题要问你。我正在实现登录应用程序,该应用程序具有用于解析请求和服务(实现 Spring Security UserDetails 服务)的 XML-RPC 控制器以实现登录。用户登录的数据存储在嵌入式 mongodb 数据库中,DAO 可以访问它。 因此,当我登录时,在 dao 的帮助下,服务会为用户访问数据库。然而,在调用服务的那一刻,DAO 没有被初始化(为空)。我究竟做错了什么? 我的控制器类:

@Controller
public class XmlRpcController 
private XmlRpcServletServer server;

@Autowired
private UserService userService;

@PostConstruct
public void init() throws XmlRpcException 
    try 
        System.out.println("Starting the server on port 8090");
        XmlRpcServerConfigImpl config= new XmlRpcServerConfigImpl();

        server=new XmlRpcServletServer();
        server.setConfig(config);

        PropertyHandlerMapping xmlRpcHandlerMapping=new PropertyHandlerMapping();
        xmlRpcHandlerMapping.load(Thread.currentThread().getContextClassLoader(),"xmlrpc.properties");
        server.setHandlerMapping(xmlRpcHandlerMapping);
        System.out.println("The server started successfully.");

     catch (Exception e) 
        System.err.println("Server Error: " + e);
        throw new XmlRpcException(e.getMessage());
    


@RequestMapping("xmlrpc")
public  void serve(HttpServletRequest request, HttpServletResponse response) throws XmlRpcException 
    try 
        server.execute(request,response);
     catch (Exception e) 
        throw new XmlRpcException(e.getMessage(), e);
    


W xmlrpc.properties 服务被定义用于实现请求:

service=org.vkalashnykov.service.UserService

服务:

@Service
public class UserService implements UserDetailsService
    @Autowired
    private UserDAO userDAO;

@Override
    public UserDetails loadUserByUsername(@NotNull String username) throws UsernameNotFoundException 
        return userDAO.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("user "+username+ " was not found"));  // Here the userDAO is null
    

    public String login(@NotNull String username, @NotNull String password)
        User user=(User)loadUserByUsername(username);
        if (user!=null && user.getPassword().equals(new BCryptPasswordEncoder().encode(password)))
            return Statuses.SUCCESS.name();
        else
            return Statuses.ERROR.name();
    

道:

 @Component
public class UserDAO

@Autowired
MongoTemplate mongoTemplate;

public Optional<User> findByUsername(@NotNull String username)
    return Optional.ofNullable(mongoTemplate.findOne(
            query(
                    where(UserField.USER_NAME.getField()).is(username)),
                    User.class));


public void save(User user)
    mongoTemplate.save(user);



Spring 安全配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
private UserService userService;

@Bean
public BCryptPasswordEncoder getBCryptPasswordEncoder()
    return new BCryptPasswordEncoder();


@Override
protected void configure(HttpSecurity http) throws Exception 
    http
            .authorizeRequests()
            .antMatchers("/xmlrpc").permitAll()
            .and()
            .csrf().disable();


@Autowired
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception 
    auth.userDetailsService(userService).passwordEncoder(getBCryptPasswordEncoder());


在客户端有一个应用程序将用户名和密码发送到服务器进行登录:

@FXML
private TextField login;

@FXML
private TextField password;

private  String configuration="xmlrpc";

private final String serverUrl="http://localhost:8090/xmlrpc";

private final XmlRpcClient xmlRpcClient=new XmlRpcClient();

public Controller() throws Exception 
    final XmlRpcClientConfigImpl config=new XmlRpcClientConfigImpl();
    try 
        System.out.println("Trying connect to server "+serverUrl);
        config.setServerURL(new URL(serverUrl));
     catch (MalformedURLException e) 
        System.err.println("Server "+serverUrl+" not found.");
        e.printStackTrace();
        errorLabel.setText("Server not found.");
        throw new Exception("Server not found.");
    
    xmlRpcClient.setConfig(config);
    System.out.println("Connected to server: "+serverUrl);

【问题讨论】:

所以你期望一个不由spring管理的类实例被spring注入和控制......你的RPC框架控制的是实例而不是Spring,所以不会自动装配任何东西。 有没有办法使用 RPC 管理 Spring bean? 【参考方案1】:

我通过以下方式更改了 Apache XML-RPC 框架的控制器配置:

@Controller
public class XmlRpcController 
    private XmlRpcServletServer server;
  @Autowired
  UserService userService;

  @PostConstruct
  public void init() throws XmlRpcException 
    try 
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
        System.out.println("Starting the server on port 8090");
        XmlRpcServerConfigImpl config= new XmlRpcServerConfigImpl();

        server=new XmlRpcServletServer();
        server.setConfig(config);

        PropertyHandlerMapping xmlRpcHandlerMapping=new PropertyHandlerMapping();
        xmlRpcHandlerMapping.setRequestProcessorFactoryFactory(pClass->pRequest->userService);
        xmlRpcHandlerMapping.addHandler(UserService.class.getSimpleName(),UserService.class);
        XmlRpcSystemImpl.addSystemHandler(xmlRpcHandlerMapping);
        server.setHandlerMapping(xmlRpcHandlerMapping);
        System.out.println("The server started successfully.");

     catch (Exception e) 
        System.err.println("Server Error: " + e);
        throw new XmlRpcException(e.getMessage());
    
  

似乎可以工作,现在 DAO 已完全初始化。谢谢。

【讨论】:

以上是关于Spring 不会在 XML-RPC 控制器下初始化服务中的自动装配 DAO bean的主要内容,如果未能解决你的问题,请参考以下文章

Spring--简记

UIViewController 不会弹出

内存数据库H2中的Spring Boot在初始化时不会从文件中加载数据

Spring IoC容器初始化过程

Spring初始化多个数据库

启用组件扫描时,Spring 不会中止 bean 初始化时的引导错误?