2012-12-17 645 views
0

我想创建一个泛型类,它将帮助我减少样板代码。我正在使用Spring 3(MVC)和Hibernate 4。如何实例化泛型spring bean?

类看起来是这样的:

@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,但如果可能的话,仍然会对它进行spring管理。

+0

你看过SpringData吗?您不必为存储库编写像这样的泛型类。 –

回答

0

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

0

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

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

使用Spring的主要做法之一是消除对象的瞬间。我们应该在Spring配置中指定所有东西,以便Spring在我们需要时为我们实例化对象。但在您使用通用方法的情况下,您需要。

+0

我实现了ApplicationContextAware接口,但我在默认的构造函数中得到了NullPointer异常。 –

+0

请提供你的修改代码。 – shazin

+0

这里是:http://pastebin.com/3wh5vAtk –

1

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

由于@Repository是构造型,Spring容器将执行类路径扫描,添加它的bean定义并注入它的依赖关系。

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