标签: applicationcontext

开发 Spring 应用程序中最常见的错误是什么?

我目前正在明斯特大学准备我的学士学位论文。我计划自动识别 Spring 配置中的典型问题。市场上有很多工具可以执行静态代码分析以查找错误或问题。这些显然无法检测仅在运行时出现的问题。我将分析一个 Spring 应用程序的 ApplicationContext 并通过使用反射和 bean 图的分析来查找错误配置。

示例: 一个简单的示例是,如果有人想通过使用注释来使类或方法事务安全。他通常会在类或方法上方添加一个@Transactional-tag,但是如果应用程序没有正确配置并且没有注册到ApplicationContext 的事务管理器,它观察注解,那么该标记将被忽略。不会出现错误信息,这也是目前很难发现这类问题的原因。

问题: 使用弹簧机制的错误配置导致的最常见错误或架构故障是哪些,可以通过动态分析检测到?是否有任何项目参与做类似的事情?

PS在我的论文过程中,我将开发一个可以检测此类问题的原型,并在以后将其开源。:)

java testing spring automated-tests applicationcontext

5
推荐指数
1
解决办法
1507
查看次数

如何在 Spring Framework 4 中初始化应用程序上下文

我有一个基于Spring Framework 4及其子项目 - Spring Data Solr 的项目。

我有机会看到的所有示例都解释了如何组织您的项目 - 从基本实体( pojo )类到 Spring 特定类(例如存储库和服务)。当谈到测试功能时,所有示例都显示带有私有字段( spring bean )的测试,该字段通常在注释的帮助下进行初始化

@ContextConfiguration(classes = some-spring-data-main-class.class, loader = SpringApplicationContextLoader.class)
Run Code Online (Sandbox Code Playgroud)

然后就可以在方法中调用它的bean的方法了@Test

但是,当涉及到项目中的 init bean 时 - 如何使用 Spring 4 来实现它,它是完全无 XML 的(我的意思是,我没有文件applicationContext xml)。

PS 在 Spring 3 中我们通常这样写:

ApplicationContext context = new ClasspathApplicationContext("applicationContext.xml") 
Run Code Online (Sandbox Code Playgroud)

期望与 Spring 4 类似的东西引入应用程序初始化的全新概念是否合理?现在我们应该写什么来初始化应用程序的第一个 bean?

spring launch javabeans applicationcontext

5
推荐指数
1
解决办法
3万
查看次数

如何准确地工作基于 Spring 继承的代理配置?

我正在学习 Spring Core 认证,我发现一些与代理概念相关的疑问。

所以在学习材料上,我找到了以下测验:

有一个 Java配置类,其中包含以下方法:

@Bean
public AccountRepository accountRepository(){ 
    return new JdbcAccountRepository(); 
}

@Bean
public TransferService transferService1() {
    TransferServiceImpl service = new TransferServiceImpl();
    service.setAccountRepository(accountRepository());
    return service;
}

@Bean
public TransferService transferService2() {
    return new TransferServiceImpl( new JdbcAccountRepository() );
}
Run Code Online (Sandbox Code Playgroud)

如您所见,transferService()有两种不同的实现,分别命名为transferService1()transferService2(),它们创建并返回TransferServiceImpl对象。

第一个创建一个新的TransferServiceImpl对象,然后对其调用setAccountRepository()方法。

第二个只是创建一个TransferServiceImpl将一个新的JdbcAccountRepository对象传递给它的构造函数。

它问我**前两种方法的最佳实现是什么?

提供的答案是:首选调用专用方法。所以我认为它说最好的方法是第一个实现。

它解释说AccountRepository bean 是一个单例(因为它是 Spring 中 bean 的标准范围)但是JdbcAccountRepository()可以被调用两次或更多次(例如在前面的代码片段中,它在调用方法时被调用 …

java spring design-patterns proxy-pattern applicationcontext

5
推荐指数
1
解决办法
705
查看次数

如何将 spring 应用程序上下文导入另一个应用程序上下文?

我有两个 spring 应用程序上下文。一个是我的应用程序本地的,另一个来自 maven 依赖项之一。

现在,我的applicationContext.xml文件看起来像这样。

<import resource="classpath*:**/sample-applicationContext.xml" />
Run Code Online (Sandbox Code Playgroud)

<context:component-scan>sample-applicationContext.xml扫描组件的文件中。

现在,当我执行以下操作时..

ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
MyClass m=ctx.getBean(MyClass.class);
Run Code Online (Sandbox Code Playgroud)

不幸的是,当我得到MyClass对象时,对象被创建,但是,我看到MyClass没有注入依赖项。

自动装配的依赖项MyClass是使用<context:component-scan>insample-applicationContext.xml文件扫描的 bean 。

有没有办法在我的项目类中使用 Maven 依赖项中存在的多个应用程序上下文并自动装配它们?

java spring spring-mvc maven applicationcontext

5
推荐指数
1
解决办法
6855
查看次数

ApplicationContext.getBean 与 new 关键字

我正在使用 JSF + Spring+ Hibernate

protected @Inject ChartOfAccount chartOfAccount;
Run Code Online (Sandbox Code Playgroud)

chartOfAccount我基本上想从列表中填充

for (DistributionEntry de : getDistributionEntries()) {

     chartOfAccount.setAccount(de.getAccount());
     chartOfAccountList.add(chartOfAccount);
}
Run Code Online (Sandbox Code Playgroud)

对于每次迭代,我想要新的对象,chartOfAccount否则你知道列表包含具有最新值的相同对象。

解决方案一:使用 new 关键字 :-p

for (DistributionEntry de : getDistributionEntries()) {
     ChartOfAccount coa= new ChartOfAccount();
     coa.setAccount(de.getAccount());
     chartOfAccountList.add(coa);
}
Run Code Online (Sandbox Code Playgroud)

解决方案二:applicationContext.getBean

for (DistributionEntry de : getDistributionEntries()) {
     chartOfAccount= applicationContext.getBean(ChartOfAccount.class);
     chartOfAccount.setAccount(de.getAccount());
     chartOfAccountList.add(chartOfAccount);
}
Run Code Online (Sandbox Code Playgroud)

但我读过某些文章,以避免使用applicationContext.getBean

如果我避免使用applicationContext.getBean处理这种情况的最佳方法是什么?两种行为都会相同吗?(ApplicationContext.getBean 与 new 关键字)

注意:我的托管bean是@Scope(“session”),模型是@Scope(BeanDefinition.SCOPE_PROTOTYPE),所以我们都知道,对于一个会话,它是单例,而不同会话的原型。

java jsf spring scope applicationcontext

5
推荐指数
1
解决办法
3956
查看次数

运行集成测试时无法加载 ApplicationContext

我正在尝试运行 mvnintegration-test阶段,但在执行集成测试时出现Failed to load ApplicationContext错误(单元测试正确执行)。我正在SpringJUnit4ClassRunner使用类来运行我的测试。

这是完整的堆栈跟踪:

2017-02-09 03:22:15.705 [main] ERROR o.s.t.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@5c072e3f] to prepare test instance [com.dentilax.app.accountservice.AccountServiceIT@768b970c]
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) …
Run Code Online (Sandbox Code Playgroud)

junit spring maven applicationcontext

5
推荐指数
1
解决办法
4万
查看次数

如何在测试之间关闭应用程序上下文

我有 3 组测试:单元、集成、验收。

  • 后两组启动 ApplicationContext:“集成”最少,“接受”完整。
  • 两个应用程序上下文都注册队列订阅者。
  • 在整个测试运行结束时注销应用程序上下文 ( @RunWith(SpringRunner.class))

当我运行“所有测试”时,会启动 2 个不同的应用程序上下文,并且我有重复的队列订阅者。

我知道此订阅者重复的以下解决方法:

  • 永远不要同时运行集成和验收测试
  • 将“验收”应用程序上下文用于“集成”测试。缺点:试运行需要更长的时间。
  • 添加静态注册表并手动添加/删除侦听器。缺点:过于复杂且容易忘记

在一组测试之后,是否有任何方便的方法来卸载应用程序上下文?

基于ndrone答案的更新

  • @DirtiesContext 是绝配
  • 另一种选择是将缓存的 ApplicationContexts 计数限制为 1 spring.test.context.cache.maxSize=1

使用脏上下文测试超类示例

    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
    @TestExecutionListeners({FlywayTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class})
    @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
    public abstract class AcceptanceTest {}
Run Code Online (Sandbox Code Playgroud)

applicationcontext spring-boot spring-boot-test

5
推荐指数
0
解决办法
2550
查看次数

Spring的上下文命名空间如何工作?

例如,如果我在application-context.xml中声明:

<context:annotation-config/>
Run Code Online (Sandbox Code Playgroud)

我从官方文件中读到:

在隐式注册后处理器包括AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor会,PersistenceAnnotationBeanPostProcessor,以及上述RequiredAnnotationBeanPostProcessor.

但我想知道Spring是如何工作的,我认为这个1-liner被转换为文档中提到的后处理器的几个bean定义.

但是,我的问题是,哪个Spring组件/类实现了"从1-liner到多个bean定义的转换"功能?

java spring xml-namespaces post-processing applicationcontext

4
推荐指数
1
解决办法
2805
查看次数

如何在PropertySource中使用相对于用户主目录的路径

Spring表达式在PropertySource注释中不起作用.

@PropertySource({ "classpath:application.properties",
        "#{systemProperties['user.home']}/.app.properties" })
@Configuration
public class Config {
@Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer result = new PropertySourcesPlaceholderConfigurer();
        result.setOrder(0);
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

java spring annotations applicationcontext

4
推荐指数
1
解决办法
4004
查看次数

是否可以在类之间缓存Spring的Application Context?

我正在尝试提高我正在研究的项目的Spring集成测试的性能。我们正在使用Spring + Gradle + JUnit。

build.gradle文件中使用以下配置:

test {
    useJUnit()
    setForkEvery(0)
    setMaxParallelForks(1)
}
Run Code Online (Sandbox Code Playgroud)

我们能够在单个JVM中运行所有测试。虽然我认为这是默认行为。

但是我一直在阅读有关Spring Test Context Caching的内容,并且在我的application-test.yml中具有以下属性:

logging:
  level:
    org:
      springframework:
        test:
          context:
            cache: DEBUG
Run Code Online (Sandbox Code Playgroud)

我注意到以下日志用于同一类中运行的测试方法

2017-09-05 08:33:11.829 DEBUG 5764 --- [    Test worker] c.DefaultCacheAwareContextLoaderDelegate : Storing ApplicationContext in cache under key [THIS HAD SENSITIVE DATA]
2017-09-05 08:33:11.830 DEBUG 5764 --- [    Test worker] org.springframework.test.context.cache   : Spring test ApplicationContext cache statistics: [DefaultContextCache@572e81e7 size = 1, maxSize = 32, parentContextCount = 0, hitCount = 0, missCount = …
Run Code Online (Sandbox Code Playgroud)

junit spring spring-test gradle applicationcontext

4
推荐指数
1
解决办法
921
查看次数