Java类中的Grails @Autowire不起作用

我有一些 Java 代码,我想将其转换为可在 Grails 控制器中使用的 Bean.通过依赖注入提供服务.该代码基于 here (作为独立运行时工作正常Java 应用程序).

I have some Java code that I want to turn into a Bean that can be used within Grails controllers & services via dependency injection. The code is based on that here (which works fine when run as a standalone Java application).

具体来说,我有:

// WannabeABeanDB.java
package hello;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.kernel.impl.util.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.core.GraphDatabase;

import java.io.File;

@Component
@Configuration
@EnableNeo4jRepositories(basePackages = "hello")
public class WannabeABeanDB extends Neo4jConfiguration {

    public WannabeABeanDB() {
        setBasePackage("hello");
    }

    @Bean
    GraphDatabaseService graphDatabaseService() {
        return new GraphDatabaseFactory().newEmbeddedDatabase("accessingdataneo4j.db");
    }

    @Autowired
    PersonRepository personRepository;

    @Autowired
    GraphDatabase graphDatabase;

    public String testThatWeCanAccessDatabase() throws Exception {
        Person greg = new Person("Greg");

        Transaction tx = graphDatabase.beginTx();
        try {
            personRepository.save(greg);
            greg = personRepository.findByName("Greg").toString();
            tx.success();
        } finally {
            tx.close();
        }
        return greg.name;

    }    
}



// Person.java
package hello;

import java.util.HashSet;
import java.util.Set;

import org.neo4j.graphdb.Direction;
import org.springframework.data.neo4j.annotation.Fetch;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;

@NodeEntity
public class Person {

    @GraphId Long id;
    public String name;

    public Person() {}
    public Person(String name) { this.name = name; }

    public String toString() {
        return this.name;
    }
}



// PersonRepository.java
package hello;

import org.springframework.data.repository.CrudRepository;

public interface PersonRepository extends CrudRepository<Person, String> {    
    Person findByName(String name);    
}

所以现在我想从控制器中使用:

So now I want to use from a controller:

// TestController.groovy
package hello

import hello.WannabeABeanDB

class TestController {

WannabeABeanDB graph

def index() { 
    render graph.test()
    }
}

我已经设置(在 Config.groovy 中):

I've set (within Config.groovy):

grails.spring.bean.packages = ['hello']

但是,当我执行 grails 运行应用程序时,Grails 崩溃并显示一条很长的错误消息,指出它无法使用空数据库.我不相信PersonRepository 或graphDatabase 都会使用@Autowire.

However, when I do a grails run-app, Grails crashes with a very long error message that says it can't work with a null database. I don't believe the @Autowire is being picked up for either PersonRepository or for graphDatabase.

所以问题是,我还需要做些什么才能将使用 Java 代码(在 src/java 中)编写为 Grails 控制器或服务中的 Bean?

So the question is, what more do I need to do to be able to write use Java code (within src/java) as a Bean within a Grails controller or service?

推荐答案

--根据示例代码编辑答案--

-- Editing answer based on the sample code --

我怀疑这个问题与组件扫描如何与 Grails 和 Java 代码混合在一起工作有关.它也可能与在这种情况下创建 bean 的顺序和幕后类的代理有关.

I suspect the issue is related to how component scanning works with Grails and Java code mixed together. It might also have to do with the order in which beans are created in this situation and proxying of classes behind the scenes.

我做了以下更改来完成这项工作:

I made the following changes to make this work:

  1. 我回到 neo4j xml 配置并添加了一个带有必要 neo4j 配置的 grails-app/conf/resources.xml.

  1. I went back to neo4j xml configuration and added a grails-app/conf/resources.xml with necessary neo4j configuration.

从类中移除了@EnableNeo4jRepositories 注解

Removed the @EnableNeo4jRepositories annotation from the class

从Config.groovy中取出语句——grails.spring.bean.packages = ['grailsS​​dn4j']

Took out statement from Config.groovy -- grails.spring.bean.packages = ['grailsSdn4j']

供他人参考,resources.xml中的neo4j配置如下:

For others' reference, the neo4j configuration in resources.xml looks like this:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
       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
        http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd">

    <context:spring-configured/>
    <context:annotation-config/>

    <neo4j:config storeDirectory="target/data/db" base-package="grailsSdn4j"/>

    <neo4j:repositories base-package="grailsSdn4j"/>
</beans>

相关文章