【问题标题】:Intilaizing a bean with constructor args - WebApplicationContext vs ClassPathApplicationContext使用构造函数参数对 bean 进行初始化 - WebApplicationContext vs ClassPathApplicationContext
【发布时间】:2014-05-08 18:06:35
【问题描述】:

applicationContext.xml 上的 bean defiend 正在使用 ClassPathXmlApllicationContext 和 WebApplicationContext 进行实例化。使用前者时,bean 按预期返回,但使用后者时,WebApplicationContext,我得到一个空值。

仅供参考:没有充分利用 Spring。只是用来定义一个bean并初始化它。它是一个基于 jboss 的 Web 服务应用程序。

我在 web.xml 中定义了 WebApplicationContext 如下

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
     xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

     <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

<servlet>
    <display-name>Service</display-name>
    <servlet-name>MService</servlet-name>
    <servlet-class>
        com.xyz.atop.ws.memb.MServiceImpl
    </servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>MService</servlet-name>
    <url-pattern>/Service</url-pattern>
</servlet-mapping>
</web-app>

applicationContext.xml 中的条目

 <beans ...>
 <context:annotation-config />

 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

 <bean id="helper" name="helper" class="com.xyz.svc.wrapper.Helper">
    <constructor-arg type="java.lang.String" value="ABC"/> 
 </bean>
 </beans>

在我的代码中使用了 ClassPathApplicationContext(按预期返回一个 bean 实例),如下所示

private static Helper helper;

public MServiceImpl() {
}    
static {
    ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    helper = (Helper) appContext.getBean("helper");
}
......
......

在使用 WebApplicationContext 时,我尝试了 @Autowired 注解,甚至尝试了 setter 注入。两种方式我都返回一个空值。

我试图初始化的“Helper”类来自一个 jar 文件,该文件又调用 cxf-spring 应用程序。

请查看上述场景并建议在使用 WebApplicationCONtext 时摆脱空指针。

【问题讨论】:

    标签: java spring dependency-injection applicationcontext


    【解决方案1】:

    好的,spring beans 被注入到其他 spring beans 中。 MService 也需要是一个 bean。然后,Autowire 会将帮助程序注入 MService bean。您不能使用静态初始化程序来执行此操作,因为它是在类加载时运行的,即在应用程序上下文加载之前。此外,助手不应该是静态的——这是不好的做法——这会使测试变得非常困难。

    【讨论】:

    • 这是有道理的。但我现在向您提出的问题是“为什么当我尝试使用 WebApplicationContext 和 Autowiring 时 spring bean 实例返回为 null?”
    • 这很可能是您的应用中加载顺序的问题。您的静态初始化程序在类加载器加载类时运行,这是在您的应用程序上下文初始化之前。要完成这项工作,您必须将自己注册为上下文完成初始化时引发的事件的侦听器。有关信息,请参阅此问题:stackoverflow.com/questions/8686507/…
    • 我没有同时使用 ClassPathApplicationContext 和 WebApplicationContext。如果我使用 ClassPathApplicationCONtext 则 web.xml 中加载上下文文件的条目将被删除,当我尝试使用 WebApplicationContext 时,我会在 web.xml 中添加条目并从实现类中删除静态块并将其替换为非静态私有类“Helper”的@Autowired注解
    • 同样的问题。静态初始化器在你的类加载后立即运行,这可能早在 spring 应用程序上下文有时间加载之前——但是它已经启动了。
    【解决方案2】:

    场景:使用 WebApplicationContext 初始化 applicationCONtext.xml 文件中定义的 bean,并在自动装配后尝试在代码中使用实例化的 bean 对象时收到 null。

    这种情况下的问题:我正在尝试在 Spring 可以控制的类中自动装配 Spring bean。

    解决方案: 使用 Spring 的 SpringBeanAutowiringSupport 类扩展作为我的 JBOSS WS 端点的 Servlet 类(不在 Spring 控制中的类)帮助我解决了这个问题。

    下面是代码sn-p

    public class MServiceImpl extends SpringBeanAutowiringSupport implements MService{
    
         @Autowired
         private Helper helper;
    
         public MServiceImpl() {
         }    
    ......
    ......
    }
    

    发现使用静态块来初始化 spring bean 是不好的方法。感谢@Engineer Dollery

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-19
      • 1970-01-01
      • 2019-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多