spring中bean的具体创建过程BeanNameAware/BeanFactoryAware/InitializingBean/BeanFactoryPostProcessor

34 篇文章 0 订阅

在spring创建bean之后通过回调方法获取beanName

package com.fchan.layui.springLife;

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;

@Component
public class GetSpringCreateBeanName implements BeanNameAware {
    
    private String beanName;
    
    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }
}

获取创建当前bean的BeanFactory,可以利用这个beanFactory去获取到其他的bean

package com.fchan.layui.springLife;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.stereotype.Component;

@Component
public class GetSpringBeanFactory implements BeanFactoryAware {

    private BeanFactory beanFactory;


    public void test(){
    //获取其他bean,如果其他bean是单例的,这个时候获取到的bean就是spring在@Autowired时自动注入的那个bean.其实就是从容器中拿出来而已
        GetSpringCreateBeanName test = (GetSpringCreateBeanName) beanFactory.getBean("getSpringCreateBeanName");
        test.toString();
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
}

实现InitializingBean接口对bean的初始化属性手动赋值

package com.fchan.layui.springLife;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Component
public class SpringInitializingBean implements InitializingBean {

    private String userName;

    /**
     * bean的初始化
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        this.userName = "XXXXX";
    }
}

BeanDefinition:
1-scope原型还是单例
2-initMethod
3-byName byType
4-dependsOn
5-beanClass(来自最开始的这个类的class,不过是可以修改的)

上面步骤串起来:
class反射----->BeanDefinition--->BeanFactory建造完成(只有beanFactory被建造完成之后才可以生产对象)----->BeanFactoryPostProcessor(bean工厂的后置处理器,可以强行修改当前实现了bean工厂后置处理器的类要注入的Bean的类型,不改变beanName)------>bean对象---->对象属性依赖注入----->BeanNameAware(看是否实现了这个接口,回调设置Beanname)---->初始化(InitializingBean看是否实现了这个接口,对bean的属性进行自定义操作)------->aop(看是否有切面,决定生成代理对象)----->最后得到的bean对象(有aop的话这里这个bean是代理对象不是原本的bean)------->单例池

BeanFactoryPostProcessor后置处理器修改beanDefinition和手动注册一个bean给spring的单例池

bean后置处理器接口BeanFactoryPostProcessor就是在所有的bean被BeanDefinition定义完成后,BeanFactory建造完成之后调用.

正常来说肯定是先有beanFactory然后再有bean,在实现BeanFactoryPostProcessor接口的postProcessBeanFactory方法中,可以观察到,在获得的beanDefinition中只有当前实现BeanFactoryPostProcessor接口的class的beanDefinition,在单例池(singleObjects)中还没有去生成当前class对应的bean.只有走完了这个方法才会去生成当前class对应的对象,然后再依赖注入等后续流程

在重写的postProcessBeanFactory中可以获取某一个bean的BeanDefinition,这个时候可以强制修改这个bean的实现类型.这里强制修改BeanType之后后面Autowired自动注入这个bean就会报错了,因为BeanType被改了,变成了另一个类型

package com.fchan.layui.springLife;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;


@Component
public class SpringBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        GenericBeanDefinition springFactoryDemo = (GenericBeanDefinition) beanFactory.getBeanDefinition("springFactoryDemo");
        System.out.println(springFactoryDemo.getBeanClassName());

		//强制修改当前 SpringBeanFactoryPostProcessor bean注入进spring的类型
        //springFactoryDemo.setBeanClassName(SpringInitializingBean.class.getName());

		//手动注册一个bean到bean工厂中
		//beanFactory.registerSingleton("xxx",new GetSpringBeanFactory());
		
		//通过手动设置by type注入属性的方式,意味着这个bean中的属性可以不用@Autowired注解也可以by type自动注入
        //不过要让这种模式生效,要让 testDesi 和 testDesi中的属性类都要被spring扫描到才行,并且要提供一下testDesi中的属性类的set方法
        /**GenericBeanDefinition testDesi = (GenericBeanDefinition) beanFactory.getBeanDefinition("testDesi");
        testDesi.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);
        TestDesi testDesi1 = (TestDesi) beanFactory.getBean("testDesi");
        testDesi1.test();*/
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值