0

我有一个春季班。

@Service("dbManager") 
@Repository
@Transactional
public class DatabaseManager {

    GenericXmlApplicationContext context;

    @PersistenceContext
    private EntityManager em;

    public DatabaseManager(GenericXmlApplicationContext context) {
        this.context = context;
    }

        ....
} //end of class DatabaseManager

我有 SpringUtil 类

public class SpringUtil {

    public static GenericXmlApplicationContext loadSpringContext(String springXmlFile) {    

        GenericXmlApplicationContext context = new GenericXmlApplicationContext();
        context.load(springXmlFile);
        context.refresh();

        return context;

    } //end of loadSpringContext()

} //end of class SpringUtil

现在主要我正在使用类似的东西

public class Regulator  {

    public static void main( String[] args ) {

        Test test = new Test;
        test.start();

    } //end of main()

} //end of class Regulator

这是测试类

public class Test {

    public void start() {

        String springXmlFile = "classpath:spring/plcb-app-context-xml.xml";
        GenericXmlApplicationContext context = SpringUtil.loadSpringContext(springXmlFile);

    } //end of reportStudent()

 } //end of class Test

但我收到错误

Could not instantiate bean class [...DatabaseManager]: No default constructor 
found; nested exception is java.lang.NoSuchMethodException: 
...DatabaseManager.<init>()

我希望在DatabaseManager创建类时,我创建的 spring 上下文SpringUtil.loadSpringContext(springXmlFile)必须传递给它。我该怎么做 ?

谢谢

编辑 - - - - - - - - - -

public void switchDataSource(DatabaseType databaseType) {

    DriverManagerDataSource dataSource = null;

    if (databaseType == DatabaseType.LEGACY) {

        dataSource = (DriverManagerDataSource)context.getBean("myLegacyDataSource");

    } else if (databaseType == DatabaseType.LS360) {

        dataSource = (DriverManagerDataSource)context.getBean("myLs360DataSource");

    }

    LocalContainerEntityManagerFactoryBean emf = context.getBean("myEmf", LocalContainerEntityManagerFactoryBean.class);
    emf.setDataSource(dataSource);

}

@SuppressWarnings("unchecked")
@Transactional(readOnly=true)
public List<Object> getResultList(String query, Class mappingClass) throws Exception {

    Query emQuery = em.createNativeQuery(query, mappingClass);

    return  emQuery.getResultList();

} //end of findTraineeFromLegacy()

实际上,我的 DatabaseManager 类中有这两种方法。我正在设置上下文,所以我可以从switchDataSource()方法中的上下文中获取 bean。

我可以做的一件事是删除实例文件并将方法更改为

public void switchDataSource(DatabaseType databaseType, GenericXmlApplicationContext context) {
     ....
}

这就是我这样做的原因?

谢谢

4

1 回答 1

2

有一个用于 DatabaseManager 的无参数构造函数。

在 DatabaseManager 中实现 ApplicationContextAware。Spring 将知道这个 bean 需要通知应用程序上下文:

@Service("dbManager") 
@Repository
@Transactional
public class DatabaseManager implements ApplicationContextAware {

    private ApplicationContext context;
    public DatabaseManager() {...}

    @Override
    public void setApplicationContext(ApplicationContext appContext) {
        this.context = appContext;
    }
} //end of class DatabaseManager

但是,请仔细考虑您是否真的需要注入。在大多数情况下,你做错了什么。


更新:

对于您在更新中的要求,您希望您的数据库管理器根据输入类型切换数据源,尽管这样做似乎不太正常,您可以简单地让您的数据库管理器注入 Map 并做任何您想做的事情,而不是注入应用程序上下文。

@Service("dbManager") 
@Repository
@Transactional
public class DatabaseManager implements ApplicationContextAware {

    @Resource("&emfBean")
    private LocalContainerEntityManagerFactoryBean emfBean;

    @Resource("dbManagerDsMap")
    private Map<DatabaseType, Datasource> dsMapping;

    public DatabaseManager() {...}

    public void switchDataSource(DatabaseType databaseType) {
        emfBean.setDatasource(dsMapping.get(databaseType));
    }

} //end of class DatabaseManager

但是我强烈建议你不要这样做。考虑为您要连接的每个数据库设置单独的 entityManagerFactory,并使用正确的 emf 连接到数据库,而不是执行这种奇怪的切换逻辑。我相信它不应该在您的应用程序开始后更改。

于 2013-07-24T10:09:08.253 回答