看起来我的Spring容器已初始化两次。这不好!我发现这一点的方式是从C3P0连接池获取连接。我在Spring上下文中有一个C3P0 ComboPooledDataSource。
@Bean
@Named("comboPooledDataSource")
public ComboPooledDataSource comboPooledDataSource() {
Properties properties = properties();
String environment = getEnvironment();
ComboPooledDataSource pool = new ComboPooledDataSource();
try {
pool.setDriverClass(properties.getProperty("com.pledgeling.platform.db.driver"));
} catch (PropertyVetoException e) {
e.printStackTrace();
}
pool.setJdbcUrl(properties.getProperty("com.company.db.dsn." + environment));
pool.setUser(properties.getProperty("com.company.db.user." + environment));
pool.setPassword(properties.getProperty("com.company.db.pass." + environment));
pool.setMaxIdleTimeExcessConnections(30 * 60);
pool.setMaxIdleTime(3 * 60 * 60);
try {
Connection testConnection = null;
testConnection = pool.getConnection();
System.out.println("Initialized Data Source " + testConnection.toString());
testConnection.close();
} catch (SQLException e) {
e.printStackTrace();
}
return pool;
}
当容器初始化时,它可以正常工作:
Dec 03, 2013 4:43:49 PM com.mchange.v2.log.MLog <clinit>
INFO: MLog clients using java 1.4+ standard logging.
Dec 03, 2013 4:43:49 PM com.mchange.v2.c3p0.C3P0Registry banner
INFO: Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]
Dec 03, 2013 4:43:50 PM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
INFO: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> z8kflt8y1fq2h6a1npdfoy|7dd8fdd6, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> org.postgresql.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> z8kflt8y1fq2h6a1npdfoy|7dd8fdd6, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> ..., maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 10800, maxIdleTimeExcessConnections -> 1800, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
Initialized Data Source com.mchange.v2.c3p0.impl.NewProxyConnection@2df8e5e4
Dec 03, 2013 4:43:50 PM org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext: initialization completed in 5795 ms
但是,我第一次通过webapp访问数据库时,再次建立连接,我不知道为什么。以下是在我的DAO类中抓取连接池的代码
private static ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
private static Connection getConnection() {
ComboPooledDataSource comboPooledDataSource = (ComboPooledDataSource)context.getBean("comboPooledDataSource");
try {
return comboPooledDataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
当它被击中时,整个容器似乎再次初始化:
Dec 03, 2013 4:46:28 PM org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider registerDefaultFilters
INFO: JSR-330 'javax.inject.Named' annotation found and supported for component scanning
Dec 03, 2013 4:46:28 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@db03ddc: startup date [Tue Dec 03 16:46:28 EST 2013]; root of context hierarchy
Dec 03, 2013 4:46:28 PM org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider registerDefaultFilters
INFO: JSR-330 'javax.inject.Named' annotation found and supported for component scanning
Dec 03, 2013 4:46:29 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Dec 03, 2013 4:46:29 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@4c84f510: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,config,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,properties,jaxRsServer,comboPooledDataSource,cxf,jaxRsApiApplication,jsonProvider,serverHealthCheck,applicationHealthCheck]; root of factory hierarchy
Dec 03, 2013 4:46:30 PM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
INFO: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> z8kflt8y1fq2h6a1npdfoy|e9fd18b, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> org.postgresql.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> z8kflt8y1fq2h6a1npdfoy|e9fd18b, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> ... , maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 10800, maxIdleTimeExcessConnections -> 1800, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
Initialized Data Source com.mchange.v2.c3p0.impl.NewProxyConnection@636ab40a
请注意:我已经使用@Inject或@Autowired语法取得了成功,所以如果这部分解决方案请告诉我在哪里以及如何使用它们。还有一点需要注意:这是一个嵌入式码头9弹簧3零XML uberjar。所有注释都被驱动。
Spring容器在Jetty启动时初始化一次,但我不知道它为什么第二次初始化。
public class JettyStarter {
public static void main(final String[] args) throws Exception {
Server server = new Server(8080);
final ServletHolder servletHolder = new ServletHolder(new CXFServlet());
final ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
context.addServlet(servletHolder, "/application/*");
context.addEventListener(new ContextLoaderListener());
context.setInitParameter("contextClass", AnnotationConfigWebApplicationContext.class.getName());
context.setInitParameter("contextConfigLocation", Config.class.getName());
server.setHandler(context);
server.start();
server.join();
}
}
答案 0 :(得分:1)
已注册的ContextLoaderListener
context.addEventListener(new ContextLoaderListener());
将使用指定的AnnotationConfigWebApplicationContext
类
@Configuration
实例
context.setInitParameter("contextClass", AnnotationConfigWebApplicationContext.class.getName());
context.setInitParameter("contextConfigLocation", Config.class.getName());
这将加载一次上下文。
您还在这里加载上下文的第二个副本
private static ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
当加载并初始化包含此成员的类时,会发生这种情况。