Есть веб-приложение, в котором в файле web.xml определены два сервлета.
Есть пул соединений c3p0, который, как я понимаю, должен инициализироваться один раз.
НО! Если обратиться к одному сервлету, а потом к другому, то пул будет инициализирован дважды и на каждый сервлет окажется свой пул.
Как это исправить, чтобы пул был общим?
Конфигурация application-context.xml :
Конфигурация сервлета 1:
Конфигурация сервлета 2:
Описание бинов для application-context:
package ru.rusal.mishka.core;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.eclipse.persistence.jpa.PersistenceProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import javax.persistence.EntityManagerFactory;
import javax.persistence.ValidationMode;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
import java.util.Properties;
@Configuration
public class ContextConfiguration {
@Bean
public DataSource dataSource(
@Qualifier("systemConfiguration") SystemConfiguration systemConfiguration
) throws PropertyVetoException {
Properties props = new Properties();
props.setProperty("user", systemConfiguration.getDBConfig().getUser());
props.setProperty("password", systemConfiguration.getDBConfig().getPassword());
final ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("oracle.jdbc.OracleDriver");
dataSource.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:DB");
dataSource.setInitialPoolSize(5);
dataSource.setMaxPoolSize(20);
dataSource.setProperties(props);
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
@Qualifier("dataSource") DataSource ds
) {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setPersistenceUnitName("MilliService");
factoryBean.setDataSource(ds);
factoryBean.setPersistenceProviderClass(PersistenceProvider.class);
factoryBean.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
factoryBean.setValidationMode(ValidationMode.NONE);
factoryBean.setPackagesToScan("ru.milli.app.persistence");
factoryBean.getJpaPropertyMap().put("eclipselink.weaving", Boolean.FALSE.toString());
factoryBean.getJpaPropertyMap().put("eclipselink.allow-zero-id", Boolean.TRUE.toString());
return factoryBean;
}
@Bean
public JpaTransactionManager transactionManager(
@Qualifier("entityManagerFactory") EntityManagerFactory factory
) throws PropertyVetoException {
JpaTransactionManager manager = new JpaTransactionManager();
manager.setEntityManagerFactory(factory);
return manager;
}
}
Для сервлетов там обычные rest-сервисы на аннотациях @RestController.
Конфиг web.xml:
Ответ
Проблема в том, что вы создаёте 2 DispatcherServlet, и в оба включаете application-context.xml. Согласно документации
A web application can define any number of DispatcherServlets. Each servlet will operate in its own namespace, loading its own application context with mappings, handlers, etc.
У каждого DispatcherServlet будет свой контекст Spring, а значит, бины для каждого будут создаваться по отдельности. Тег
Решить это можно, создав root контекст с бинами, необходимыми всем дочерним контекстам. Делается это при помощи добавления ContextLoaderListener в web.xml
Все бины, определённые в root контексте, будут видны в дочерних (web application) контекстах. При этом дочерний контекст может переопределить бин из родительского контекста (объявив свой бин с таким же id), поэтому включать application-context.xml в конфиг каждого сервлета при такой конфигурации не нужно.
Комментариев нет:
Отправить комментарий