2013-06-05 63 views
0

我正在开发一个简单的Spring MVC应用程序,用于从流式API下载推文并将其显示在网页中。该应用程序的用户可以提交他们想要下载的推文的关键字Task。这些任务是共享的,因此每个人都可以启动,停止,修改,更改或取消任务。Spring服务的后台执行

TwitterFetcher是负责下载推文的类。这个类接收一个任务,并持续下载到数据库中的所有推文。

@Service 
public class TwitterFetcher { 

    @Autowired 
    private OAuthService oAuthService; 

    @Autowired 
    private TweetService tweetService; 

    private Task task; 
    private TwitterStream twitterStream; 

    public void start(Task task) { 
     /* Stop previous stream */ 
     stop(); 

     /* Get OAuth credentials */ 
     OAuth oAuth = oAuthService.findOneEnabled(); 

     if (oAuth == null) { 

     } else { 
      this.task = task; 

      Configuration oAuthConfiguration = getOAuthConfiguration(oAuth); 
      twitterStream = new TwitterStreamFactory(oAuthConfiguration).getInstance(); 
      twitterStream.addListener(new TwitterListener()); 

      String keywords = task.getBaseKeywords() + ", " + task.getExpandedKeywords(); 
      FilterQuery filterQuery = new FilterQuery(); 
      filterQuery.track(keywords.split(", ")); 
      twitterStream.filter(filterQuery); 
     } 
    } 

    public void stop() { 
     if (twitterStream != null) { 
      twitterStream.shutdown(); 
     } 
    } 

    private Configuration getOAuthConfiguration(OAuth oAuth) { 
     ConfigurationBuilder cb = new ConfigurationBuilder(); 
     cb.setDebugEnabled(false); 
     cb.setJSONStoreEnabled(true); 
     cb.setOAuthAccessToken(oAuth.getAccessToken()); 
     cb.setOAuthAccessTokenSecret(oAuth.getAccessTokenSecret()); 
     cb.setOAuthConsumerKey(oAuth.getConsumerKey()); 
     cb.setOAuthConsumerSecret(oAuth.getConsumerSecret()); 

     return cb.build(); 
    } 

    private class TwitterListener implements StatusListener { 

     @Override 
     public void onStatus(Status status) { 
      /* Persist new tweet */ 
      Tweet tweet = new Tweet(); 
      tweet.setJson(DataObjectFactory.getRawJSON(status)); 
      tweetService.save(tweet); 
     } 

     [Omitted code] 
    } 
} 

的基本功能将成为下一个:

  1. 开始于用户从网站上提取程序。
  2. 收件人收到一条新的推文并将其保存在数据库中
  3. 收件人持续接收推文,直到用户停止推文为止。

该应用程序有一个仪表板来控制fetchers和任务,并且用户必须能够在fetcher下载时与它交互。

我的问题是,fetcher会阻止应用程序还是会在不同的线程中执行?在最坏的情况下,我必须改变以解决这个问题?我还远离可用的应用程序,所以我无法测试它。即便如此,如果可能的话,我现在要解决它。

回答

0

您可以使用ExecutorService在单独的线程中运行fetcher。我推荐使用线程池,所以如果过多的用户运行取出器,你不吹性能:

ExecutorService executor = Executors.newFixedThreadPool(maxThreads) 

当一个任务是通过执行提交它会返回一个Future对象,从中可以检查作业完成

Future f = executor.submit(myTask); 
boolean isDone = f.isDone(); 

请阅读更多关于Java并发性,如果你不熟悉:http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html

0

标注您的start()方法与@Async

@Async 
public void start(Task task) 

这将使启动方法异步并且不会阻塞应用程序。

你可以看看一个简单的例子here