Spring java项目对外提供服务和java进程启动时bean,内部缓存加载的先后关系?

Spring java项目对外提供服务有这么几种,一种是web服务,譬如tomcat,一种是RPC服务,譬如dubbo,thrift。总的来说就是对外开放某个/些端口,接收请求。

Spring工程项目启动时,bean会加载,内部的一些类成员缓存,譬如guava的CacheBuilder.newBuilder().build(){},会初始化。

Spring或者java是如何保证bean加载完,缓存加载完后才对外提供服务的呢?

打个比方,下面是一个@Service注解的类的类成员,初始化时会远程调用来加载缓存,如何保证这个缓存加载完成后,该java进程才对外服务呢?

    private LoadingCache<String, Set<Long>> mycache = CacheBuilder.newBuilder()
                .expireAfterWrite(6, TimeUnit.MINUTES)
                .refreshAfterWrite(5, TimeUnit.MINUTES)
                .build(new CacheLoader<String, Set<Long>>() {
                    @Override
                    public Set<Long> load(String key) throws Exception {
                        Set<Long> resultSet = myFeign.callRemote(param);
                        return resultSet;
                    }

                    @Override
                    public ListenableFuture<Set<Long>> reload(final String key, Set<Long> oldValue) throws Exception {
                        return listeningThreadPool.getListeningExecutor().submit(new Callable<Set<Long>>() {
                            @Override
                            public Set<Long> call() throws Exception {
                                return load(key);
                            }
                        });
                    }
                });
               

~

阅读 3.7k
4 个回答

一般来说,对外服务的控制类Controller也是bean,所以没有这些问题,如果controller依赖到一个bean,那么这个bean肯定会比controller更早实例化。

其次,不了解你的缓存机制,如果你需要创建实例之后调用某个方法加载缓存,可以用BeanFactory创建bean的实例。

看描述应该是想知道访问请求应用时,怎么确保请求资源是可用的?差不多就两种:
1.初始化完成后,再对外提供服务。比如springboot,全部加载完毕后,再启动tomcat服务接受外部请求。
2.懒加载,真正调用的时候再去加载初始化。你请求过来了,我再进行初始化,初始化完成后再给你提供结果

方法很多,比如spirngboot 两个启动监听器,spirng 生命周期监听器,或者你把缓存交给spring管理也行啊,等服务能用了,bean都准备好了,在有一些java自带方法,static块,代码块,构造函数。在有一些spring接口,initializingbean。我真不觉得这是个问题。

就你给这个例子看,楼上几位好像都没理解对你的问题。你的问题是“如何保证这个缓存加载完成后,该java进程才对外服务呢?”,答案是并不会保证,甚至在服务启动后class都可能没有全部加载完,只是对外提供服务后,当接收到一个请求,发现需要加载哪个class,如果没加载就去加载,需要创建哪个实例,如果没有或需要新的就去创建,创建完了再调用这个实例而已,而你例子里的缓存是否在访问时已经加载好,也是不提供保证的,可能在请求来的时候已经加载过了,也可能没加载过,如果没加载过,假如这个缓存除了定时加载以外,还支持被动加载,即请求过来用key去查询发现没有,就实时去加载一次,那么也可以返回缓存值,如果不支持被动加载,那么可能就直接返回空了,即便现在数据源里有数据

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题