解读 Spring Bean的生命周期

image

实例化Bean

对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。

对于ApplicationContext容器,当容器启动结束后,通过获取BeanDefinition对象中的信息,实例化所有的bean。(BeanDefinitionSpring 中极其重要的一个概念,它存储了bean对象

的所有特征信息,如是否单例,是否懒加载,factoryBeanName 等。BeanDefinition对象的创建时通过各种bean的配置信息进行构建 )

设置对象属性(依赖注入):

实例化后的对象被封装在BeanWrapper对象中,紧接着Spring根据BeanDefinition中的信息以及通过BeanWrapper提供的设置属性的接口完成依赖注入。

处理Aware接口:

接着,Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给Bean:如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的就是Spring配置文件中Beanid值。 如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,传递的是Spring工厂自身。 如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文。

Bean的后置处理器(BeanPostProcessor)

如果想对Bean进行一些自定义的处理,那么可以让Bean实现了BeanPostProcessor接口,那将会调用postProcessBeforeInitialization方法。由于这个方法是在Bean初始化结束时调用的,所以可以被应用于内存或缓存技术;

InitializingBeaninit-method

如果BeanSpring配置文件中配置了init-method 属性,则会自动调用其配置的初始化方法。

Bean的后置处理器(BeanPostProcessor)

如果这个Bean实现了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法;以上几个步骤完成后,Bean就已经被正确创建了,之后就可以使用这个Bean了。

DisposableBean:

当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法;

destroy-method:

最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

示例代码:

User类:

@Component
@Slf4j
public class User implements BeanNameAware , BeanFactoryAware , ApplicationContextAware {

    public User() {
        System.out.println("a的构造方法执行了.........");
    }

    private String name ;

    @Value("张三")
    public void setName(String name) {
        System.out.println("setName方法执行了.........");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("setBeanName方法执行了.........");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("setBeanFactory方法执行了.........");
    }

    @PostConstruct
    public void init() {
        System.out.println("init方法执行了.................");
    }

    @PreDestroy
    public void destory() {
        System.out.println("destory方法执行了...............");
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("setApplicationContext方法执行了........");
    }

}
Bean的后置处理器(BeanPostProcessor):

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization方法执行了.........");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization方法执行了.........");
        return bean;
    }

}

测试类:

ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = applicationContext.getBean(User.class);
System.out.println(user);
applicationContext.close();

控制台输出结果:

Generic bean: class [com.itheima.user.domain.User]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [E:\idea-edu-workplace\spring\target\classes\com\itheima\user\domain\User.class]
a的构造方法执行了.........
setName方法执行了.........
setBeanName方法执行了.........
setBeanFactory方法执行了.........
setApplicationContext方法执行了........
postProcessBeforeInitialization方法执行了.........
init方法执行了.................
postProcessAfterInitialization方法执行了.........
com.itheima.user.domain.User@4386f16
destory方法执行了...............

InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。

范骏博客
请先登录后发表评论
  • latest comments
  • 总共0条评论