miller
发布于

spring 相关笔记

初始化顺序

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean

    1. invokeAwareMethods
      处理BeanNameAware,BeanClassLoaderAware,BeanFactoryAware接口方法
    1. BeanPostProcessor的postProcessBeforeInitialization方法 . PostConstruct 在里面执行
    1. @PostConstruct 在构造方法之后执行
    1. invokeInitMethods(beanName, wrappedBean, mbd)
  • 3.1 在对象的所有属性被初始化后之后才会调用 InitializingBean.afterPropertiesSet
  • 3.2 init-method
    1. applyBeanPostProcessorsAfterInitialization
    1. CommandLineRunner
    1. ApplicationRunner
	public CommonAnnotationBeanPostProcessor() {
		setOrder(Ordered.LOWEST_PRECEDENCE - 3);
		setInitAnnotationType(PostConstruct.class);
		setDestroyAnnotationType(PreDestroy.class);
		ignoreResourceType("javax.xml.ws.WebServiceContext");
	}

https://blog.csdn.net/wangwei19871103/article/details/105149605
https://blog.csdn.net/wangwei19871103/article/details/105150359

BeanDefinition

BeanDefinition表示Bean定义,BeanDefinition中存在很多属性用来描述一个Bean的特点。比如:

  • class,表示Bean类型
  • scope,表示Bean作用域,单例或原型等
  • lazyInit:表示Bean是否是懒加载
  • initMethodName:表示Bean初始化时要执行的方法
  • destroyMethodName:表示Bean销毁时要执行的方法还有很多...

在Spring中,我们经常会通过以下几种方式来定义Bean: @Bean @Component(@Service,@Controller)这些,我们可以称之申明式定义Bean。
我们还可以编程式定义Bean,那就是直接通过BeanDefinition,比如:AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

// 生成一个BeanDefinition对象,并设置beanClass为User.class,并注册到ApplicationContext中
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(User.class);
context.registerBeanDefinition("user", beanDefinition);

System.out.println(context.getBean("user"));
我们还可以通过BeanDefinition设置一个Bean的其他属性beanDefinition.setScope("prototype"); // 设置作用域
beanDefinition.setInitMethodName("init"); // 设置初始化方法
beanDefinition.setLazyInit(true); // 设置懒加载
最终都会被Spring解析为对应的BeanDefinition对象,并放入Spring容器中。

原文

public class BeanDefinitionDemo {
    public static void main(String[] args) {
        //BeanDefinitionBuilder
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class) ;
        beanDefinitionBuilder
                .addPropertyValue("id",1)
                .addPropertyValue("name","Demo01");
        BeanDefinition beanDefinition= beanDefinitionBuilder.getBeanDefinition() ;
 
        //GenericBeanDefinition
        GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
        genericBeanDefinition.setBeanClass(User.class);
        MutablePropertyValues propertyValues = new MutablePropertyValues();
        propertyValues
                .add("id",2)
                .add("name","Demo02");
        genericBeanDefinition.setPropertyValues(propertyValues);
        System.out.println(genericBeanDefinition.getBeanClassName());
    }
}

BeanPostProcessor

BeanPostProcess表示Bena的后置处理器,我们可以定义一个或多个BeanPostProcessor,比如通过一下代码定义一个BeanPostProcessor:
postProcessBeforeInitialization + postProcessAfterInitialization

一个BeanPostProcessor可以在任意一个Bean的初始化之前以及初始化之后去额外的做一些用户自定义的逻辑,当然,我们可以通过判断beanName来进行针对性处理(针对某个Bean,或某部分Bean)。

BeanFactoryPostProcessor

BeanPostProcessor是干涉Bean的创建过程,BeanFactoryPostProcessor是干涉BeanFactory的创建过程

FactoryBean

我们可以通过BeanPostPorcessor来干涉Spring创建Bean的过程,但是如果我们想一个Bean完完全全由我们来创造,也是可以的. 但是通过这种方式创造出来的UserService的Bean,只会经过初始化后,其他Spring的生命周期步骤是不会经过的,比如依赖注入。

@Bean定义的Bean是会经过完整的Bean生命周期的。

bean 生命周期

BeanFactory和ApplicationContext有什么区别?

BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。

两者区别如下:
1、功能上的区别。
BeanFactory是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能,如继承MessageSource、支持国际化、统一的资源文件访问方式、同时加载多个配置文件等功能。
2、加载方式的区别。
BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。而ApplicationContext是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。 ApplicationContext启动后预载入所有的单例Bean,那么在需要的时候,不需要等待创建bean,因为它们已经创建好了。相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。
3、创建方式的区别。
BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader。
4、注册方式的区别。
BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。

如何真正理解Spring的核心思想 ? - 程序员大彬的回答 - 知乎
https://www.zhihu.com/question/438612354/answer/2954395290


@Bean和@Component有什么区别?

都是使用注解定义 Bean。@Bean 是使用 Java 代码装配 Bean,@Component 是自动装配 Bean。
@Component 注解用在类上,表明一个类会作为组件类,并告知Spring要为这个类创建bean,每个类对应一个 Bean。
@Bean 注解用在方法上,表示这个方法会返回一个 Bean。@Bean 需要在配置类中使用,即类上需要加上@Configuration注解。

@Bean 注解更加灵活。当需要将第三方类装配到 Spring 容器中,因为没办法源代码上添加@Component注解,只能使用@Bean 注解的方式,当然也可以使用 xml 的方式。

浏览 (334)
点赞
收藏
评论