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的主要内容,如果未能解决你的问题,请参考以下文章