2013-06-05 61 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