SpringBoot Runner 与 @PostConstruct 初始化数据

一、Springboot Runner - 在服务启动后进行初始化工作

可以初始化一些数据,比如加载数据库数据到redis

1.实现ApplicationRunner接口

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

/**
 * ApplicationRunner
 * 该接口的方法会在服务启动之后被立即执行
 * 主要用来做一些初始化的工作
 * 但是该方法的运行是在SpringApplication.run(…​) 执行完毕之前执行
 */

@Component
@Slf4j
public class ApplicationRunnerImpl implements ApplicationRunner {

    /**
     * 会在服务启动完成后立即执行
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {

        log.info("Successful service startup!");
    }
}
2.实现CommandLineRunner

import com.simply.zuozuo.util.JedisSingleton;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

/**
 *
 * CommandLineRunner跟ApplicationRunner一样的功能
 */
@Component
public class CommandLineRunnerImpl implements CommandLineRunner{

    /**
     * 会在服务启动完成后立即执行
     */
    @Override
    public void run(String... args) throws Exception {

        JedisSingleton.getInstance().set("Service startup time", String.valueOf(System.nanoTime()));
    }
}


二、@PostConstruct 进行初始化工作

Java EE5 引入了@PostConstruct和@PreDestroy这两个作用于Servlet生命周期的注解,实现Bean初始化之前和销毁之前的自定义操作。这里主要说明@PostConstruct。

以下为@PostConstruct的API使用说明:

PostConstruct 注释用于在依赖关系注入完成之后需要执行的方法上,以执行任何初始化。此方法必须在将类放入服务之前调用。支持依赖关系注入的所有类都必须支持此注释。即使类没有请求注入任何资源,用 PostConstruct 注释的方法也必须被调用。只有一个方法可以用此注释进行注释。应用 PostConstruct 注释的方法必须遵守以下所有标准:该方法不得有任何参数,除非是在 EJB 拦截器 (interceptor) 的情况下,根据 EJB 规范的定义,在这种情况下它将带有一个 InvocationContext 对象 ;该方法的返回类型必须为 void;该方法不得抛出已检查异常;应用 PostConstruct 的方法可以是 public、protected、package private 或 private;除了应用程序客户端之外,该方法不能是 static;该方法可以是 final;如果该方法抛出未检查异常,那么不得将类放入服务中,除非是能够处理异常并可从中恢复的 EJB。

总结为一下几点:

  1. 只有一个方法可以使用此注释进行注解;
  2. 被注解方法不得有任何参数;
  3. 被注解方法返回值为void;
  4. 被注解方法不得抛出已检查异常;
  5. 被注解方法需是非静态方法;
  6. 此方法只会被执行一次;
  7. Servlet执行流程图


两个注解在Servlet执行流程中的过程 如图: 


在具体Bean的实例化过程中,@PostConstruct注释的方法,会在构造方法之后,init方法之前进行调用。
 

实例

UserService方法(提供缓存数据):

package com.secbro.service;

import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 二师兄
 * @date 2016/8/10
 */
@Service
public class UserService {

    public List<String> getUser(){

        List<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        return list;
    }
}

BusinessService方法,通过@PostConstruct调用UserService:

package com.secbro.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * @author 二师兄
 * @date 2016/8/10
 */
@Service
public class BusinessService {

    @Autowired
    private UserService userService;

    private List<String> list = null;

    /**
     * 构造方法执行之后,调用此方法
     */
    @PostConstruct
    public void init(){
        System.out.println("@PostConstruct方法被调用");
        // 实例化类之前缓存获得用户信息
        List<String> list = userService.getUser();
        this.list = list;
        if(list != null && !list.isEmpty()){
            for(String user : list){
                System.out.println("用户:" + user);
            }
        }
    }

    public BusinessService(){
        System.out.println("构造方法被调用");
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }
}
1

执行结果:

构造方法被调用
@PostConstruct方法被调用
用户:张三
用户:李四


项目应用
在项目中@PostConstruct主要应用场景是在初始化Servlet时加载一些缓存数据等。

注意事项
使用此注解时会影响到服务的启动时间。服务器在启动时会扫描WEB-INF/classes的所有文件和WEB-INF/lib下的所有jar包。
 

  • 28
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值