启动时从数据库初始化SpringWeb应用程序
Spring 3.1+Tomcat 我这里有一个设计问题: 在数据库中指定了一组类别。这些类别可以被认为是全球性的,因为它们可以在整个webapp中使用。我想做的是在服务器启动时阅读这些类别,并用Java填充某种类型的集合。在启动时只需从数据库中读取一次,就可以将其视为初始化类型。 我可以想到两个选择: 1) 我应该使用非延迟初始化的bean吗 或 2) 修改web.xml启动时从数据库初始化SpringWeb应用程序,spring,jakarta-ee,spring-mvc,Spring,Jakarta Ee,Spring Mvc,Spring 3.1+Tomcat 我这里有一个设计问题: 在数据库中指定了一组类别。这些类别可以被认为是全球性的,因为它们可以在整个webapp中使用。我想做的是在服务器启动时阅读这些类别,并用Java填充某种类型的集合。在启动时只需从数据库中读取一次,就可以将其视为初始化类型。 我可以想到两个选择: 1) 我应该使用非延迟初始化的bean吗 或 2) 修改web.xml 我真的不确定什么是首选方法,任何关于如何执行建议的操作的说明都将不胜感激。谢谢 您提供的选项是最常用的: 使用带有@Pos
我真的不确定什么是首选方法,任何关于如何执行建议的操作的说明都将不胜感激。谢谢 您提供的选项是最常用的:
@PostConstruct
注释的方法的单例非惰性bean(但要注意@Transactional
)。使用这样的初始化例程可以有几个beanorg.springframework.web.context.ContextLoaderListener
并在web.xml
中使用它。我发现这个解决方案不那么优雅,而且还推广了糟糕的编程风格(通过调用super
来扩展以增强基类)我使用了一个
控制器
,它实现了ServletContextAware
和初始化bean
。控制器在应用程序启动时运行,我在AfterPropertieSet
方法中运行参数加载代码,以便正确注入ServletContext。然后,这些属性可以从ServletContext在整个应用程序中使用。代码:
@Controller
public class ParameterizationController implements ServletContextAware , InitializingBean {
protected final Log logger = LogFactory.getLog(getClass());
public static final String PARAMETERS_SC_ATTRIBUTE = "allProps";
private ServletContext sc;
public ParameterizationController() {
logger.info("inside ParameterizationController...");
}
@Autowired
private SomeService someService;
@RequestMapping("/loadparams.do")
public String formHandler(
Model model) {
String forwardValue = "/loadparams";
// an admin can also call this page to reload props at runtime
this.sc.setAttribute(PARAMETERS_SC_ATTRIBUTE, loadProperties());
return forwardValue;
}
private HashMap<Integer, HashMap<String, String>> loadProperties() {
return someService.loadProperties();
}
// makes sure the SC is injected for use
public void setServletContext(ServletContext sc) {
this.sc = sc;
}
// only runs after all injections have been completed
public void afterPropertiesSet() throws Exception {
this.sc.setAttribute(PARAMETERS_SC_ATTRIBUTE, loadProperties());
}
@控制器
公共类ParameterizationController实现ServletContextAware,初始化bean{
受保护的最终日志记录器=LogFactory.getLog(getClass());
公共静态最终字符串参数\u SC\u ATTRIBUTE=“allProps”;
私人服务;
公共参数化控制器(){
logger.info(“内部参数化控制器…”);
}
@自动连线
私人服务;
@RequestMapping(“/loadparams.do”)
公共字符串formHandler(
(模型){
String forwardValue=“/loadparams”;
//管理员也可以调用此页面在运行时重新加载道具
this.sc.setAttribute(PARAMETERS_sc_属性,loadProperties());
返回值;
}
私有HashMap loadProperties(){
返回someService.loadProperties();
}
//确保注入SC以供使用
公共void setServletContext(ServletContext sc){
这个.sc=sc;
}
//仅在完成所有注射后运行
public void afterPropertieSet()引发异常{
this.sc.setAttribute(PARAMETERS_sc_属性,loadProperties());
}
我使用了方法1,但我没有使用PostContrust,而是在bean定义中使用了init Method属性,这似乎是我所需要的。是的,这是完全相同的。事实上,init Method
入侵性最小(您也可以实现初始化bean
),因为它完全不依赖于您的bean。