天天看點

Spring Bean建立及生命周期注冊Spring Bean執行個體化BeanBean初始化Bean銷毀

注冊Spring Bean

XML配置元資訊

Java注解元資訊

  1. @Bean
  2. @Component及其派生注解
  3. @Import

Java接口繼承

ImportSelector

ImportBeanDefinitionRegistrar

Java API

注冊普通Bean

命名方式:

BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)

非命名方式:

BeanDefinitionReaderUtils#registerWithGeneratedName(AbstractBeanDefinition,Be anDefinitionRegistry)

void registerBeanDefinition(BeanDefinitionRegistry registry, AbstractBeanDefinition beanDefinition, String beanName) {
  if (StringUtils.hasText(beanName)) {
    // 注冊BeanDefinition
    registry.registerBeanDefinition(beanName, beanDefinition);
  } else {
    // 注冊 非命名Bean
    BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry);
    // 按照 definitionHolder 注冊
    // BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
  }
}
           
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.refresh();

//  通過 AbstractBeanDefinition 以及派生類
AbstractBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(User.class);

MutablePropertyValues propertyValues = new MutablePropertyValues()
  .add("id", 1)
  .add("name", "wangrui");
// propertyValues.addPropertyValue("id", 1);
beanDefinition.setPropertyValues(propertyValues);

registerBeanDefinition(applicationContext, beanDefinition, "user");
registerBeanDefinition(applicationContext, beanDefinition, null);

Map<String, User> userMap = applicationContext.getBeansOfType(User.class);
// {user=User(id=1, name=wangrui), com.example.boot244.domain.model.User#0=User(id=1, name=wangrui)}
System.out.println(userMap);
           

注冊配置Bean

AnnotatedBeanDefinitionReader#register(Class...)

與AnnotatedBeanDefinitionReader一次隻注冊單個Bean相比,還有一個掃描器ClassPathBeanDefinitionScanner。但兩者差別在于:

AnnotatedBeanDefinitionReader:可以注冊任意類

ClassPathBeanDefinitionScanner:隻能掃描特定類

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.refresh();

AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(applicationContext);
reader.register(User.class);

User bean = applicationContext.getBean(User.class);
System.out.println(bean);
           

注冊單例Bean

SingletonBeanRegistry#registerSingleton

void test() throws Exception {
  AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
  applicationContext.refresh();

  User user = new User().setId(1).setName("wangrui");
  registerSingleton(applicationContext.getBeanFactory(), "user", user);

  user = applicationContext.getBean(User.class);
  System.out.println(user);
}

public void registerSingleton(SingletonBeanRegistry beanRegistry, String beanname, Object obj) {
  beanRegistry.registerSingleton(beanname, obj);
}
           

執行個體化Bean

Bean正常方式

通過構造器(配置元資訊:XML、Java注解和Java API)

通過靜态方法(配置元資訊:XML和Java API)

通過執行個體方法(配置元資訊:XML和Java API)

通過FactoryBean(配置元資訊:XML、Java注解和Java API)

public class User {
  private Integer id;
  private String name;
	// 靜态方法
  public static User createUser() {
    return new User().setId(1).setName("createUser");
  }
}
           
public class UserFactory {
  // 執行個體方法
  public User createUser() {
    return new User().setId(1).setName("factory工廠");
  }
}
           
// 通過FactoryBean
public class UserFactoryBean implements FactoryBean<User> {
  @Override
  public User getObject() throws Exception {
    return new User().setId(1).setName("userFactoryBean");
  }

  @Override
  public Class<?> getObjectType() {
    return User.class;
  }
}
           
// 注冊工具
void registerBeanDefinition(BeanDefinitionRegistry registry, AbstractBeanDefinition beanDefinition, String beanName) {
  if (StringUtils.hasText(beanName)) {
    // 注冊BeanDefinition
    registry.registerBeanDefinition(beanName, beanDefinition);
  } else {
    // 注冊 非命名Bean
    BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry);
    // 按照 definitionHolder 注冊
    // BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
  }
}
           
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// UserFactoryBean屬于FactoryBean方式
applicationContext.register(UserFactory.class, UserFactoryBean.class);
applicationContext.refresh();

// 通過靜态工廠方法
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(User.class)
  .setFactoryMethod("createUser")
  .getBeanDefinition();
registerBeanDefinition(applicationContext, beanDefinition, null);

// 通過執行個體工廠方法
AbstractBeanDefinition beanDefinition1 = BeanDefinitionBuilder.genericBeanDefinition(User.class)
  .setFactoryMethodOnBean("createUser", "userFactory")
  .getBeanDefinition();
registerBeanDefinition(applicationContext, beanDefinition1, null);

Map<String, User> userMap = applicationContext.getBeansOfType(User.class);
System.out.println(userMap);
           

特殊方式

通過ServiceLoaderFactoryBean(配置元資訊:XML、Java注解和Java API)

public interface DemoFactory { }

public class DefaultDemoFactory implements DemoFactory {  }

public class StandDemoFactory implements DemoFactory {  }
           

META-INF/services/com.example.boot.service.DemoFactory

# 這裡用來展示去重
com.example.boot244.service.DefaultDemoFactory
com.example.boot244.service.StandDemoFactory
com.example.boot244.service.StandDemoFactory
           
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.refresh();

AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(ServiceLoaderFactoryBean.class)
  .addPropertyValue("serviceType", DemoFactory.class)
  .getBeanDefinition();
registerBeanDefinition(applicationContext, beanDefinition, null);

ServiceLoader serviceLoader = applicationContext.getBean(ServiceLoader.class);
serviceLoader.forEach(System.out::println);
           

通過AutowireCapableBeanFactory#createBean

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.refresh();

// 此種方式可以觸發 依賴注入,但createBean(Class<T> beanClass)不能觸發依賴查找
User user = applicationContext.getBeanFactory().createBean(User.class);
System.out.println(user);
           

通過BeanDefinitionRegistry#registerBeanDefinition

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.refresh();

AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(User.class)
  .addPropertyValue("id", 1)
  .addPropertyValue("name", "wangrui")
  .getBeanDefinition();
applicationContext.registerBeanDefinition("user", beanDefinition);

User user = applicationContext.getBean(User.class);
System.out.println(user);
           

Bean初始化

@PostConstruct

實作InitializingBean接口

自定義初始化方法

XML配置:

Java注解:@Bean(initMethod="")

Java API:AbstractBeanDefinition#setInitMethodName

那以上三種方式均在同一Bean中定義,那麼這些方法的執行順序是怎樣的呢?

  1. @PostConstruct
  2. 實作InitializingBean接口
  3. 自定義初始化方法
public class Person implements InitializingBean {
  @Override
  public void afterPropertiesSet() throws Exception {
    System.out.println("InitializingBean#afterPropertiesSet() : 初始化中...");
  }

  @PostConstruct
  public void init() {
    System.out.println("@PostConstruct : 初始化中...");
  }

  public void initFactory() {
    System.out.println("自定義初始化方法 initUserFactory() : 初始化中...");
  }
}
           
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.refresh();

AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Person.class)
  .setInitMethodName("initFactory")
  .getBeanDefinition();
BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, applicationContext);

Person person = applicationContext.getBean(Person.class);
           

Bean銷毀

@PreDestory

實作DisposableBean接口

自定義銷毀方法

XML配置:

Java注解:@Bean(destory="")

Java API:AbstractBeanDefinition#setDestroyMethodName

那以上三種方式均在同一Bean中定義,那麼這些方法的執行順序是怎樣的呢?

  1. @PreDestory
  2. 實作DisposableBean接口
  3. 自定義銷毀方法
public class Person implements DisposableBean {
  @Override
  public void destroy() throws Exception {
    System.out.println("DisposableBean#destroy() : 銷毀中...");
  }

  @PreDestroy
  public void destory() {
    System.out.println("@PreDestroy : 銷毀中...");
  }

  public void destoryFactory() {
    System.out.println("自定義銷毀方法 doDestroy() : 銷毀中...");
  }
}
           
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.refresh();

AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Person.class)
  .setDestroyMethodName("destoryFactory")
  .getBeanDefinition();
BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, applicationContext);

Person person = applicationContext.getBean(Person.class);
System.out.println(person);

applicationContext.close();
           

繼續閱讀