我有一个完全工作的弹簧和vaadin应用程序基于弹簧启动。现在已经修改了应用程序类以创建自定义servlet,因此我可以在项目中同时使用touchkit和spring。
我一直在关注这个git项目来执行此操作:git project example
public class SmartenderApplication {
public static void main(String[] args) {
SpringApplication.run(SmartenderApplication.class, args);
}
@Bean
public VaadinServlet vaadinServlet() {
return new SpringAwareTouchKitServlet();
}}
我修改了自定义servlet以遵循vaadin文档,使用UI提供程序在touchkit UI和browswer后备UI之间进行选择
public class SpringAwareTouchKitServlet extends SpringVaadinServlet {
TouchKitSettings touchKitSettings;
MyUIProvider prov = new MyUIProvider();
@Override
protected void servletInitialized() throws ServletException {
super.servletInitialized();
getService().addSessionInitListener(
new SessionInitListener() {
@Override
public void sessionInit(SessionInitEvent event)
throws ServiceException {
event.getSession().addUIProvider(prov);
}
});
touchKitSettings = new TouchKitSettings(getService());
}
}
class MyUIProvider extends UIProvider {
@Override
public Class<? extends UI>
getUIClass(UIClassSelectionEvent event) {
String ua = event.getRequest()
.getHeader("user-agent").toLowerCase();
if ( ua.toLowerCase().contains("ios")) {
return myTouchkitUI.class;
} else {
return myUI.class;
}
}
}
当我不调用此部分代码来选择UI提供程序时,我的应用程序正常工作。但它总会转到touchkit UI。 :
getService().addSessionInitListener(
new SessionInitListener() {
@Override
public void sessionInit(SessionInitEvent event)
throws ServiceException {
event.getSession().addUIProvider(prov);
}
});
我的问题是,虽然它会在开始通过所选UI代码进行选择之后选择返回哪个UI类,但它会传回最初通过spring自动装配的空对象。当我不选择UI而只是选择触摸套件时,我认为它必须在我的UI提供商选择代码的某个地方停止Spring功能允许我的类自动装配等等?
答案 0 :(得分:1)
嗯,UIProvider应该管理UI实例。此外,既然您正在使用Spring(Boot或不使用),它应该从Spring上下文中检索bean,而不是在必要时自己创建实例:
UIProvider
/ DefaultUIProvider
:
public UI createInstance(UICreateEvent event) {
try {
return event.getUIClass().newInstance();
} catch (InstantiationException e) {
throw new RuntimeException("Could not instantiate UI class", e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Could not access UI class", e);
}
}
因此,我要说的是,不应该扩展简单的UIProvider
(或者更确切地说是DefaultUIProvider
),而应该扩展SpringUIProvider
,从应用程序的Spring上下文中检索实例,所以自动化将再次发生。
@Override
public UI createInstance(UICreateEvent event) {
final Class<UIID> key = UIID.class;
final UIID identifier = new UIID(event);
CurrentInstance.set(key, identifier);
try {
logger.debug(
"Creating a new UI bean of class [{}] with identifier [{}]",
event.getUIClass().getCanonicalName(), identifier);
return webApplicationContext.getBean(event.getUIClass());
} finally {
CurrentInstance.set(key, null);
}
}