将bean注入GraphQL的DataFetcher [英] Inject bean into DataFetcher of GraphQL
问题描述
我正在使用 Spring &我的项目中的graphql-java( graphql-java-annotation )。
对于检索数据部分,我使用DataFetcher从服务(从数据库)获取数据。
I'm using Spring & graphql-java (graphql-java-annotation) in my project. For retrieving data part, i'm using a DataFetcher to get data from a service (from database).
奇怪的是: myService
始终是 null 。有人知道原因吗?
The weird thing is that: myService
is always null. Anyone know the reason?
DataFetcher
@Component
public class MyDataFetcher implements DataFetcher {
// get data from database
@Autowired
private MyService myService;
@Override
public Object get(DataFetchingEnvironment environment) {
return myService.getData();
}
}
架构
@Component
@GraphQLName("Query")
public class MyGraphSchema {
@GraphQLField
@GraphQLDataFetcher(MyDataFetcher.class)
public Data getData() {
return null;
}
}
MyService
@Service
public class MyService {
@Autowired
private MyRepository myRepo;
@Transactional(readOnly = true)
public Data getData() {
return myRepo.getData();
}
}
主要测试
@Bean
public String testGraphql(){
GraphQLObjectType object = GraphQLAnnotations.object(MyGraphSchema.class);
GraphQLSchema schema = newSchema().query(object).build();
GraphQL graphql = new GraphQL(schema);
ExecutionResult result = graphql.execute("{getData {id name desc}}");;
Map<String, Object> v = (Map<String, Object>) result.getData();
System.out.println(v);
return v.toString();
}
推荐答案
因为在graphql-java-中注释数据提取器是由注释定义的,它是由框架构造的(使用反射来获取构造函数),因此它不能是bean。
Since in graphql-java-annotation the data fetcher is defined by annotation, it is constructed by the framework (using reflection to get the constructor), thus it can't be a bean.
我发现的解决方法是将其设置为 ApplicationContextAware
,然后我可以初始化一些静态字段而不是一个豆。不是最好的,但它确实有效:
The workaround I've found for this is setting it as ApplicationContextAware
, and then I can initialize some static field instead of a bean. Not the nicest thing, but it works:
@Component
public class MyDataFetcher implements DataFetcher, ApplicationContextAware {
private static MyService myService;
private static ApplicationContext context;
@Override
public Object get(DataFetchingEnvironment environment) {
return myService.getData();
}
@override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansExcepion {
context = applicationContext;
myService = context.getBean(MyService.class);
}
}
基本上你仍会得到一个新的实例由graphQL初始化的数据获取器,但是spring会初始化它,并且由于 myService
是静态的,你将得到初始化的。
Basically you'll still get a new instance of the data fetcher initialized by graphQL, but also spring will initialize it, and since the myService
is static, you'll get the initialized one.
这篇关于将bean注入GraphQL的DataFetcher的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!