Spring注入不适用于FF4J Web控制台

时间:2015-06-24 09:11:05

标签: java spring ff4j

我尝试让FF4j(ff4j.org)Web控制台正常工作。根据网站上的文档,我使用以下配置:

<servlet>
    <servlet-name>ff4j-console</servlet-name>
    <servlet-class>org.ff4j.web.embedded.ConsoleServlet</servlet-class>
    <init-param>
        <param-name>ff4jProvider</param-name>
        <param-value><path to class>.ConsoleFF4jProvider</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>ff4j-console</servlet-name>
    <url-pattern>/ff4j-console</url-pattern>
</servlet-mapping>

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

FF4JProvider的实施是:

import org.ff4j.FF4j;
import org.ff4j.web.api.FF4JProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/**
 * Created by itaykl on 17/06/2015.
 */
@Component
public class ConsoleFF4jProvider implements FF4JProvider{

    @Autowired
    private FF4j ff4j;

    public ConsoleFF4jProvider() {
    }

    @Override
    public FF4j getFF4j() {
        return ff4j;
    }
}

我的问题是,无论我做什么,我都无法让ff4j自动装配工作。只要ConsoleServlet进入getFF4J()的方法调用,ff4j类成员就会null

我已尝试将其他几个servlet与FF4J控制台一起使用,并尝试以多种方式定义ff4j bean。

目前定义为:

<bean id="ff4j" class="org.ff4j.FF4j" ></bean>

但似乎没有任何效果。

如果有人找到了这个问题的解决方案并且可以分享它,我会非常感激。

2 个答案:

答案 0 :(得分:3)

正如我在评论中所说,当您尝试访问FF4j中的bean时,ConsoleFF4jProvider的构造函数尚未被调用。这是因为Spring首先加载ConsoleFF4jProvider而不加载web.xml中定义的bean。要解决此问题,您可以删除:

@Autowired
private FF4j ff4j;

并修改您的getFF4j()功能,如下所示:

@Override
public FF4j getFF4j() {
    final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
    context.register(FF4j.class); 
    context.refresh();

    FF4j ff4j= context.getBean(FF4j.class);
    return ff4j;
}

或者你也可以在构造函数中初始化ff4j。

修改 否则你可以添加

SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

ConsoleFF4jProvider

的构造函数

希望这能解决您的问题。

答案 1 :(得分:2)

Spring 4注入适用于@Configuration类和@Autowired

问题是Servlet是由Jetty(你的servlet容器)初始化的,这就是为什么ConsoleFF4jProvider不知道Spring上下文。

通过这个例子,你仍然可以使用带有@Autowired的Spring注入机制。

你需要:

  1. 在web.xml中添加一个Spring侦听器。
  2. 创建一个Java类来处理bean FF4j。
  3. 在ConsoleFF4jProvider中注入Spring上下文。
  4. web.xml:

    <web-app 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_3_0.xsd"
        version="3.0">
    
        <display-name>HelloWorld ff4j app</display-name>
    
         <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
        <context-param>
            <param-name>contextClass</param-name>
            <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
        </context-param>
    
        <!-- Configuration using @Configuration classes -->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>foo.bar.ApplicationConfig</param-value>
        </context-param>
    
        <servlet>
            <servlet-name>ff4j-console</servlet-name>
            <servlet-class>org.ff4j.web.embedded.ConsoleServlet</servlet-class>
            <init-param>
                <param-name>ff4jProvider</param-name>
                <param-value>foo.bar.ConsoleFF4jProvider</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>ff4j-console</servlet-name>
            <url-pattern>/ff4j-console</url-pattern>
        </servlet-mapping>
    
        <welcome-file-list>
            <welcome-file>index.jsp </welcome-file>
        </welcome-file-list>
    
    </web-app>
    

    <强> ApplicationConfig.java

    package foo.bar;
    
    import org.ff4j.FF4j;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class ApplicationConfig {
    
        @Bean
        public FF4j getFF4j() {
            return new FF4j("ff4j.xml");
        }
    }
    

    更新了ConsoleFF4jProvider.java

    package foo.bar;
    
    import org.ff4j.FF4j;
    import org.ff4j.web.api.FF4JProvider;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.context.support.SpringBeanAutowiringSupport;
    
    public class ConsoleFF4jProvider implements FF4JProvider {
    
        @Autowired
        private FF4j ff4j;
    
        /**
         * Inject the appropriate Spring bean FF4j declared into
         * {@link ApplicationConfig}. Property {@code ff4j} marked with @Autowired
         * annotation will work.
         */
        public ConsoleFF4jProvider() {
            SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
        }
    
        @Override
        public FF4j getFF4j() {
            return ff4j;
        }
    }