简体   繁体   English

如何实例化通用Spring bean?

[英]How to instantiate generic spring bean?

I'm trying to create a generic class that will help me reduce boilerplate code. 我正在尝试创建一个通用类,该类将帮助我减少样板代码。 I'm using Spring 3 (MVC) and Hibernate 4 for this. 我为此使用Spring 3(MVC)和Hibernate 4。

Class looks like this: 类看起来像这样:

@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;
    }

}

I'm instantiating bean like this: 我像这样实例化bean:

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

If I run the code, I'm getting "no default constructor found" exception. 如果我运行代码,则会收到“未找到默认构造函数”异常。 If I add a default constructor I'm getting null pointer exception at this line: 如果添加默认构造函数,则在此行将得到空指针异常:

Session session = sessionFactory.getCurrentSession();

Why is this and how can I solve this problem? 为什么会这样,我该如何解决呢? I'm guessing the problem is because bean is not getting instantiated by Spring itself so it can't autowire fields. 我猜问题是因为Spring本身没有实例化bean,所以它不能自动装配字段。 I would like to instantiate bean myself but still have it spring managed if possible. 我想自己实例化bean,但如果可能的话,仍要在春季进行管理。

Make Sure you have added <context:component-scan base-package='package name'> in your xml bean definition file. 确保在xml bean定义文件中添加了<context:component-scan base-package='package name'>

As @Repository is stereotype, Spring container will do classpath scanning , add it's bean definition and injects it's dependencies. 由于@Repository是构造型,因此Spring容器将进行类路径扫描,添加其bean定义并注入其依赖项。

Later you can get handle of bean from ApplicationContext with bean name (AutoComplete). 稍后,您可以从ApplicationContext使用bean名称(AutoComplete)获得bean的句柄。

Spring container will instantiate this bean for you,in that case,sessionFactory will be injected. Spring容器将为您实例化此bean,在这种情况下,将注入sessionFactory。 You instantiate this bean by your own code: new AutoComplete(),of course sessionFactory is null. 您可以通过自己的代码实例化此bean:new AutoComplete(),当然sessionFactory为null。

Never instantiate classes with fields which has @Autowired annotation. 切勿使用带有@Autowired批注的字段实例化类。 If you do that field will result in null. 如果这样做,该字段将为空。 What you should do is that you should get a reference to ApplicationContext of Spring (you can do this by implementing ApplicationContextAware interface) and use the following code in your AutoComplete class's default constructor. 您应该做的是应该获得对Spring的ApplicationContext的引用(可以通过实现ApplicationContextAware接口来实现此目的),并在AutoComplete类的默认构造函数中使用以下代码。

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

One of the major practice while using Spring is eliminating instantition of objects by ourselves. 使用Spring的主要实践之一是自己消除对象的实例化。 We should specify everything in spring configuration so that Spring will instantiate objects for us when we need. 我们应该在spring配置中指定所有内容,以便Spring在需要时为我们实例化对象。 But in your case with the Generic approach you need to. 但是,对于通用方法,您需要这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM