我有一个打包在ear文件中的servlet,我无法让它解析@Value注释属性。
该应用程序由两部分组成:一个封装在war文件中的servlet,然后由封装在ear文件中的不同应用程序包含。该应用程序提供了由servlet中的接口定义的类(ResourceManager)的实现,以及包含@Value注释字段的属性值的属性文件。
战争文件包含:
web.xml:
<servlet>
<servlet-class>... extends MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/spring-ws.xml
classpath:/spring-app.xml
</param-value>
</init-param>
</servlet>
spring-ws.xml:
<context:annotation-config/>
<context:property-placeholder location="classpath:/spring-ws.properties"/>
spring-ws.properties中的值直接从spring-ws.xml引用,并且都可以正常工作。
servlet类包含:
public class MyServlet extends MessageDispatcherServlet
@Autowired private ResourceManager resourceManager; // original annotation - got this to work
@Value("${app.name:}") private String appName; // added later - cannot get this to work
app.name是可选的,因此尾随“:”。
ear文件添加(打包在ear-lib目录中的jar文件中):
Spring应用程序.xml:
<context:property-placeholder location="classpath:/spring-app.properties"/>
<bean class="ResourceManagerImpl">
...
</bean>
spring-app.properties:
app.name=myApp
我的第一个问题是@Autowired注释:不确定我是否正确地找到了它的底部,但是我设法通过将此代码添加到servlet来使其正常工作:
@Override
protected void initFrameworkServlet() throws ServletException {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(getWebApplicationContext().getAutowireCapableBeanFactory());
bpp.processInjection(this);
}
这可能不是解决这个问题的最佳方法,但这是我第一次找到它,并且很有效,所以我使用它并继续。然后我添加了一个带@Value注释的字段,但我找不到一种方法来实现它。AutowiredAnnotationBeanPostProcessor的javadocs说,它也应该处理@Value注释,但似乎不是这样的:appName属性总是空的(可能是默认值)。
我确实有一个解决方法,使用豆子:
@Autowired @Qualifier("appName") private String appName;
<bean id="appName" class="java.lang.String">
<constructor-arg value="myApp"/>
</bean>
但是我确信一定有更好的方法来做到这一点。我读过这篇文章Spring Framework中applicationContext.xml和spring-servlet.xml之间的差异,但我不确定它是否适用:我想我甚至没有这里的应用程序上下文,只是在web.xml中为(单个)servlet类定义的servlet上下文。
我也看到了这一点:Spring 3.0.5没有从属性中评估@Value注释,这看起来像是同样的问题,但那里的解决方案似乎是移动”
最后,我快速简化了问题,删除了单独的应用程序,并将所有内容打包在一场战争中,但我不认为这是问题所在(尽管可能明显是错误的……):spring可以解析应用程序的类路径。xml文件,因此它必须能够解析应用程序的类路径。属性文件。
非常感谢任何帮助,但我想在这一点上这是一个学术兴趣,因为我有一个可行的解决方案(使用beans ),支付账单的人真的不关心它如何工作,只要它能工作!我只是想知道,这样下次我就不必复制(我认为是)一个有缺陷的解决方法。
使用Spring-ws-core 2.1.4,它通过 maven 依赖项拉入Spring 3.2.4。
谢谢
更新-已解决
原来解决这个问题的关键是M Deina的评论,“你也有一个重复的元素……”。我在同一个上下文中有两个单独的属性PlaceholderConfigrer,所以第二个被忽略了,它的属性从未使用过。上下文本身(这是一个servlet上下文,而不是根上下文)或注释处理没有问题。
因此,修复方法是简单地从spring-app.xml中删除属性占位符,并将两个属性文件合并到spring-ws.xml
<context:property-placeholder
location="classpath:/spring-ws.properties,
classpath:/spring-app.properties"/>
TL公司;DR在这里的答案是Spring:namespace vs contextConfigLocation在web中的init参数。xml还可以很好地解释不同上下文是如何处理的!
干杯,
对此有一个解决方法。
您可以在 Java 类中创建静态字段来存储值。
public class SystemPropertyHelper {
public static String propertyValue;
}
并创建一个用@Service或@Component注释的java类,您可以在其中注入属性,并将此值传递给静态字段。
@Component
public class SpringBeanClass {
@Value("${propertyName}")
private String propertyValue;
@PostConstruct
public void init() {
SystemPropertyHelper.propertyValue = propertyValue;
}
}
这样,您可以始终通过静态字段访问属性值SystemPropertyHelper.propertyValue
对于@Autowired注释,您只需要有一个包含这些注释的类:
@Configuration
@PropertySource("classpath:myFile.properties")
@ComponentScan("com.company.package")
Spring使用@Configuration来告诉它是一个用于配置的类(它替换了您提到的xml文件,xml conf文件是Spring 2,注解是Spring 3和4的新内容)
@ ComponentScan可以管理IOC (@Autowire)
@PropertySource加载属性文件
然后在启动时使用prop文件初始化类:
@Component("myFileProperties")
public class MyFileProperties{
@Value("${app.name}")
private String appName;
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName= appName;
}
}
如果您希望它能够激励您,请看这里(我开发的web上下文中的conf文件):https://github.com/ebrigand/RSSLiker/blob/master/src/main/java/com/mrm/rss/init/WebAppConfig.java
您的servlet不是spring管理的bean,而是由Servlet容器管理的。这就是为什么< code>@Autowired不能工作的原因。Spring只会处理它知道的豆子。
ContextLoaderListener
和servlet(基本上是任何扩展FrameworkServletContextLoaderListener
中的一个被servlet中构造的上下文用作父级。因此,您的servlet中确实有一个ApplicationContext
。
现在要正确解析这个@Value
,您需要有一个Property tyPlaceHolderConfigrer
来解析占位符。由于Property tyPlaceHolderConfigrer
是一个BeanFactoryPostProcorer
,它只对同一上下文中的bean进行操作,因此由ContextLoaderListener
加载/配置的那个不会对与servlet中的上下文相关的bean执行任何操作。(因此您需要添加
一般来说,你也有一个重复的元素,你想避免这种情况,因为它会同时导致问题,要么一个覆盖另一个,要么你会得到占位符不能被
属性PlaceHolderConfigrer
中的任何一个解析的异常
您的init代码也过于复杂,您不需要< code > AutowiredAnnotationBeanPostProcessor
只需使用可用的方法。
getWebApplicationContext().getAutowireCapableBeanFactory().autowireBean(this);
这也比只有AutowiredAnnotationBeanPostProcessor
做的更多。
主要内容:@WebServlet 注解的属性,@WebServlet 注解的使用,@WebServlet 注解 和 web.xml 的优缺点在 Servlet 中,web.xml 扮演的角色十分的重要,它可以将所有的 Servlet 的配置集中进行管理,但是若项目中 Servelt 数量较多时,web.xml 的配置会变得十分的冗长。这种情况下,注解(Annotation)就是一种更好的选择。 与 XML 不同,注解不需要依赖于配置文件,它可以直接在类中使用,其配置只对当前类有效,这样就避免了集
本文向大家介绍Spring @value和@PropertySource注解使用方法解析,包括了Spring @value和@PropertySource注解使用方法解析的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了Spring @value和@PropertySource注解使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考
问题内容: 使用诸如 可以分配具有某些属性的某些字段。 是否有更短,更简洁的形式来执行此操作? 问题答案:
问题内容: 如何在Spring中使用@Value批注将值从属性文件注入Map中? 我的Spring Java类是我尝试使用$,但收到以下错误消息 无法自动装配字段:私有 嵌套异常是:无法解析字符串值中的占位符 我在.properties文件中具有以下属性 问题答案: 我相信Spring Boot支持使用注释开箱即用地加载属性映射。 根据该文档,你可以加载属性: 像这样变成豆子: 我之前使用过@Co
我正在运行IntelliJ IDEA 2017.3.4(终极版)。我有一个Spring Boot项目,定义了Spring属性,它将自动连接到类中的注释字段中。属性在Application.properties中定义。 如果“My.Property.Value”解析为“TheValue”,将显示如下: 我宁愿它不这样做。是否有禁用此功能的首选项?我没有运气找到答案,搜索的想法,偏好或网上。