1

我试图让 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>

但似乎没有任何效果。

如果有人找到解决此问题的方法并可以分享,我将不胜感激。

4

2 回答 2

3

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

@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

希望这能解决您的问题。

于 2015-06-24T11:55:54.830 回答
2

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

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

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

你需要 :

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

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;
    }
}
于 2015-09-15T14:43:49.093 回答