spring生命周期步骤简要说明

  1. 实例化前
    为啥需要实例化前这个动作呢?在Spring中,实例化对象之前,Spring提供了一个扩展点,允许用户来控制是否在某个或某些Bean实例化之前做一些启动动作。怎么理解实例化前?实例化,也就是new一个对象,实例化前,也就是在new对象之前执行。

    @Component
    public class MyPostProcess implements InstantiationAwareBeanPostProcessor {
    
        @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if ("other1Entity".equals(beanName)){
            System.out.println("实例化前可以做一些操作,比如往redis设值,等等");
        }
        return null;
    }
    

    如上代码会导致,在other1Entity这个Bean实例化前,会进行打印。

    值得注意的是,postProcessBeforeInstantiation()是有返回值的,如果这么实现:

    @Component
    public class MyPostProcess implements InstantiationAwareBeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            if ("other1Entity".equals(beanName)){
                System.out.println("实例化前可以做一些操作,比如往redis设值,等等");
                return new Other1Entity();
            }
            return null;
        }
    }
    

    other1Entity这个Bean,在实例化前会直接返回一个由我们所定义的Other1Entity对象。如果是这样,表示不需要Spring来实例化了,并且后续的Spring依赖注入也不会进行了,会跳过一些步骤,直接执行初始化后这一步。怎么验证这句话的真实性呢?请看以下代码:

    @Component
    public class MyPostProcess implements InstantiationAwareBeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            if ("other1Entity".equals(beanName)){
                System.out.println("实例化前可以做一些操作,比如往redis设值,等等");
                return new Other1Entity();
            }
            return null;
        }
    
        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            System.out.println("这是实例化后的操作,在这里面,对other1Entity的Name属性进行了赋值,但是并没有成功设置值");
            if ("other1Entity".equals(beanName)){
                Other1Entity o = (Other1Entity)bean;
                o.setName("yzyyzyzyzyzy");
                System.out.println("postProcessAfterInstantiation:" + beanName);
            }
            return false;
        }
    }
    

    在这里插入图片描述
    可以看到,在实例化后的操作里面,对other1Entity的Name属性进行了赋值,但是并没有成功设置值。也就验证了那句话。

  2. 实例化
    在这个步骤中就会根据BeanDefinition去创建一个对象了。
    2.1. 通过Supplier创建对象。请看代码:

    @Component
    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition)beanFactory.getBeanDefinition("other2Entity");
            beanDefinition.setInstanceSupplier(() -> {
                System.out.println("通过supplier构建other2Entity");
                return new Other2Entity();
            });
        }
    }
    
    @Data
    @Component
    public class Other2Entity {
        private String name;
    }
    

    在这里插入图片描述
    可以看出来:other2Entity是通过Supplier创建出来的,如果把MyBeanFactoryPostProcessor 的@Component注释掉,会发生什么呢?咱们试试
    在这里插入图片描述
    从结果得知,这就不是通过Supplier创建的other2Entity,那是怎么创建出来的呢?
    当然,这涉及到推断构造方法,spring默认使用无参的构造方法进行实例化。

    @Component
    public class Other2Entity {
        private String name;
    
        public Other2Entity(){
            System.out.println("通过无参构造方法创建Other2Entity");
        }
    
        public Other2Entity(String name){
            this.name = name;
            System.out.println("通过有参构造方法创建Other2Entity");
        }
    }
    
    public class Test {
        public static void main(String[] args) throws IOException {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringAnnotationTest.class);
            Other2Entity testPrimary = (Other2Entity)context.getBean("other2Entity");
            System.out.println(testPrimary);
        }
    }
    

    在这里插入图片描述
    如果不存在无参的构造方法,但是只有一个有参的构造方法,也不会报错

    @Component
    @Data
    public class Other2Entity {
        private String name;
    
        private Other1Entity other1Entity;
    
    //    public Other2Entity(){
    //        System.out.println("通过无参构造方法创建Other2Entity");
    //    }
    
    //    @Autowired
        public Other2Entity(Other1Entity other1Entity){
            this.other1Entity = other1Entity;
            System.out.println("通过有参构造方法创建Other2Entity");
        }
    
    //    public Other2Entity(Other1Entity other1Entity, TestPrimary testPrimary){
    //        this.other1Entity = other1Entity;
    //        System.out.println("通过有参构造方法创建Other2Entity");
    //    }
    }
    

    在这里插入图片描述

    如果有多个有参构造方法,但是没有无参构造方法,会报错。

    @Component
    @Data
    public class Other2Entity {
        private String name;
    
        private Other1Entity other1Entity;
    
    //    public Other2Entity(){
    //        System.out.println("通过无参构造方法创建Other2Entity");
    //    }
    
    //    @Autowired
        public Other2Entity(Other1Entity other1Entity){
            this.other1Entity = other1Entity;
            System.out.println("通过有参构造方法创建Other2Entity");
        }
    
        public Other2Entity(Other1Entity other1Entity, TestPrimary testPrimary){
            this.other1Entity = other1Entity;
            System.out.println("通过有参构造方法创建Other2Entity");
        }
    }
    

    在这里插入图片描述
    如果有多个有参构造方法,但是没有无参构造方法,但是在某个有参构造方法上加上@Autowired,则默认使用加了@Autowired进行实例化,不会报错。

    @Component
    @Data
    public class Other2Entity {
        private String name;
    
        private Other1Entity other1Entity;
    
    //    public Other2Entity(){
    //        System.out.println("通过无参构造方法创建Other2Entity");
    //    }
    
        @Autowired
        public Other2Entity(Other1Entity other1Entity){
            this.other1Entity = other1Entity;
            System.out.println("通过有参构造方法创建Other2Entity");
        }
    
        public Other2Entity(Other1Entity other1Entity, TestPrimary testPrimary){
            this.other1Entity = other1Entity;
            System.out.println("通过有参构造方法创建Other2Entity");
        }
    }
    

    在这里插入图片描述

  3. BeanDefinition的后置处理
    Bean对象实例化出来之后,接下来就应该给对象的属性赋值了。在真正给属性赋值之前,Spring又提供了一个扩展点MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以对此时的BeanDefinition进行加工,比如:

    @Component
    public class MyMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {
        @Override
        public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
            if ("other2Entity".equals(beanName)){
                beanDefinition.setScope("prototype");
            }
        }
    }
    

    以上代码就是把other2Entity的beanDefinition的作用范围改为原型的

    public class Test {
        public static void main(String[] args) throws IOException {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringAnnotationTest.class);
            Other2Entity other2Entity = (Other2Entity)context.getBean("other2Entity", new Other1Entity());
            System.out.println(other2Entity);
    
            Other2Entity other2Entity1 = (Other2Entity)context.getBean("other2Entity", new Other1Entity());
            System.out.println(other2Entity1);
        }
    }
    

    在这里插入图片描述
    虽然Other2Entity在BeanDefinition的后置处理中改为了原型的,但是在实例化的时候,其还是原型的,也就是说在单例池中,也还是会有Other2Entity这个Bean的,证明:
    在这里插入图片描述

  4. 实例化后
    在处理完BeanDefinition后,Spring又设计了一个扩展点:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(),比如:

    @Component
    public class MyPostProcess implements InstantiationAwareBeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            if ("other2Entity".equals(beanName)){
                System.out.println("实例化前可以做一些操作,比如往redis设值,等等");
            }
            return null;
        }
    
        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            // 实例化后的操作
            if ("other2Entity".equals(beanName)){
                Other2Entity o = (Other2Entity)bean;
                o.setName("yzyyzyzyzyzy");
            }
            return false;
        }
    }
    

    在实例化后步骤中,我们把Other2Entity 的name属性设置为yzyyzyzyzyzy。测试:

    public class Test {
        public static void main(String[] args) throws IOException {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringAnnotationTest.class);
    
            Other2Entity other2Entity = (Other2Entity)context.getBean("other2Entity", new Other1Entity());
            System.out.println(other2Entity.getName());
    
            Other2Entity other2Entity1 = (Other2Entity)context.getBean("other2Entity", new Other1Entity());
            System.out.println(other2Entity1.getName());
        }
    }
    

    在这里插入图片描述
    到这里,实例化后操作完成。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值