在 Tomcat 6.0.18 中启动我的 web 应用程序时,我仅使用初始化系统所需的内容(即目前的数据库迁移)来引导 Spring。 在迁移成功完成之前,我不希望加载系统的任何部分。 这可以防止其他 bean 在操作甚至实例化之前必须等待迁移完成。
我有一个startup-appcontext.xml配置了一个dbMigrationDAO,一个startupManager,它是一个 ThreadPoolExecutor,最后是一个 FullSystemLauch bean。 我通过 setter 注入将配置位置列表传递给 FullSystemLaunch bean。 FullSystemLaunch bean 实现 ServletContextAware,获取对当前 WebApplicationContext 因此我可以有一个 ConfigurableListableBeanFactory. 不幸的是,这个bean工厂isConfigurationFrozen()返回true,所以通过调用beanFactory.setConfigLocations(configLocations)没有效果。
我可以完成这个任务吗?还是 Spring 阻止我这样做,因为它有点不寻常? 理解起来似乎很有道理,但也有点危险。 是的,我愿意清除当前上下文,因为初始化完成后不需要当前加载的单例。
感谢您的帮助。
Upon starting my webapp within Tomcat 6.0.18, I bootstrap Spring with only what is necessary to initialize the system -- namely, for now, database migrations. I do not want any part of the system to load until the migrations have successfully completed. This prevents the other beans from having to wait on the migrations to complete before operating, or even instantiating.
I have a startup-appcontext.xml configured with a dbMigrationDAO, a startupManager which is a ThreadPoolExecutor, and lastly, a FullSystemLauch bean. I pass a list of configuration locations to the FullSystemLaunch bean via setter injection. The FullSystemLaunch bean implements ServletContextAware, gets a reference to the current WebApplicationContext and thus I can have a ConfigurableListableBeanFactory. Unfortunately, this bean factory isConfigurationFrozen() returns true, so by calling beanFactory.setConfigLocations(configLocations) has no effect.
Can I accomplish this or is Spring preventing me from doing so because it's a bit out of the ordinary? It seems reasonable if understood, but also a bit dangerous. And yes, I'm willing to blow away the current context b/c the currently loaded Singletons are not needed once initialization is complete.
Thank you for the help.
发布评论
评论(6)
我的意见是允许 Spring 在它认为合适的情况下初始化您的 bean - 按照其声明的依赖项的顺序。
如果您需要数据库迁移,有几种模式可以让它们首先运行:
优点很明显:简单。
My opinion would be to allow Spring to initialise your beans is it sees fit - in the order of their declared dependencies.
If you need database migrations there are a couple of patterns to have them run first:
The advantage is clear: simplicity.
您可以使用现有上下文作为其他上下文的父上下文,尽管我怀疑您是否可以替换现有的 WebApplicationContext。
如果您使用 EAR - WAR 打包,则可以通过从 EAR 加载应用程序上下文然后在 WAR 中添加应用程序上下文来获得这种开箱即用的(某种程度上)。
不确定这是否适用于您的情况。
You could use the existing context as parent context for the other contexts, although I doubt that you could replace the existing WebApplicationContext.
If you use EAR - WAR packaging, you get this out-of-the-box (sort of) by loading an application context from the EAR and then adding one in the WAR.
Not sure whether this is applicable in your situation.
可以 延迟初始化 成为您想要实现的目标的替代方案吗?
Could lazy-initialization be an alternative for what you are trying to achieve?
可能的 XmlBeanDefinitionReader 可以帮助你吗?
Possible XmlBeanDefinitionReader can help you?
您可以将 WebApplicatonContext 升级为 ConfigurableWebApplicationContext
然后使用 setConfigurations 方法。
不要忘记刷新;
you can upcat the WebApplicatonContext to ConfigurableWebApplicationContext
then use the setConfigurations method.
dont forget refresh;
有相同的任务,我创建了两个上下文:
startUpContext.xml
和applicationContext.xml
。 在startUpContext.xml
中有一个 bean,它会触发appliationContext.xml
的加载。 (应用程序上下文位置在startUpContext.xml
中配置为触发器的属性)。 最后,触发器替换当前上下文的位置并刷新它:(startUpContext.xml 使用标准 spring 上下文加载器侦听器加载)
There was the same task and I created two contexts:
startUpContext.xml
andapplicationContext.xml
. InstartUpContext.xml
there is a bean, which triggers loading ofappliationContext.xml
. (application context location is configured instartUpContext.xml
as a property of a trigger). And finally the trigger replaces locations of the current context and refreshes it:(startUpContext.xml is loaded with a standard spring context loader listener)