GVKun编程网logo

当Spring上下文无法加载时,停止服务器的已知方法是什么?(spring 上下文)

23

最近很多小伙伴都在问当Spring上下文无法加载时,停止服务器的已知方法是什么?和spring上下文这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展java–Spring在运行时添

最近很多小伙伴都在问当Spring上下文无法加载时,停止服务器的已知方法是什么?spring 上下文这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展java – Spring在运行时添加外部spring上下文、java – 使用Spring和Maven时,将代码部署到服务器的最佳方法是什么?、java – 使用Web应用程序上下文的Spring上下文层次结构、java – 每次集成测试后的Spring上下文脏等相关知识,下面开始了哦!

本文目录一览:

当Spring上下文无法加载时,停止服务器的已知方法是什么?(spring 上下文)

当Spring上下文无法加载时,停止服务器的已知方法是什么?(spring 上下文)

有时在开发过程中,某些东西会损坏,从而导致spring上下文无法加载。问题在于,有时错误仅出现在某些Bean中,但是Webapp的其余部分已部分加载,然后您会得到一些奇怪的行为。

有什么已知的方法可以使Spring在发生问题时停止服务器进程?例如某些bean注入失败,或者某些NPE发生在某些PostConstruct之类的东西中。

web.xml中的stopOnError = true之类的东西。

答案1

小编典典

因此,最终我找到的解决方案是:创建一个实现ServletContextListener的类,将其称为ApplicationLoaderListener。

在web.xml中设置此类:

<listener>    <listener-class>com.my.package.ApplicationLoaderListener</listener-class></listener>

向其中添加一个私人成员:

private final ServletContextListener loader = new ContextLoaderListener();

此类必须实现两种接口方法,其中的一种是contextInizialized:

@Overridepublic void contextInitialized(ServletContextEvent sce) {    try {        loader.contextInitialized(sce);    } catch (BeanCreationException e) {        handle(e);    }}

和handle()的实现:

private void handle(BeanCreationException e) {    log.error("=============== FATAL =============== - failed to create bean: ", e);    System.exit(1);}

为了使代码完整,第二种方法是:

@Overridepublic void contextDestroyed(ServletContextEvent sce) {    loader.contextDestroyed(sce);}

java – Spring在运行时添加外部spring上下文

java – Spring在运行时添加外部spring上下文

我们有一个包含多个组件(小部件)的主页,有点像包含portlet的门户.其中一些小部件将由其他团队提供广告罐,其中一些将需要一些由 Spring管理的自定义bean.一种解决方案可能是使用带有I通配符的import语句导入spring上下文(例如,在classpath匹配context-widget – * .xml中导入所有上下文).

但是,我更喜欢一种更具编程性的解决方案,我在其中检查每个小部件需要加载的上下文(来自类路径).我没有找到任何解释这个问题的博客,但确实在论坛上发现了一些帖子,说明这将是一个父子语境,这只是单向的;不幸的是,在我的情况下,它需要是双向的.

因此,在浏览了一些API之后,我设法提出了一些有效的方法,但我不相信它是一个很好的解决方案,或者它有任何我没有想到的陷阱.对于这种情况,或许还有另一种(更好的)解决方案?

public class WidgetManager implements ApplicationContextAware
{

    @Autowired
    private WidgetService widgetService;

    @Override
    public void setApplicationContext(ApplicationContext parentApplicationContext) throws BeansException {
        //I do need the parent context to have finished initializing beans
        List<WidgetTO> widgets = widgetService.findAllWidgets();

        List<String> contexts = newArrayListWithCapacity(widgets.size());
        for (WidgetTO widget : widgets) {
            if (isNotBlank(widget.getSpringContext())) {
                contexts.add(widget.getSpringContext());
            }
        }

        AbstractRefreshableWebApplicationContext parentContext = (AbstractRefreshableWebApplicationContext) parentApplicationContext;

        ClasspathXmlApplicationContext context = new ClasspathXmlApplicationContext(contexts.toArray(new String[] {}),parentApplicationContext);
        String[] singletonNames = context.getbeanfactory().getSingletonNames();
        for (String s : singletonNames) {
            //copy all singletons that don't already exist from child to parent
            if (!parentContext.getbeanfactory().containsSingleton(s)) {
                parentContext.getbeanfactory().registerSingleton(s,context.getbeanfactory().getSingleton(s));
            }
        }

    }
}

解决方法

这实际上就是我做的.我们已经使用这种方式超过3年,从来没有问题.

java – 使用Spring和Maven时,将代码部署到服务器的最佳方法是什么?

java – 使用Spring和Maven时,将代码部署到服务器的最佳方法是什么?

我有一个使用 Spring的项目.每次部署时,我都会运行maven目标“package”,它运行所有测试并创建war文件.然后我手动使用ftp程序将war文件复制到服务器.然后我运行一个bash脚本来关闭服务器,替换战争并再次启动服务器.

有时,当他们对数据库模式进行更改时,我必须手动运行sql迁移脚本.

我可以使用更好的工作流程吗?由于项目的war文件为60MB,我不得不等待10-12分钟才能将其上传到服务器.如果我意识到需要改变一件小事,我必须重新做整个过程.

这对我来说是双坏的,因为在DSL上,上传带宽会导致下载带宽消耗,因此互联网完全无法运行.即使在项目上运行并运行maven目标也很慢,因为他们一直使用互联网连接来查找依赖项.

有更好的工作方式吗?谢谢.

解决方法

首先,您可以使用Maven Deploy插件来避免手动ftp副本.
您可以在此URL上找到通过ftp部署项目的方法:

http://maven.apache.org/plugins/maven-deploy-plugin/examples/deploy-ftp.html

第二点是关于你的项目的问题:你的WAR大小是否正常?
我听说过嵌入多余jar的配置,以避免在构建最终jar时meta-inf / spring.handlers覆盖的问题.如果您遇到这种情况,您可能也会对此感兴趣:

http://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html

java – 使用Web应用程序上下文的Spring上下文层次结构

java – 使用Web应用程序上下文的Spring上下文层次结构

我正在处理一个使用dispatcherServlet引导的 Spring MVC Web应用程序.它创建一个管理整个应用程序的XmlWebApplicationContext:
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.dispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

现在有一些模块应该使用ContextSingletonbeanfactoryLocator在运行时加载.因此每个模块都有自己的ClasspathXmlApplicationContext.所以一个模块可以引用XmlWebApplicationContext中的bean,它应该被附加到XmlWebApplicationContext以形成一个上下文层次结构,其中XmlWebApplicationContext应该扮演父类的角色,并且该模块的ClasspathXmlApplicationContext是子上下文的角色.不幸的是我无法连接他们使用

<beans>
    <bean id="moduleContext"https://www.jb51.cc/tag/ssp/" target="_blank">sspathXmlApplicationContext">
        <constructor-arg>
            ...
        </constructor-arg>
        <constructor-arg ref="parentContext" />
    </bean>
</beans>

因为我没有找到没有办法给WebApplicationContext的名称为parentContext.我忽略了一些东西,还是有一种更好/更容易的方式来实现不同的方式?

解决方法

如果您使用注释,您可以这样做:
@Inject
private XmlWebApplicationContext context;

@Inject
private List<ClasspathXmlApplicationContext> childs;

@postconstruct
public void refreshContext() {
    for(ClasspathXmlApplicationContext appContext : childs) {
        appContext.setParent(context);
    }
    context.refresh();
}

您也可以通过使用接口InitializingBean和ApplicationContextAware来进行注释.

编辑:childs是按类型自动连线的,所以Spring将注入作为ClasspathXmlApplicationContext实例的所有bean.

java – 每次集成测试后的Spring上下文脏

java – 每次集成测试后的Spring上下文脏

我最近在我目前的项目中担任自由职业者.我投入的一件事就是失败的jenkins建筑(从4月8日开始失败,在我开始前一周).

一般来说,您可以在日志中看到一系列DI问题.我做的第一件事就是从相同的应用程序上下文开始,以相同的方式使所有测试工作.
他们还实施了自己的“嘲弄”的东西,似乎无法正常工作.在与开发者讨论后,我建议开始使用Springockito. (对于某个模块,他们需要模拟他们的集成测试 – 遗留原因,无法更改)

无论如何,事情之后开始失败了.在测试中被嘲笑的很多豆子都没有被嘲笑,或者没有找到或者其他什么.通常,它会在加载应用程序上下文时失败,说明缺少一个或另一个bean.

我尝试了不同的东西和不同的方法,但最后,只有我最担心的事情才能起作用:将@DirtiesContext添加到每个测试中.现在,maven构建开始再次变为绿色,测试开始做他们应该做的事情.但是我每次都在重新加载Spring上下文,这需要时间 – 这都是相对的,因为上下文加载大约1-2秒.

这个故事的一个侧面是他们已经升级到Hibernate 4,因此升级到Spring 3.2.以前,他们使用的是旧版本的Spring 3.当时所有测试都在进行,并且没有必要使用@DirtiesContext.

现在,让我最担心的是,我无法立即想到对这种奇怪行为的解释.通过启动使用@Autowired bean的测试,几乎可以看出Springs上下文变脏了.并非所有测试都使用Mocks,因此不可能.
这听起来对任何人都很熟悉吗?有没有人与Spring(最新版本)Spring的集成测试有相同的经验?

在Stackoverflow上,我找到了这张票:How can a test ‘dirty’ a spring application context?
它似乎几乎总结了我所看到的行为,但关键是我们是自动装配服务/存储库/ ……,而且我们在这些类上没有任何设置器.

有什么想法吗?

谢谢!

最佳答案
要回答我自己的问题,秘密就在Spring版本中.我们使用的是Spring 3.1.3,而我推测他们使用的是Spring 3.2(他们一直在谈论Spring版本的最新升级).

这里有一个解释,一篇博文,我在寻找修复时偶然发现:http://blog.springsource.org/2012/11/07/spring-framework-3-2-rc1-new-testing-features/

以及相关部分的复制粘贴:

The use of generic factory methods in Spring configuration is by no means specific to >testing,but generic factory methods such as EasyMock.createMock(MyService.class) or Mockito.mock(MyService.class) are often used to create dynamic mocks for Spring beans in a >test application context. For example,prior to Spring Framework 3.2 the following >configuration Could fail to autowire the OrderRepository into the OrderService. The reason is >that,depending on the order in which beans are initialized in the application context,>Spring would potentially infer the type of the orderRepository bean to be java.lang.Object >instead of com.example.repository.OrderRepository.

那么,我是如何解决这个问题的呢?好吧,我做了以下步骤:

>创建一个新的maven模块
>筛选出需要模拟的测试.所有非模拟测试都将在Spring构建中运行,在单独的Failsafe运行中运行(我创建了一个基础包“clean”,并将它们整理出来)
>将所有模拟测试放在名为“mocked”的基础包中,并在Failsafe中为模拟测试进行额外运行.
>每个模拟测试都使用Springockito来创建模拟.我也在使用Springockito注释,轻松地实现@ReplaceWithMock.然后使用@DirtiesContext对每个模拟测试进行注释,因此每次测试后上下文都会变脏,并且每次测试都会重新引入Spring上下文.

我能给出的唯一合理的解释是,上下文实际上是脏的,因为有一个框架(Springockito)从Spring框架接管Spring bean的管理.我不知道这是否正确,但这是我能想到的最好的解释.事实上,这是脏上下文的定义,这就是我们需要将其标记为脏的原因.

使用这个策略,我得到了构建并再次运行,所有测试都运行正常.它并不完美,但它有效,并且它是一致的.

今天关于当Spring上下文无法加载时,停止服务器的已知方法是什么?spring 上下文的分享就到这里,希望大家有所收获,若想了解更多关于java – Spring在运行时添加外部spring上下文、java – 使用Spring和Maven时,将代码部署到服务器的最佳方法是什么?、java – 使用Web应用程序上下文的Spring上下文层次结构、java – 每次集成测试后的Spring上下文脏等相关知识,可以在本站进行查询。

本文标签: