Spring不能将AOP与嵌入式数据库脚本一起使用

时间:2017-04-07 11:40:49

标签: java spring junit spring-data

Spring无法初始化bean“dataSource”,而bean声明包含<jdbc:script location="...."/> 当我运行我的单元测试时。

脚本的路径似乎是正确的,脚本似乎是正确的。

初始化是这样的:applicationContext.xml导入db-h2-config.xml,它找到“dataSource”bean。

如果此bean包含<jdbc:script location>部分中的任何一个,则它会因附加的堆栈跟踪而失败。 (有关完整的堆栈跟踪,请参阅下文)

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#3427b02d': Cannot create inner bean '(inner bean)#41fbdac4' of type [org.springframework.jdbc.config.SortedResourcesFactoryBean] while setting bean property 'scripts'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#41fbdac4': Post-processing of FactoryBean's object failed; nested exception is java.lang.AssertionError

如果删除<jdbc:script location>部分,则没有错误。

更新 我在下面添加了SayAOP.java和TrackCoach.java代码。

SayAOP.java:

package hu.springdemo;

public class SayAOP {

   public void shoutAOPBefore() {
        System.out.println("HERE IS THE AOP BEFORE");
    }

    public void shoutAOPAfter(){
        System.out.println("HERE IS THE AOP After");
    }
}

TrackCoach.java:

package hu.springdemo;

public class TrackCoach implements CoachIF {
    @Override
    public void getDailyWorkout() {
        System.out.println("TrackCoach says: 'Go and run 5k!' ");
    }

}

AppTest.java:

package hu.apptest;

import hu.springdemo.BaseballAthlete;
import hu.springdemo.CoachIF;
import hu.springdemo.CoachSpringConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.parsing.Location;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/applicationContext.xml")
public class AppTest {

    @Autowired
    CoachIF myBaseBallGuy;

    @Test
    public void baseballAthleteShouldNotBeNull() {
        assertNotNull(myBaseBallGuy);
        myBaseBallGuy.getDailyWorkout();
    }
}

分贝-H2-config.xml中:

<beans xmlns:jdbc="http://www.springframework.org/schema/jdbc"
        xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/jdbc     
        http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd">

    <jdbc:embedded-database id="dataSource" type="H2">
            <jdbc:script location="classpath:db/sql/create-db.sql"/>
    </jdbc:embedded-database>

</beans>

的applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/jdbc
        http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/jdbc
        http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
">

    <import resource="classpath:db-h2-config.xml"/>

    <bean id="myTrackCoach"
          class="hu.springdemo.TrackCoach">
    </bean>

    <bean id="SayAOP"
          class="hu.springdemo.SayAOP">
    </bean>

    <aop:config>

        <aop:aspect id="mtc" ref="SayAOP">
            <aop:pointcut id="pmtc" expression="execution(* hu.springdemo.TrackCoach.getDailyWorkout(..))"/>
            <aop:before pointcut-ref="pmtc" method="shoutAOPBefore"/>
            <aop:after pointcut-ref="pmtc" method="shoutAOPAfter"/>
        </aop:aspect>
    </aop:config>

</beans>

创建-db.sql:

CREATE TABLE users (
  id         INTEGER PRIMARY KEY,
  name VARCHAR(30),
  email  VARCHAR(50)
);

堆栈跟踪:

    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.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:253)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': Cannot create inner bean '(inner bean)#72f926e6' of type [org.springframework.jdbc.datasource.init.CompositeDatabasePopulator] while setting bean property 'databasePopulator'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#72f926e6': Cannot create inner bean '(inner bean)#3427b02d' of type [org.springframework.jdbc.datasource.init.ResourceDatabasePopulator] while setting bean property 'populators' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#3427b02d': Cannot create inner bean '(inner bean)#41fbdac4' of type [org.springframework.jdbc.config.SortedResourcesFactoryBean] while setting bean property 'scripts'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#41fbdac4': Post-processing of FactoryBean's object failed; nested exception is java.lang.AssertionError
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:313)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:129)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1481)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1226)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:108)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:251)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
    ... 29 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#72f926e6': Cannot create inner bean '(inner bean)#3427b02d' of type [org.springframework.jdbc.datasource.init.ResourceDatabasePopulator] while setting bean property 'populators' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#3427b02d': Cannot create inner bean '(inner bean)#41fbdac4' of type [org.springframework.jdbc.config.SortedResourcesFactoryBean] while setting bean property 'scripts'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#41fbdac4': Post-processing of FactoryBean's object failed; nested exception is java.lang.AssertionError
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:313)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:129)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:382)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:157)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1481)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1226)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:299)
    ... 47 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#3427b02d': Cannot create inner bean '(inner bean)#41fbdac4' of type [org.springframework.jdbc.config.SortedResourcesFactoryBean] while setting bean property 'scripts'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#41fbdac4': Post-processing of FactoryBean's object failed; nested exception is java.lang.AssertionError
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:313)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:129)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1481)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1226)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:299)
    ... 55 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#41fbdac4': Post-processing of FactoryBean's object failed; nested exception is java.lang.AssertionError
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:133)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:302)
    ... 61 more
Caused by: java.lang.AssertionError
    at org.aspectj.weaver.UnresolvedType.nameToSignature(UnresolvedType.java:726)
    at org.aspectj.weaver.UnresolvedType.forName(UnresolvedType.java:231)
    at org.aspectj.weaver.World.resolve(World.java:423)
    at org.aspectj.weaver.internal.tools.PointcutExpressionImpl.couldMatchJoinPointsInType(PointcutExpressionImpl.java:80)
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.matches(AspectJExpressionPointcut.java:250)
    at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:220)
    at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:279)
    at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:311)
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:118)
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:88)
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:69)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:347)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:299)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1723)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:130)
    ... 62 more


Process finished with exit code 255

2 个答案:

答案 0 :(得分:1)

问题在于AspectJ。请将aspectj依赖项升级到最新版本。请查看JIRA了解更多详情

https://jira.spring.io/browse/SPR-9272

https://jira.spring.io/browse/SPR-7989

答案 1 :(得分:0)

不同的问题,但它的解决方案也解决了我的问题,但原因仍然不明确,似乎我的脚本运行与Spring AOP发生冲突:

Populating H2 database with Spring and jdbc DataSourceTransactionManager

我按如下方式更改了嵌入式数据库bean以删除脚本元素:

<jdbc:embedded-database id="embeddedH2Database" type="H2"/>

在我的测试之前添加了@Sql注释来创建表和加载表。

@Sql({"classpath:db/sql/create-db.sql", "classpath:db/sql/insert-data.sql"})