Bean创建的生命周期

RepublicLine / 2024-03-04 / 原文

Bean创建的生命周期

((20231222181259-yw9e73s 'Spring的三级缓存机制:'))

User.class -> 无参构造器 -> user对象(属性无赋值) -> DI(依赖注入),这里通常使用@Autowired为属性赋值 -> 初始化前(PostConstruct) -> 初始化(InitializingBean) -> 初始化后(AOP) ->代理对象-> userBean对象(属性赋值)

这里如果使用AOP了之后会生成代理对象,代理对象会作为bean对象被spring容器管理.

((20231220161222-4xkz1rt 'Bean对象的生命周期:'))

需求: 获取一个bean对象的时候,希望这个bean对象的属性已经赋值完毕,并且这些属性是通过查询数据库中的数据完成赋值的?

这里就需要用到bean的生命周期,在一个对象未成为bean的时候,为其赋完所有需要的值.

//伪代码  方式1. 方法上标注@PostConstruct注解,初始化前生效
@Compoment
public class User{
  @Autowired
  private Clazz clazz; //这里的班级信息,希望的情况是获取到用户对象的时候,已经从数据库中查到了班级信息,并为该用户赋值班级属性的相关值.
  @PostConstruct  // 初始化前
  public void init(){
    //逻辑步骤   mysql查询 -> 赋值..
  }
}

//方式2. 实现InitializingBean接口,实现接口中的方法
@Compoment
public class User implements InitializingBean{
  @Autowired
  private Clazz clazz;

  @Override //方式2.
  public void afterPropertiesSet() throws Exception {
    //逻辑步骤   mysql查询 -> 赋值..
  }
}


@Compoment
public class Clazz{
  private Integer cno;
  private String cname;
}

总结Bean生命周期:

  1. 初始化前需要的准备工作, 在方法上标明@PostConstruct注解,spring会在bean初始化前执行这个方法.

    伪代码:

    Class<? extends Class> userClass = UserService.class.getClass();
    for (Method method : userClass.getMethods()) {
        if (method.isAnnotationPresent(PostConstruct.class)){
            method.invoke(userClass.newInstance(),null);
        }
    }
    
  2. 类实现InitializingBean接口,并在方法中写业务代码.

    伪代码:

    Class<? extends Class> userClass = UserService.class.getClass();
    if (userClass.isInstance(InitializingBean.class)){
        Method afterPropertiesSet = userClass.getMethod("afterPropertiesSet");
        afterPropertiesSet.invoke(userClass.newInstance(),null);
    }
    
  3. bean创建时候默认调用无参构造器创建对象,如果含有有参构造(1个的情况下),没有无参构造器,spring也会调用这个有参构造器. 如果含有多个有参构造器,spring默认会调用无参构造器.