将 bean 注入 GraphQL 的 DataFetcher [英] Inject bean into DataFetcher of GraphQL

查看:23
本文介绍了将 bean 注入 GraphQL 的 DataFetcher的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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;
    }
}

我的服务

@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-annotation 中数据 fetcher 是由 annotation 定义的,所以它是由框架构造的(使用反射获取构造函数),因此它可以不是豆子.

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,然后我可以初始化一些静态字段而不是 bean.不是最好的事情,但它有效:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆