在参加了@CopusBowersox的针对Java开发人员的Spring Data的Infinite Skills课程之后,唯一似乎没有像宣传的那样工作的部分是Async方法。请注意,在课程开始时,他介绍了xml和Java配置,但他在整个课程的其余部分继续使用xml配置,而我继续使用Java配置进行每个练习,并且能够获得所有其他部分工作。一个小的区别是我使用IntelliJ IDEA而不是STS,正如他在整个课程中使用的那样。
如果有任何熟悉Spring Data异步查询或其课程(https://www.safaribooksonline.com/library/view/spring-data-for/9781771375924/video241705.html)的人对可能遗漏的内容有所了解,请告知我们。
以下是相关位:
/ * Application.java * /
@EnableAsync
public class Application {
public static void main(String[] args) throws ParseException {
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
DataConfiguration.class)) {
BookRepository repository = context.getBean(BookRepository.class);
// TODO: Make method Async
for (long x = 0; x < 4; x++) {
repository.findByIds(x);
}
}
}
}
/ * BaseRepository.java * /
@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
@Override
@Async("executor")
List<T> findByIds(ID... ids);
}
/ * ExtendedRepositoryImpl.java * /
public class ExtendedRepositoryImpl<T, ID extends Serializable>
extends SimpleJpaRepository<T, ID> implements BaseRepository<T, ID> {
private JpaEntityInformation<T, ?> entityInformation;
private final EntityManager entityManager;
public ExtendedRepositoryImpl(
JpaEntityInformation<T, ?> entityInformation,
EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityInformation = entityInformation;
this.entityManager = entityManager;
}
@Override
public List<T> findByIds(ID... ids) {
Query query = this.entityManager.createQuery("select e from " + this.entityInformation.getEntityName()
+ " e where e." + this.entityInformation.getIdAttribute().getName() + " in :ids");
query.setParameter("ids", Arrays.asList(ids));
long wait = new Random().nextInt(10000-1) +1;
System.out.println(wait);
try {
Thread.sleep(wait);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Executing query for ID: " + Arrays.toString(ids));
return (List<T>) query.getResultList();
}
}
/ * DataConfiguration.java(又名AppConfig.java)* /
@EnableJpaRepositories(
basePackages = {"com.infiniteskills.springdata.async"},
repositoryBaseClass = com.infiniteskills.springdata.async.data.repository.ExtendedRepositoryImpl.class,
repositoryImplementationPostfix = "CustomImpl")
@EnableJpaAuditing(auditorAwareRef = "customAuditorAware")
@EnableAsync
@EnableTransactionManagement
@ComponentScan("com.infiniteskills.springdata.async")
@Configuration
public class DataConfiguration implements AsyncConfigurer {
@Bean
public CustomAuditorAware customAuditorAware() {
return new CustomAuditorAware();
}
@Bean
public DataSource dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
return builder.setType(EmbeddedDatabaseType.H2).build();
}
@Bean
public EntityManagerFactory entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
// Generate tables in database
vendorAdapter.setGenerateDdl(true);
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.hbm2ddl.auto", "create-drop");
//jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
//jpaProperties.put("hibernate.connection.driver_class", "org.h2.Driver");
// After DDL has been run, run init script to populate table with data.
jpaProperties.put("hibernate.hbm2ddl.import_files", "init.sql");
// Entity Manager Factory Bean
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPackagesToScan("com.infiniteskills.springdata.async");
entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
entityManagerFactoryBean.setJpaProperties(jpaProperties);
entityManagerFactoryBean.afterPropertiesSet();
return entityManagerFactoryBean.getObject();
}
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory());
return transactionManager;
}
@Override
@Bean(name = "executor")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("executor-");
executor.initialize();
return executor;
}
@Override
@Bean
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
}
答案 0 :(得分:1)
该方法必须具有返回类型void
或Future
才能被称为异步。
答案 1 :(得分:1)
@EnableAsync
用于任何@Configuration
类。
来自docs
要与@Configuration类一起使用,如下所示,为整个Spring应用程序上下文启用注释驱动的异步处理:
使用Application
注释您的@Configuration
课程。
希望这有帮助。
答案 2 :(得分:0)
由于我在练习中一直使用Java配置,因此我最初不确定是否使用了与演示的xml配置等效的所有正确注释。 IntelliJ IDEA可以提供与STS不同的代码建议......
无论如何,课程的Spring Data Async Queries部分(https://www.safaribooksonline.com/library/view/spring-data-for/9781771375924/video241705.html)让我质疑我的理智。
基本上,结果是我的Application.java
类:
public class Application {
public static void main(String[] args) throws ParseException {
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
DataConfiguration.class)) {
BookRepository repository = context.getBean(BookRepository.class);
// TODO: Make method Async
for (long x = 0; x < 4; x++) {
repository.findByIds(x);
}
}
}
}
应该没有try-with-resources
语法,而是看起来像这样:
public class Application {
public static void main(String[] args) throws ParseException {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
DataConfiguration.class)
BookRepository repository = context.getBean(BookRepository.class;
for (long x = 0; x < 4; x++) {
repository.findByIds(x);
}
}
}