如何通过ApplicationScope的springboot JPA获取数据



我需要在应用程序启动时获取数据,并且数据在整个应用程序范围内保持不变,因为这是将进一步使用的参考数据

这是我的bean,它在应用程序范围内存储数据
ApplicationBean.java

@Component
@Slf4j
public class ApplicationBean {
@Getter
private List<Discounts> discountList = new ArrayList<>();
@Autowired
private DiscountService discountService;
@Bean
@ApplicationScope
@EventListener(ApplicationReadyEvent.class)
public  void getDiscounts(){
log.info("Inside Application Scope...");
discountList=discountService.getAllDiscounts();
}
}

折扣服务.java

@Service
public class DiscountService {
@Autowired
private DiscountRepository discountRepository;
public List<Discounts> getAllDiscounts(){
return discountRepository.findAll();
}

}

这是存储库DiscountRepository.java

@Repository
public interface DiscountRepository extends JpaRepository<Discounts,Long> {
@Override
List<Discounts> findAll();
@Override
List<Discounts> findAllById(Iterable<Long> longs);
}

错误

19:52:27.154 [main] INFO  o.a.catalina.core.StandardService - Starting service [Tomcat]
19:52:27.169 [main] INFO  o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.54]
19:52:27.295 [main] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
19:52:27.342 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
19:52:27.717 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
19:52:28.038 [main] INFO  o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
19:52:28.124 [main] INFO  org.hibernate.Version - HHH000412: Hibernate ORM core version 5.4.32.Final
19:52:28.290 [main] INFO  o.h.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
19:52:28.463 [main] INFO  org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
19:52:29.170 [main] INFO  o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
19:52:29.641 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
19:52:29.657 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
19:52:29.657 [main] INFO  o.a.catalina.core.StandardService - Stopping service [Tomcat]
**19:52:29.688 [main] ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getDiscounts' defined in BeanDefinition defined in class path resource [com/xyz/bookingservice/config/ApplicationBean.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of void: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class void**
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:628)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:925)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:338)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332)
at com.xyz.bookingservice.BookingserviceApplication.main(BookingserviceApplication.java:10)
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of void: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class void
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:209)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110)
at org.springframework.aop.scope.ScopedProxyFactoryBean.setBeanFactory(ScopedProxyFactoryBean.java:117)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1826)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1791)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
... 15 common frames omitted
Caused by: java.lang.IllegalArgumentException: Cannot subclass final class void
at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:660)
at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.springframework.cglib.core.ClassLoaderAwareGeneratorStrategy.generate(ClassLoaderAwareGeneratorStrategy.java:57)
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:358)
at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:585)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:110)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:108)
at org.springframework.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:134)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:319)
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:572)
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:419)
at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:57)
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:206)
... 20 common frames omitted
Process finished with exit code 1


我不知道如何做到这一点?我必须将DiscountService和DiscountRepository的范围更改为ApplicationScope吗

只需执行以下操作:

@Component
@Slf4j
public class ApplicationBean implements ApplicationRunner {
private List<Discounts> discountList = new ArrayList<>();
private final DiscountService discountService;

public ApplicationBean(DiscountService discountService) {
this.discountService=discountService;
}
public void run(ApplicationArguments args) {
this.init();
}
private void init(){
log.info("Inside Application Scope...");
discountList=discountService.getAllDiscounts();
}
public List<Discounts> getDiscountList() {
return Collections.unmodifableList(this.discountList);
}
}

或者只使用@PostContruct

@Component
@Slf4j
public class ApplicationBean {
private List<Discounts> discountList = new ArrayList<>();
private final DiscountService discountService;

public ApplicationBean(DiscountService discountService) {
this.discountService=discountService;
}
@PostConstruct
public void init(){
log.info("Inside Application Scope...");
discountList=discountService.getAllDiscounts();
}
public List<Discounts> getDiscountList() {
return Collections.unmodifableList(this.discountList);
}
}

我改为构造函数注入,因为这应该是首选方式,您还希望防止getter返回实际的列表,而是列表的副本。

最后,您甚至可能需要重新考虑这一点,并使用JPA提供者的二级缓存来缓存查询结果。我非常怀疑你永远不会添加折扣,现在你需要重新启动整个应用程序来刷新数据。

最新更新