0

我正在尝试创建一个通用类来帮助我减少样板代码。我为此使用 Spring 3 (MVC) 和 Hibernate 4。

类看起来像这样:

@Repository("AutoComplete")
public class AutoComplete<T extends Serializable> implements IAutoComplete {

    @Autowired
    private SessionFactory sessionFactory;

    private Class<T> entity;

    public AutoComplete(Class<T> entity) {
        this.setEntity(entity);
    }

    @Transactional(readOnly=true)
    public List<String> getAllFTS(String searchTerm) {
        Session session = sessionFactory.getCurrentSession();
        return null;
    }

    public Class<T> getEntity() {
        return entity;
    }

    public void setEntity(Class<T> entity) {
        this.entity = entity;
    }

}

我正在像这样实例化bean:

IAutoComplete place = new AutoComplete<Place>(Place.class);
place.getAllFTS("something");

如果我运行代码,我会收到“未找到默认构造函数”异常。如果我添加一个默认构造函数,我会在这一行得到空指针异常:

Session session = sessionFactory.getCurrentSession();

为什么会这样,我该如何解决这个问题?我猜这个问题是因为 bean 没有被 Spring 本身实例化,所以它不能自动装配字段。我想自己实例化 bean,但如果可能的话,仍然可以管理它。

4

3 回答 3

1

确保您已<context:component-scan base-package='package name'>在 xml bean 定义文件中添加。

由于@Repository 是原型,Spring 容器将进行类路径扫描,添加它的 bean 定义并注入它的依赖项。

稍后您可以使用 bean 名称(AutoComplete)从 ApplicationContext 获取 bean 的句柄。

于 2013-03-13T11:27:00.500 回答
0

Spring 容器会为你实例化这个 bean,在这种情况下,sessionFactory 会被注入。你用你自己的代码实例化这个bean:new AutoComplete(),当然sessionFactory是null。

于 2012-12-17T12:36:27.990 回答
0

永远不要使用具有 @Autowired 注释的字段来实例化类。如果你这样做,该字段将导致 null。你应该做的是你应该得到一个 Spring 的 ApplicationContext 的引用(你可以通过实现 ApplicationContextAware 接口来做到这一点)并在你的 AutoComplete 类的默认构造函数中使用以下代码。

public AutoComplete() {
    sessionFactory = (SessionFactory) applicationContext.getBean("sessionFactory");
}

使用 Spring 时的主要实践之一是我们自己消除对象的实例化。我们应该在 spring 配置中指定所有内容,以便 Spring 在需要时为我们实例化对象。但是在您的情况下,您需要使用通用方法。

于 2012-12-17T12:38:37.560 回答