最近使用SpringMVC+Hibernate+Freemarker+Mysql写一个具备基本功能的内容管理系统sdlightcms。在写自定义标签时需要使用自动注解的bean,找到一方法,却发现,每调用一次程序池就初始化一次,最后把Mysql撑爆,出现Too many connections的错误。最后通过ApplicationContextAware来解决了问题。
如下代码中的channelService
@Component
public class ChannelDirective extends BaseDirective implements TemplateDirectiveModel{
@Autowired
private ChannelServiceI channelService;
@Override
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
Channel channel=channelService.get(1);
//具体实现略
}
}
确认在web.xml里添加包的扫描,但是在调试发现channelService为null折腾好久没解决,选用其他方法:即 普通类中调用自动注解的bean
public class ChannelDirective extends BaseDirective implements TemplateDirectiveModel{
private ChannelServiceI channelService;
private SiteServiceI siteService;
@Override
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
ApplicationContext ac=new FileSystemXmlApplicationContext("classpath:spring.xml","classpath:spring-hibernate.xml");
channelService = ac.getBean(ChannelServiceI.class)
Channel channel=channelService.get(1);
//具体实现略
}
}
可以正常运行获取channelService了,但是发现了一个问题,
channelService = ac.getBean(ChannelServiceI.class)
每执行一次就程序池就初始化一次,Console输出信息
[INFO][2016-01-19 14:13:33,748][com.alibaba.druid.pool.DruidDataSource]{dataSource-97} inited
Mysql就多一条连接,如果连接数量超过Mysql的max_connections值,就会报错
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
这个时候增大Mysql的max_connections值是没意义的,再多也会被撑死,只有想其他方法。
找度娘查到了这篇文章http://blog.csdn.net/majian_1987/article/details/11170841
经过一番调试找到解决方法。
解决方法:
定义一个类实现接口ApplicationContextAware
package sdlight.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class SpringContextHelper implements ApplicationContextAware {
private static ApplicationContext context = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextHelper.context = applicationContext;
}
public static <T> Object getBean(Class<T> requireType){
return context.getBean(requireType);
}
}
在spring.xml里添加Bean
<bean id="springContextHelper" class="sdlight.utils.SpringContextHelper"></bean>
当需要使用自动注解的Bean时就可以这样调用,如
channelService =(ChannelServiceI)SpringContextHelper.getBean(ChannelServiceI.class);
经测试,完美解决问题。