2013-07-19 36 views
8

Tôi mới thực hiện tác vụ không đồng bộ trong Mùa xuân, vì vậy hãy tha thứ cho tôi nếu điều này nghe có vẻ giống như một câu hỏi ngớ ngẩn.Mùa xuân 3: Cách gọi các phương thức được chú thích @Async từ TaskExecutor

Tôi đọc rằng chú thích @Async được giới thiệu từ Mùa xuân 3.x trở đi ở cấp phương thức để yêu cầu phương thức đó sẽ xảy ra không đồng bộ. Tôi cũng đọc rằng chúng ta có thể cấu hình ThreadPoolTaskExecutor trong tệp cấu hình mùa xuân.

Những gì tôi không thể hiểu được là làm thế nào để gọi một phương thức @Async chú thích từ một người thi hành tak phép giả sử - AsyncTaskExecutor

Trước đó chúng tôi sử dụng để làm một cái gì đó giống như trong một lớp học:

@Autowired protected AsyncTaskExecutor executor; 

và sau đó

executor.submit(<Some Runnable or Callable task>) 

tôi không thể hiểu được mối quan hệ giữa các phương pháp @Async chú thích và TaskExecutor.

Tôi đã cố gắng tìm kiếm rất nhiều trên internet nhưng không thể nhận được bất cứ điều gì về điều này.

Ai đó có thể cung cấp ví dụ giống nhau.

Trả lời

29

Dưới đây là một ví dụ về @Async sử dụng:

@Async 
void doSomething() { 
    // this will be executed asynchronously 
} 

Bây giờ gọi đó là phương pháp từ một lớp khác và nó sẽ chạy không đồng bộ. Nếu bạn muốn có một giá trị trả về sử dụng một Future

@Async 
Future<String> returnSomething(int i) { 
    // this will be executed asynchronously 
} 

Mối quan hệ giữa @AsyncTaskExecutor@Async sử dụng một TaskExecutor đằng sau hậu trường. Từ tài liệu:

Theo mặc định khi chỉ định @Async trên phương thức, người thực thi sẽ được sử dụng là phần tử được cung cấp cho phần tử 'chú thích hướng' như được mô tả ở trên. Tuy nhiên, thuộc tính giá trị của chú thích @Async có thể được sử dụng khi cần chỉ ra rằng một người thực thi không phải là mặc định sẽ được sử dụng khi thực hiện một phương thức nhất định.

Vì vậy, để thiết lập một chấp hành viên mặc định, thêm video này vào cấu hình mùa xuân của bạn

<task:annotation-driven executor="myExecutor" /> 

Hoặc sử dụng một chấp hành viên đặc biệt đối với một single use thử

@Async("otherExecutor") 

Xem http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/scheduling.html#scheduling-annotation-support-async

+0

Tôi đọc tài liệu quá nhưng tôi không hoàn toàn hiểu được làm thế nào mà liên quan đến Runnables? Tôi có cần đánh dấu một cái gì đó bằng Runnable và thực hiện một phương thức chạy hay không cần thiết? –

+0

Bạn không cần. Chỉ cần đánh dấu phương thức mà bạn muốn chạy không đồng bộ với @Async và khi bạn gọi nó, nó sẽ chạy không đồng bộ. – Planky

+0

@Planky Điều này thật tuyệt. Nhưng khi tôi đang làm tương tự bằng cách sử dụng một ứng dụng mùa xuân chính và đơn giản nhất bằng cách lấy bean như ApplicationContext = new ClassPathXml ...(). và thực hiện lời gọi async. Nó được gọi phương thức trong thread riêng biệt, cho đến khi điều này là tốt. Nhưng chương trình không phải là thoát, tôi có nghĩa là sau khi thực hiện dòng cuối cùng của chương trình chính vẫn còn sống. Tôi đã cố gắng để giữ cho sống còn 2 giây nhưng vô ích. Tôi chạy chương trình trong chế độ chạy không có trong nút gỡ lỗi. Bất kỳ cái nhìn sâu sắc về điều này? Nếu bạn muốn tôi có thể đăng các mã trong qstn riêng biệt. – anirban

0

Trong tệp cấu hình, người ta nên đề cập đến tác vụ hướng chú thích với tên và phương thức của nhóm luồng có @Async (tên nhóm) wil l được thực hiện như một phần của hồ bơi đó. Điều này tạo ra một lớp proxy cho một trong đó có chú thích @Async và thực hiện nó cho mỗi luồng.

+0

âm thanh giống như nhận xét hơn là câu trả lời. Bạn có thể chỉ định thêm một chút không? –

+0

vâng đó là một bình luận, Planky đã đưa ra câu trả lời. –

0

Bạn có thể thêm @Async vào phương thức của mình và các tùy chọn sau vào ngữ cảnh Ứng dụng của bạn.

<task:annotation-driven executor="asynExecutor"/> 
    <task:executor id="asynExecutor" pool-size="5" /> 
1

Hoàn Ví dụ

  1. Config Xuân

    @Configuration   
    @EnableAsync   
    @ComponentScan("com.async") 
    public class AppConfig { 
    
        @Bean 
        public AsyncManager asyncManger() { 
         return new AsyncManager(); 
        } 
    
        @Bean 
        public AsyncExecutor asyncExecutor() { 
         return new AsyncExecutor(); 
        } 
    } 
    
  2. Executor Lớp tạo, Executor tôi đã tạo nên mùa xuân mà sẽ chăm sóc quản lý chủ đề.

    public class AsyncExecutor extends AsyncConfigurerSupport { 
    
        @Override 
        public Executor getAsyncExecutor() { 
         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 
         executor.setCorePoolSize(2); 
         executor.setMaxPoolSize(2); 
         executor.setQueueCapacity(500); 
         executor.setThreadNamePrefix("Violation-"); 
         executor.initialize(); 
         return executor; 
        } 
    } 
    
  3. Tạo người quản lý.

    public class AsyncManager { 
    
        @Autowired 
        private AsyncService asyncService; 
    
        public void doAsyncTask(){ 
         try { 
          Map<Long, ViolationDetails> violation = asyncService.getViolation(); 
          if(!org.springframework.util.CollectionUtils.isEmpty(violation)){ 
           violation.entrySet().forEach(violationEntry -> {System.out.println(violationEntry.getKey() +"" +violationEntry.getValue());}); 
          } 
          System.out.println("do some async task"); 
         } catch (Exception e) { 
         } 
    
        } 
    } 
    
  4. Định cấu hình lớp dịch vụ của bạn.

    @Service 
    public class AsyncService { 
    
        @Autowired 
        private AsyncExecutor asyncExecutor; 
    
        @Async 
        public Map<Long,ViolationDetails> getViolation() { 
         // TODO Auto-generated method stub 
         List<Long> list = Arrays.asList(100l,200l,300l,400l,500l,600l,700l); 
         Executor executor = asyncExecutor.getAsyncExecutor(); 
         Map<Long,ViolationDetails> returnMap = new HashMap<>(); 
         for(Long estCode : list){ 
          ViolationDetails violationDetails = new ViolationDetails(estCode); 
          returnMap.put(estCode, violationDetails); 
          executor.execute((Runnable)new ViolationWorker(violationDetails)); 
         } 
         return returnMap;  
        } 
    } 
    class ViolationWorker implements Runnable{ 
    
        private ViolationDetails violationDetails; 
    
        public ViolationWorker(ViolationDetails violationDetails){ 
         this.violationDetails = violationDetails; 
        } 
    
        @Override 
        public void run() { 
         violationDetails.setViolation(System.currentTimeMillis()); 
         System.out.println(violationDetails.getEstablishmentID() + " " + violationDetails.getViolation()); 
        } 
    } 
    
  5. Mô hình.

    public class ViolationDetails { 
        private long establishmentID; 
        private long violation; 
    
    
        public ViolationDetails(long establishmentID){ 
         this.establishmentID = establishmentID; 
        } 
    
        public long getEstablishmentID() { 
         return establishmentID; 
        } 
        public void setEstablishmentID(long establishmentID) { 
         this.establishmentID = establishmentID; 
        } 
        public long getViolation() { 
         return violation; 
        } 
        public void setViolation(long violation) { 
         this.violation = violation; 
        } 
    
    } 
    
  6. thử nghiệm để chạy

    public class AppTest { 
        public static void main(String[] args) throws SQLException { 
         AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); 
         ctx.register(AppConfig.class); 
         ctx.refresh(); 
    
         AsyncManager task= ctx.getBean(AsyncManager.class); 
         task.doAsyncTask(); 
        } 
    } 
    
Các vấn đề liên quan