Spring 3.1 + Tomcat
我在这里有一些设计问题:
在数据库中指定了一组类别。这些类别可以被认为是全局的,因为它们可以在整个webapp中使用。我想要做的是在服务器启动时阅读这些类别,并在Java中填充某种类型的集合。在启动时只需要从数据库中读取一次,将其视为一种初始化。
我能想到的两个选择:
1)我应该使用非懒惰的初始化bean吗?
或
2)修改web.xml?
我不确定首选方法是什么,并且非常感谢任何有关如何执行推荐的说明。谢谢!
答案 0 :(得分:4)
您提供的选项最常用:
使用带有@PostConstruct
注释方法的单例非懒惰bean(但请注意@Transactional
might not work)。你可以拥有几个具有这种初始化例程的bean。
扩展org.springframework.web.context.ContextLoaderListener
并在web.xml
中使用它。我发现这个解决方案不那么优雅,并且还促进了错误的编程风格(通过调用super
扩展以增强基类)
答案 1 :(得分:3)
我使用Controller
来实现ServletContextAware
和InitializingBean
。控制器在app启动时运行,我在afterPropertiesSet
方法中运行参数加载代码,以便正确注入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());
}