我正在将Play Framework 2.2.x中的应用程序重构为Play Framework 2.6.x,并且在应用程序的更新版本中,@ Autowired spring服务为null(我没有使用“new”,因此Spring会混淆)。
AuthentecatedAction类:
@Scope("prototype")
@Component
public class AuthenticatedAction extends Action<Authenticated>
{
private final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
ABCUserService ABCUserService;
@Autowired
AccessTokenService accessTokenService;
@Autowired
AccessTokenValidator accessTokenValidator;
@Override
public CompletionStage<Result> call(Http.Context ctx)
{
AccessToken accessToken;
try {
accessToken = accessTokenService.getAccessTokenFromHeader(ctx._requestHeader().headers());
} catch (Throwable throwable) {
return ResultUtils.handleError(new ValidationException(FORBIDDEN, String.format("Access token service is null. %s", throwable.getMessage())));
}
// Some more code here
}
// Some more code here
}
此处accessTokenService
是@Autowired,但它始终为空。
AccessTokenService类:
@Service
public class AccessTokenService extends JedisBaseService
{
private final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
private ConfigurationService configurationService;
@Autowired
private EncryptionService encryptionService;
@Inject
public AccessTokenService(JedisPool jedisPool) {
super(jedisPool);
}
// some methods
}
JedisBaseService类:
public class JedisBaseService extends Controller
{
private final Logger log = LoggerFactory.getLogger(getClass());
private JedisPool jedisPool;
@Inject
public JedisBaseService(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
// some methods
// TODO: Check that solution with iserting JedisPool works
// See https://github.com/playframework/play-plugins/tree/master/redis for reference
protected Jedis getJedis()
{
return jedisPool.getResource();
}
}
请帮助我理解为什么AuthentecatedAction类accessTokenService
中的@Autowired始终为空。
编辑:
我应该补充一点,我的build.sbt
文件包含以下行:
// https://mvnrepository.com/artifact/org.springframework/spring-context
"org.springframework" % "spring-context" % "4.3.10.RELEASE"
我的routes
文件包含以下行:
POST /accesstokens @api.controller.accesstoken.AccessTokenController.createAccessToken()
DELETE /accesstokens @api.controller.accesstoken.AccessTokenController.deleteAccessToken()
因此,我使用动态控制器调度来管理控制器实例(通过在路由文件中使用@符号作为控制器类名称前缀)。
有一个用于访问令牌的控制器:
@Controller
public class AccessTokenController extends ABCController
{
@Autowired
private AccessTokenService accessTokenService;
@Autowired
private ABCUserService ABCUserService;
@Autowired
private ActivityCreationService activityCreationService;
@Autowired
private LiveUpdateService liveUpdateService;
@BodyParser.Of(BodyParser.TolerantJson.class)
@ResponseContentType(type = "accessToken")
public Result createAccessToken() throws ABCControllerException
{
// Implementation
}
public Result deleteAccessToken() throws ABCControllerException
{
// Implementation
}
}
我的应用程序的全局对象,它委托控制器实例管理:
public class ABCGlobal
{
private final Logger log = LoggerFactory.getLogger(getClass());
protected static ApplicationContext ctx;
private final ActorSystem system;
@Inject
public ABCGlobal(ActorSystem system) {
this.system = system;
}
public static ApplicationContext getApplicationContext()
{
return ctx;
}
public void onStart(Application app)
{
String springConfigurationName = app.configuration().getString("spring.context");
ctx = new ClassPathXmlApplicationContext(springConfigurationName);
log.info("Loading spring configuration: {}", springConfigurationName);
// Some other code
}
// see: http://typesafe.com/blog/announcing-play-framework-21-the-high-velocit
public <A> A getControllerInstance(Class<A> clazz)
{
return ctx.getBean(clazz);
}
// Some other code
}
以下是用于配置Spring的关联conf / components.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="api, service"/>
<context:property-placeholder location="classpath:application-base.conf" />
<context:property-placeholder location="classpath:application.conf" />
<bean class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean" id="resourceConverterFactory">
<property name="serviceLocatorInterface" value="service.resource.conversion.ResourceConverterFactory">
</property>
</bean>
<bean class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean" id="scraperFactory">
<property name="serviceLocatorInterface" value="service.scraping.ScraperFactory">
</property>
</bean>
<bean id="storageService" class="service.storage.impl.MongoGridFSStorageService"/>
<bean id="configurationService" class="service.configuration.impl.PlayConfigurationService">
<constructor-arg value="com.typesafe.config.Config" name="config">
</constructor-arg>
</bean>
<bean id="mailService" class="service.mail.impl.MailGunApiMailService"/>
</beans>
在我的application-base.conf
文件中,我有以下内容:
# Spring configuration
# ~~~~~
# Define what spring context should be used.
spring.context="components.xml"