How to do it...

Let us now explore the asynchronous side of Spring Data JPA module:

  1. Convert ch12-asyncjpa to a Spring Boot 2.0 application by adding the Spring Boot 2.0.0.M2starter POM dependencies, such as webflux, actuator for project status monitoring and management, Spring JDBC, and MYSQL connector.
  2. Since there is no dedicated Spring Data JPA module for asynchronous repository transactions, add the same starter POM dependencies for Spring Data JPA to pom.xml:
<dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-data-jpa</artifactId> 
</dependency> 
  1. Inside the core package, org.packt.microservice.core, add the following Bootstrap class:
@SpringBootApplication 
public class HRDeptBootApplication  
extends  SpringBootServletInitializer  { 
   // refer to sources 
}
  1. Copy the config folder and logback.xml from the previous project to src/main/resources. Update the log file details of logback.xml.
  2. Inside the src/main/resources directory, add application.properties that contains the same details as the previous Spring Data JPA project. Since we will rely on the auto-increment feature of MySQL for object ID generation, always set spring.jpa.hibernate.use-new-id-generator-mappings to false to allow data persistence.
  3. To configure the Spring Data JPA module, add the following configuration class inside org.packt.microservice.core.config, which will enable JPA transaction management:
@Configuration 
@EnableJpaRepositories( 
      basePackages="org.packt.microservice.core.dao") 
@EnableTransactionManagement 
public class SpringDataConfig { } 
  1. Enable asynchronous features though this configuration class that also generates thread pools through Executor:
@EnableAsync 
@Configuration 
public class SpringAsynchConfig implements AsyncConfigurer { 
    
   private static Logger logger =  
      LoggerFactory.getLogger(SpringAsynchConfig.class); 
         
          @Bean("mvcTaskexecutor") 
         @Override 
           public Executor getAsyncExecutor() { 
            ConcurrentTaskExecutor executor = 
               new ConcurrentTaskExecutor( 
                       Executors.newFixedThreadPool(100));   
            executor.setTaskDecorator(new TaskDecorator() { 
                 @Override 
                 public Runnable decorate (Runnable  
                  runnable) { 
                     return () -> { 
          
                         long t =  
                           System.currentTimeMillis(); 
                         runnable.run(); 
                         logger.info("creating thread  
                           pool...."); 
                         System.out.printf("Thread %s has a  
                        processing time:  %s%n",  
Thread.currentThread().getName(),                             (System.currentTimeMillis() - t)); 
                     }; 
                 } 
             }); 
            return executor; 
      } 
} 
  1. Copy the JPA Department entity model from the previous project to the org.packt.microservice.core.model.data package.
  2. Now, create the DepartmentRepository interface using JpaRepository, showcasing the implementation of asynchronous properties as follows:
@Repository 
public interface DepartmentRepository  
extends JpaRepository<Department, Integer>{ 
       
    @Async 
    public Future<List<Department>>  
findAllByDeptid(Integer deptid); 
     
    @Async 
    public CompletableFuture<Department>  
      findIgnoreCaseByName(String name); 
    
    @Async 
    public ListenableFuture<Department>  
      findDeptById(Integer id); 
 
} 
  1. Then, create a DepartmentService interface that has the following services. Drop this file inside the org.packt.microservice.core.service package:
public interface DepartmentService { 
    
   public List<Department> findAllDeptList(); 
   public Department findAllDeptById(Integer id); 
   public List<Department> findAllByDeptName(String name); 
   public Future<List<Department>>  
findAllByDeptId(Integer deptId); 
   public CompletableFuture<Department>  
      findAllFirstByNameIgnoreCase(String name); 
   public ListenableFuture<Department>  
findAllFirstById(Integer id);   
}
  1. To implement the services, just apply the asynchronous properties from DepartmentRepository:
@Service 
public class DepartmentServiceImpl implements DepartmentService{ 
    
   @Autowired 
   private DepartmentRepository departmentRepository; 
 
   @Override 
   public Future<List<Department>>  
findAllByDeptId(Integer deptId) { 
      return departmentRepository.findAllByDeptid(deptId); 
   } 
 
   @Override 
   public CompletableFuture<Department>  
               findAllFirstByNameIgnoreCase(String name) { 
      return departmentRepository 
.findIgnoreCaseByName(name); 
   } 
 
   @Override 
   public ListenableFuture<Department>  
findAllFirstById(Integer id) { 
      return departmentRepository.findDeptById(id); 
} 
 
   // refer to sources 
} 
  1. We have come to the highlight of this recipe, which is the implementation of the request handlers given the asynchronous data retrieval from DepartmentRepository. These request handlers just reuse the concepts discussed in the previous chapters on how to build callbacks which retrieve the exact data from Future<T>, CompletableFuture<T>, and ListenableFuture<T>.
  2. Create @Controller, bearing all these request methods inside org.packt.microservice.core.controller:
@RestController 
public class DeptAsyncController { 
    
   @Autowired 
   private DepartmentService departmentServiceImpl; 
    
   private Department result = new Department(); 
       
   @GetMapping(value="/webSyncDept/{id}.json",  
produces ="application/json",  
headers = {"Accept=text/xml, application/json"}) 
   public WebAsyncTask<Department> websyncDeptList( 
              @PathVariable("id") Integer id){ 
       
       Callable<Department> callable =  
             new Callable<Department>() { 
         public Department call() throws Exception { 
             
             ListenableFuture<Department> listenFuture =  
               departmentServiceImpl.findAllFirstById(id); 
             listenFuture.addCallback( 
new ListenableFutureCallback<Department>(){ 
 
                @Override 
                public void onSuccess(Department dept) { 
                  result = dept; 
                } 
 
                @Override 
                public void onFailure(Throwable arg0) { 
                  result = new Department(); 
                } 
                 
             }); 
             return result; 
             } 
       }; 
       return new WebAsyncTask<Department>(500, callable); 
   } 
    
   @GetMapping(value="/deferSelectDept/{name}.json",  
produces ="application/json",   
headers = {"Accept=text/xml, application/json"}) 
   public DeferredResult<Department> deferredSelectDept( 
      @PathVariable("name") String name) { 
       DeferredResult<Department> deferredResult =  
            new DeferredResult<>(); 
       CompletableFuture.supplyAsync(()->{ 
         try { 
            return departmentServiceImpl 
             .findAllFirstByNameIgnoreCase(name) 
             .get(500, TimeUnit.MILLISECONDS); 
         } catch (InterruptedException e) { 
            e.printStackTrace(); 
         } catch (ExecutionException e) { 
            e.printStackTrace(); 
         } catch (TimeoutException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
         } 
         return null; 
       }).thenAccept((msg)->{ 
         deferredResult.setResult(msg); 
       }); 
       return deferredResult; 
   } 
   // refer to sources 
} 
  1. Save all files. Then clean, build, and deploy the microservice.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.61.81