Spring 注入不适用于 FF4J Web 控制台
Spring injection not working for FF4J web console
我正在尝试让 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
class 成员是 null
.
我尝试将其他几个 servlet 与 FF4J 控制台一起使用,并尝试以多种方式定义 ff4j
bean。
目前定义为:
<bean id="ff4j" class="org.ff4j.FF4j" ></bean>
但似乎没有任何效果。
如果有人找到解决此问题的方法并分享,我将不胜感激。
正如我在评论中所说,当您尝试访问 ConsoleFF4jProvider
中的 bean 时,尚未调用 FF4j
的构造函数。这是因为 Spring 首先加载 ConsoleFF4jProvider
而不是 web.xml
中定义的 beans。要解决此问题,您可以删除:
@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
的构造函数
希望这能解决您的问题。
Spring 4 注入与@Configuration class 和@Autowired
一起工作
问题是 servlet 是由 Jetty(您的 servlet 容器)初始化的,这就是 ConsoleFF4jProvider 不知道 Spring 上下文的原因。
在这个例子中,您仍然可以使用 Spring 注入机制和 @Autowired。
您需要:
- 在 web.xml 中添加一个 Spring 侦听器。
- 创建一个Java class来处理bean FF4j。
- 在 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;
}
}
对我来说,如果在 servlet 容器中引用 FF4J,它的工作方式如下所示。只需重写配置函数并获取定义 FF4j 的 FF4jConfig class。
@Configuration
public class FF4jWebConsoleConfiguration extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(FF4JConfig.class); //scan
}
// autowired working here
@Bean
public FF4jDispatcherServlet ff4jDispatcherServlet(@Autowired FF4j 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
class 成员是 null
.
我尝试将其他几个 servlet 与 FF4J 控制台一起使用,并尝试以多种方式定义 ff4j
bean。
目前定义为:
<bean id="ff4j" class="org.ff4j.FF4j" ></bean>
但似乎没有任何效果。
如果有人找到解决此问题的方法并分享,我将不胜感激。
正如我在评论中所说,当您尝试访问 ConsoleFF4jProvider
中的 bean 时,尚未调用 FF4j
的构造函数。这是因为 Spring 首先加载 ConsoleFF4jProvider
而不是 web.xml
中定义的 beans。要解决此问题,您可以删除:
@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
希望这能解决您的问题。
Spring 4 注入与@Configuration class 和@Autowired
一起工作问题是 servlet 是由 Jetty(您的 servlet 容器)初始化的,这就是 ConsoleFF4jProvider 不知道 Spring 上下文的原因。
在这个例子中,您仍然可以使用 Spring 注入机制和 @Autowired。
您需要:
- 在 web.xml 中添加一个 Spring 侦听器。
- 创建一个Java class来处理bean FF4j。
- 在 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;
}
}
对我来说,如果在 servlet 容器中引用 FF4J,它的工作方式如下所示。只需重写配置函数并获取定义 FF4j 的 FF4jConfig class。
@Configuration
public class FF4jWebConsoleConfiguration extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(FF4JConfig.class); //scan
}
// autowired working here
@Bean
public FF4jDispatcherServlet ff4jDispatcherServlet(@Autowired FF4j ff4j) {
...
}