spring 容器加载后执行,关键是实现 ApplicationListener<ContextRefreshedEvent> (这个事件有几种,可以拓展下)。
在Spring中已经定义了五个标准事件,分别介绍如下:
1)ContextRefreshedEvent:当ApplicationContext初始化或者刷新时触发该事件。
2)ContextClosedEvent:当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
3) RequestHandleEvent:在Web应用中,当一个http请求(request)结束触发该事件。
ContestStartedEvent:Spring2.5新增的事件,当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。
5)ContestStopedEvent:Spring2.5新增的事件,当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import com.pacs.components.damon.model.UploadFileEntity;
/**
* <!-- 同步图片程序 spring框架一初始化完成即开始执行 -->
*
* @since 2016-09-22
*/
public class SynUpload implements ApplicationListener<ContextRefreshedEvent>{
private Logger logger = Logger.getLogger(SynUpload.class);
private String ftpDirectory;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
/*
* 系统两种容器:root application context 和项目名-servlet context ;
* 下面代码防止执行两次
*/
if(event.getApplicationContext().getParent() == null){
//需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。
logger.info(" *********开始启动同步图片程序********");
BlockingQueue<UploadFileEntity > blockingQueue = new LinkedBlockingQueue<UploadFileEntity>(10); //队列容量暂定为10
// ExecutorService service = Executors.newCachedThreadPool();
// Producer produce1 = new Producer(blockingQueue,ftpDirectory);
// Consumer consumer1 = new Consumer(blockingQueue);
// service.submit(produce1);
// service.submit(consumer1);
Thread producer = new Thread(new Producer(blockingQueue,ftpDirectory));
Thread consumer = new Thread(new Consumer(blockingQueue));
producer.start();
consumer.start();
}
}
public String getFtpDirectory() {
return ftpDirectory;
}
public void setFtpDirectory(String ftpDirectory) {
this.ftpDirectory = ftpDirectory;
}
}
由于用到了线程,所以在注入的时候会出现问题,注册不成功。下面可以自定义类来获取bean。
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class SpringApplicationContextHolder implements ApplicationContextAware {
private static Logger log = Logger.getLogger(SpringApplicationContextHolder.class);
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
SpringApplicationContextHolder.context = context;
}
public static Object getSpringBean(String beanName) {
if(beanName == null || beanName =="") log.debug("beanName不能为空!");
return context==null?null:context.getBean(beanName);
}
public static String[] getBeanDefinitionNames() {
return context.getBeanDefinitionNames();
}
}
当然,别忘了把这两个类配置成bean。
<!-- 同步图片程序 spring框架一初始化完成即开始执行 -->
<bean id="synUpload" class="com.components.damon.SynUpload">
<property name="ftpDirectory">
<value>/doc/</value>
</property>
</bean>
<bean class="com.pacs.util.SpringApplicationContextHolder"></bean>
关于生产者消费者两个线程类,就不贴出来了,按个人要求实现,或者网上搜索怎么写。
本文主要说明两点:第一,spring容器启动后执行特定任务;第二,此时,如果特定任务涉及到线程,那么可以注入的时候可能失败,就需要我们自己实现一个类来获取加载bean。