Spring 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();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

①笶侕濄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值