Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么Spring@Value与@Controller不兼容?_Java_Spring_Annotations_Aspectj_Load Time Weaving - Fatal编程技术网

Java 为什么Spring@Value与@Controller不兼容?

Java 为什么Spring@Value与@Controller不兼容?,java,spring,annotations,aspectj,load-time-weaving,Java,Spring,Annotations,Aspectj,Load Time Weaving,我在寻找对这个问题更好的理解。解决方法非常简单,即将配置数据移动到另一个没有代理/建议包装的类,但我认为更好地理解这一点将有助于我避免将来出现其他相关问题,因此我希望任何人都能提供任何解释 我将Spring3.1.0.RELEASE与SpringSTS和vFabric tc服务器一起使用。使用@Controller类实现了一个基本的LittleREST服务器。这很好(真的,是这样),但是@Controller也是@Transactional的,在加载时编织和vFabric tc服务器之间,它破坏

我在寻找对这个问题更好的理解。解决方法非常简单,即将配置数据移动到另一个没有代理/建议包装的类,但我认为更好地理解这一点将有助于我避免将来出现其他相关问题,因此我希望任何人都能提供任何解释

我将Spring3.1.0.RELEASE与SpringSTS和vFabric tc服务器一起使用。使用@Controller类实现了一个基本的LittleREST服务器。这很好(真的,是这样),但是@Controller也是@Transactional的,在加载时编织和vFabric tc服务器之间,它破坏了@Value

@Controller
@RequestMapping("/hello")
public class MyAPI {

    @Value("${my.property}")
    private String prop;
    ...

    @Transactional
    handleRequest(...) ...


}
和属性文件app.properties:

my.property = SUCCESS
这在JUnit下运行良好,测试得到的MyAPI对象的prop设置为“SUCCESS”。但当应用程序加载到vFabric中时,我猜它会在加载时进行编织和代理。无论发生什么情况,都会创建两个MyAPI实例,一个实例的prop==“SUCCESS”,另一个实例(不幸的是处理http请求的实例)的prop==“${my.prop}”

总之,我称之为魔法的失败,这是我最关心的使用AOP之类的东西。即使使用STS,我也不知道如何追踪问题背后的原因,或者弄清楚这是否是一个严重的错误。如果它是一个bug,我不知道它是Spring、AspectJ、load time weaver还是vFabric中的bug,所以我甚至不知道在哪里提交bug报告


因此,任何有助于理解这一点的人都将不胜感激。谢谢。

首先,使用$的符号是正确的,而不是#

现在关于原始海报,我认为两个注释(@Controller和@Transactional)之间存在冲突

使用@Transactional注释将代理您的实现(我猜是为了检测错误并启动回滚)

现在,您可以看到控制器的两个实例。这不应该发生。 通常,在内存中应该只加载一个控制器实例

可能与您的配置文件有关,或者由于@Transactional及其代理性质的存在

作为补充说明,我从未在控制器本身中使用@Transactional,而是在服务或dao的方法中使用。因为实际的进程可能会失败,需要回滚,并且可以从不同的控制器/源进行访问


问候。

我想明白了。这确实太神奇了

我在STS中使用SpringRoo来生成基本的应用程序框架,然后使用STS分解Roo,因为我们不想坚持使用它

Roo作为“最佳实践”所做的一件事是创建两个Spring上下文,一个用于整个应用程序,另一个限于DispatcherServlet。确切的原因是什么,我还没有弄清楚,但我想他们希望不让表示层的东西,比如控制器,悄悄地进入共享的服务层。axtavt很好地解释了这一点。这些都是STS对我隐瞒的

在带Roo的STS中,WEB-INF源代码不是我所期望的,在/src/main/resources(META-INF目录所在的位置)下,而是在/src/main/webapp下,它不是Java源代码目录,因此完全独立地显示在/target目录的正上方,所以我把它误认为是输出文件夹

在applicationContext.xml中,Roo插入了过滤器,以防止应用程序上下文构造控制器,正如axtavt的文章中所解释的,但它也加入了另一个过滤器,以消除对Roo生成的类的扫描。我同时取出了两个过滤器,不知道它们是干什么用的,但我认为它们只是Roo的剩菜

现在我有了前面解释过的问题。应用程序上下文中的一个将获得分配的属性,因为它正在使用applicationContext.xml并查找属性文件。但是为什么他们两个都没有设置属性呢

这让我回到模糊的webapps文件夹。Roo在WEB-INF文件夹中放置了WEB.xml(自然)和一个包含webmvc-config.xml文件的spring文件夹。此配置文件设置为仅扫描、创建和设置控制器。xml文件将web应用程序设置为使用applicationContext.xml,并将dispatcherServlet设置为使用webmvc-config.xml,因此我应该将过滤器保留在applicationContext.xml中,以避免重复创建


拼图的最后一块是这个webmvc-config.xml文件。由于这是控制器设置的上下文,文件也需要配置,以便它可以找到属性文件

在我的例子中,我是这样解决的: 在
之前的
springservlet.xml
中,我将以下内容:

<context:property-placeholder location="classpath:strings.properties"/>

strings.properties
文件则放在
src/main/resources/


注意:
context:property placeholder
标记的可见性有限,因此我在某处阅读了建议在每个上下文文件中复制它,您可以使用其中的字符串。

我遇到了同样的问题,事实上我需要这两个

让这两位议员工作

  • 将属性(通过@Value)注入控制器
  • 将具有属性(通过@Value)的托管bean(通过@Inject)注入控制器
  • 我希望这有帮助

    这是web.xml文件

        <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:/spring-config/spring-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    最后,这里是我将属性注入的类:

    @Service
    public class ConfigProperties {
    
    @Value("${message1}")
    public String message1;
    }
    

    这对我有用,对你也有用。祝你好运

    你确定是AOP引起的吗?如果您删除了
    @Transactional
    ?@axtavt您向我指出了解决方案。请参阅下面我的完整答案,但简短的回答是,
    Controller
    s在我的(mis-)配置中被创建了两次。
    @Transactional
    没有问题,因为它使用的是AspectJ,而不是
    @Controller
    @RequestMapping("/fooController")
    public class MyController {
    
    @Value("${message1}")
    public String message1;
    
    @Inject
    public ConfigProperties configProperties;
    
    @Service
    public class ConfigProperties {
    
    @Value("${message1}")
    public String message1;
    }