具有@Value 注释的模拟对象
Mock object that has @Value annotation
我有这个 class 存储 webapp 的属性。它在服务 class 中自动装配。我想模拟该服务和 运行 JUnit 测试,但它表明无法自动装配 @Value 字段。
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private myapp.ConfigProperties myapp.SectionServiceImpl.configProperties; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configProperties': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public java.lang.String myapp.ConfigProperties.appFileFolderDocument; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'webapp.root' in string value "${webapp.root}documents\"
源代码
@Component
public class ConfigProperties {
@Value("${email.active}")
public String emailActive;
@Value("${app.homepage}")
public String appHomepage;
@Value("${app.context}")
public String appContext;
@Value("${email.username}")
public String adminEmailAddress;
@Value("${account.trial.dates}")
public int trialVersionDates;
@Value("${app.file.folder.document}")
public String appFileFolderDocument;
@Value("${app.file.folder.pdf}")
public String appFileFolderPdf;
@Value("${app.file.folder.logo}")
public String appFileFolderLogo;
@Value("${app.section.folder.logo}")
public String appSectionFolderLogo;
@Value("${app.folder.img}")
public String appFolderImage;
@Value("${email.emailAddressMatthijs}")
public String emailAddressMatthijs;
@Value("${email.emailAddressInfo}")
public String emailAddressInfo;
// Pagination
@Value("${pagination.items_per_page}")
public int paginationItemsPerPage;
@Value("${pagination.num_display_entries}")
public int paginationNumDisplayEntries;
@Value("${pagination.num_edge_entries}")
public int paginationNumEdgeEntries;
@Value("${use.pdf.report.newsolution}")
public int usePdfReportNewSolution;
@Value("${use.pdf.report.numberOfIndicatorInPdfReport}")
public int usePdfReportNumberOfIndicatorInPdfReport;
@Value("${recaptcha.publickey}")
public String captcharPublicKey;
@Value("${recaptcha.privatekey}")
public String captcharPrivateKey;
@Value("${file.upload.not.allowed}")
public String fileUploadNotAllowed;
@Value("${file.upload.image}")
public String fileUploadImage;
@Value("${maxUploadFileSize}")
public String maxUploadFileSize;
// Pagination
@Value("${pagination.admin.items_per_page}")
public int paginationAdminItemsPerPage;
@Value("${pagination.admin.num_display_entries}")
public int paginationAdminNumDisplayEntries;
@Value("${pagination.admin.num_edge_entries}")
public int paginationAdminNumEdgeEntries;
}
我已经尝试在 XML 中创建 bean,但它仍然显示错误。
<bean id="configProperties" class="myapp.ConfigProperties">
<property name="appFileFolderDocument" value="E:/myapp/src/main/webapp/documents" />
</bean>
错误
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public java.lang.String myapp.ConfigProperties.appFileFolderDocument; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'webapp.root' in string value "${webapp.root}documents\"
configs.properties
app.context = http://localhost:8080/myapp/
app.homepage = http://localhost:8080/myapp
app.file.folder.document = ${webapp.root}documents\
app.file.folder.pdf = ${webapp.root}pdf\
app.file.folder.logo = ${webapp.root}companylogo\
app.section.folder.logo = ${webapp.root}logo\
app.folder.img = ${webapp.root}images\
JUnit 测试文件
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:test-context.xml"})
public class IndicatorTemplateDaoTest {
@Test
public void test() {
}
}
测试-context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:repository="http://www.springframework.org/schema/data/repository"
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-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/data/repository
http://www.springframework.org/schema/data/repository/spring-repository.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:META-INF/properties/config.properties"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxActive" value="${jdbc.maxactive}"/>
<property name="initialSize" value="${jdbc.initialsize}"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"></property>
<property name="persistenceUnitName" value="JpaPersistenceUnit" />
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" >
<property name="showSql" value="false"/>
</bean>
</property>
</bean>
<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven />
<context:component-scan base-package="myapp.dao.impl" >
</context:component-scan>
<bean id="indicatorTemplateDao" class="myapp.dao.impl.IndicatorTemplateDaoImpl">
</bean>
<bean id="indicatorTemplateService" class="myapp.service.impl.IndicatorTemplateServiceImpl">
</bean>
<bean id="indicatorDao" class="myapp.dao.impl.IndicatorDaoImpl">
</bean>
<bean id="indicatorService" class="myapp.service.impl.IndicatorServiceImpl">
</bean>
<bean id="indicatorActionDao" class="myapp.dao.impl.IndicatorActionDaoImpl">
</bean>
<bean id="menuService" class="myapp.service.impl.MenuServiceImpl">
</bean>
<bean id="sectionService" class="myapp.service.impl.SectionServiceImpl">
</bean>
<bean id="configProperties" class="myapp.utils.ConfigProperties">
<property name="appFileFolderDocument" value="E:/myapp/src/main/webapp/documents" />
</bean>
</beans>
如何解决?
首先,从 Spring Framework 3.1 开始,您不应该使用 PropertyPlaceholderConfigurer
。相反,您应该使用 PropertySourcesPlaceholderConfigurer
,它支持 属性 源的层次结构。
从 Spring 3.1 开始,<context:property-placeholder ...>
XML 命名空间元素在后台自动使用 PropertySourcesPlaceholderConfigurer
。
所以一旦你切换到 PropertySourcesPlaceholderConfigurer
,你可以简单地按照我在这个相关讨论中的说明操作:
此致,
Sam(Spring TestContext Framework 的作者)
我有这个 class 存储 webapp 的属性。它在服务 class 中自动装配。我想模拟该服务和 运行 JUnit 测试,但它表明无法自动装配 @Value 字段。
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private myapp.ConfigProperties myapp.SectionServiceImpl.configProperties; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configProperties': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public java.lang.String myapp.ConfigProperties.appFileFolderDocument; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'webapp.root' in string value "${webapp.root}documents\"
源代码
@Component
public class ConfigProperties {
@Value("${email.active}")
public String emailActive;
@Value("${app.homepage}")
public String appHomepage;
@Value("${app.context}")
public String appContext;
@Value("${email.username}")
public String adminEmailAddress;
@Value("${account.trial.dates}")
public int trialVersionDates;
@Value("${app.file.folder.document}")
public String appFileFolderDocument;
@Value("${app.file.folder.pdf}")
public String appFileFolderPdf;
@Value("${app.file.folder.logo}")
public String appFileFolderLogo;
@Value("${app.section.folder.logo}")
public String appSectionFolderLogo;
@Value("${app.folder.img}")
public String appFolderImage;
@Value("${email.emailAddressMatthijs}")
public String emailAddressMatthijs;
@Value("${email.emailAddressInfo}")
public String emailAddressInfo;
// Pagination
@Value("${pagination.items_per_page}")
public int paginationItemsPerPage;
@Value("${pagination.num_display_entries}")
public int paginationNumDisplayEntries;
@Value("${pagination.num_edge_entries}")
public int paginationNumEdgeEntries;
@Value("${use.pdf.report.newsolution}")
public int usePdfReportNewSolution;
@Value("${use.pdf.report.numberOfIndicatorInPdfReport}")
public int usePdfReportNumberOfIndicatorInPdfReport;
@Value("${recaptcha.publickey}")
public String captcharPublicKey;
@Value("${recaptcha.privatekey}")
public String captcharPrivateKey;
@Value("${file.upload.not.allowed}")
public String fileUploadNotAllowed;
@Value("${file.upload.image}")
public String fileUploadImage;
@Value("${maxUploadFileSize}")
public String maxUploadFileSize;
// Pagination
@Value("${pagination.admin.items_per_page}")
public int paginationAdminItemsPerPage;
@Value("${pagination.admin.num_display_entries}")
public int paginationAdminNumDisplayEntries;
@Value("${pagination.admin.num_edge_entries}")
public int paginationAdminNumEdgeEntries;
}
我已经尝试在 XML 中创建 bean,但它仍然显示错误。
<bean id="configProperties" class="myapp.ConfigProperties">
<property name="appFileFolderDocument" value="E:/myapp/src/main/webapp/documents" />
</bean>
错误
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public java.lang.String myapp.ConfigProperties.appFileFolderDocument; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'webapp.root' in string value "${webapp.root}documents\"
configs.properties
app.context = http://localhost:8080/myapp/
app.homepage = http://localhost:8080/myapp
app.file.folder.document = ${webapp.root}documents\
app.file.folder.pdf = ${webapp.root}pdf\
app.file.folder.logo = ${webapp.root}companylogo\
app.section.folder.logo = ${webapp.root}logo\
app.folder.img = ${webapp.root}images\
JUnit 测试文件
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:test-context.xml"})
public class IndicatorTemplateDaoTest {
@Test
public void test() {
}
}
测试-context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:repository="http://www.springframework.org/schema/data/repository"
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-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/data/repository
http://www.springframework.org/schema/data/repository/spring-repository.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:META-INF/properties/config.properties"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxActive" value="${jdbc.maxactive}"/>
<property name="initialSize" value="${jdbc.initialsize}"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"></property>
<property name="persistenceUnitName" value="JpaPersistenceUnit" />
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" >
<property name="showSql" value="false"/>
</bean>
</property>
</bean>
<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven />
<context:component-scan base-package="myapp.dao.impl" >
</context:component-scan>
<bean id="indicatorTemplateDao" class="myapp.dao.impl.IndicatorTemplateDaoImpl">
</bean>
<bean id="indicatorTemplateService" class="myapp.service.impl.IndicatorTemplateServiceImpl">
</bean>
<bean id="indicatorDao" class="myapp.dao.impl.IndicatorDaoImpl">
</bean>
<bean id="indicatorService" class="myapp.service.impl.IndicatorServiceImpl">
</bean>
<bean id="indicatorActionDao" class="myapp.dao.impl.IndicatorActionDaoImpl">
</bean>
<bean id="menuService" class="myapp.service.impl.MenuServiceImpl">
</bean>
<bean id="sectionService" class="myapp.service.impl.SectionServiceImpl">
</bean>
<bean id="configProperties" class="myapp.utils.ConfigProperties">
<property name="appFileFolderDocument" value="E:/myapp/src/main/webapp/documents" />
</bean>
</beans>
如何解决?
首先,从 Spring Framework 3.1 开始,您不应该使用 PropertyPlaceholderConfigurer
。相反,您应该使用 PropertySourcesPlaceholderConfigurer
,它支持 属性 源的层次结构。
从 Spring 3.1 开始,<context:property-placeholder ...>
XML 命名空间元素在后台自动使用 PropertySourcesPlaceholderConfigurer
。
所以一旦你切换到 PropertySourcesPlaceholderConfigurer
,你可以简单地按照我在这个相关讨论中的说明操作:
此致,
Sam(Spring TestContext Framework 的作者)