Spring-Bean基础


什么是 BeanDefinition

BeanDefinition 是 Spring Framework 中定义 Bean 的配置元信息接口,包含如下信息:在这里插入图片描述

如何获取BeanDefinition

我们直接给出代码示例:

public class BeanDefinitionCreator {
    public static void main(String[] args) {
        /*
         * 方式一:通过BeanDefinitionBuilder构建
         */
        // 获取BeanDefinitionBuilder
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
        // 设置属性
        beanDefinitionBuilder
                .addPropertyValue("id", 1)
                .addPropertyValue("name", "zfDtpTest1");
        // 构建BeanDefinition
        BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();

        /*
         * 方式二:通过AbstractBeanDefinition以及其派生类构建
         */
        GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
        genericBeanDefinition.setBeanClass(User.class);
        MutablePropertyValues propertyValues = new MutablePropertyValues();
        propertyValues
                .add("id", 2)
                .add("name", "zfDtpTest2");
        genericBeanDefinition.setPropertyValues(propertyValues);
    }
}

如何将BeanDefinition注册到容器中

  • XML 配置元信息
    • <bean name=”…” … />
  • Java 注解配置元信息
    • @Bean
    • @Component
    • @Import
// @Import将Config注册到容器中
@Import(AnnotationBeanDefinitionDemo.Config.class)
public class AnnotationBeanDefinitionDemo {

    public static void main(String[] args) {
    	// 定义容器
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
		// 此处其实是用的Java API的方式进行注册的
        annotationConfigApplicationContext.register(Config.class);
        // 刷新容器
        annotationConfigApplicationContext.refresh();
        User user3 = annotationConfigApplicationContext.getBean("user3", User.class);
        User test3 = annotationConfigApplicationContext.getBean("test3", User.class);
        // 关闭容器
        annotationConfigApplicationContext.close();
    }

	// 使用@Component将Config 注册到容器中
    @Component
    public static class Config {
        @Bean(name = {"user3", "test3"})
        public User user() {
            User user = new User();
            user.setId(3);
            user.setName("test3");
            return user;
        }
    }
}
  • Java API 配置元信息
    • 命名方式:BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)
    • 非命名方式:
      BeanDefinitionReaderUtils#registerWithGeneratedName(AbstractBeanDefinition,BeanDe
      finitionRegistry)
    • 配置类方式:AnnotatedBeanDefinitionReader#register(Class…)
public class ApiRegistryBeanDemo {
    public static void main(String[] args) {
        // 定义容器
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();

        // 命名方式
        annotationConfigApplicationContext.registerBeanDefinition("user1", getUserBeanDefinition());

        // 非命名方式
        BeanDefinitionReaderUtils.registerWithGeneratedName(getUserBeanDefinition(), annotationConfigApplicationContext);

        // 刷新容器
        annotationConfigApplicationContext.refresh();

        User user = annotationConfigApplicationContext.getBean("user1", User.class);
        System.out.println(user);

        // 关闭容器
        annotationConfigApplicationContext.close();
    }

    public static AbstractBeanDefinition getUserBeanDefinition(){
        GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
        genericBeanDefinition.setBeanClass(User.class);
        MutablePropertyValues propertyValues = new MutablePropertyValues();
        propertyValues
                .add("id", 2)
                .add("name", "zfDtpTest2");
        genericBeanDefinition.setPropertyValues(propertyValues);
        return genericBeanDefinition;
    }
}

Bean的初始化操作

  • @PostConstruct 标注方法
  • 实现 InitializingBean 接口的 afterPropertiesSet() 方法
  • 自定义初始化方法
    • XML 配置:<bean init-method=”init” … />
    • Java 注解:@Bean(initMethod=”init”)
    • Java API:AbstractBeanDefinition#setInitMethodName(String)
public class BeanInitDemo {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(BeanInitDemo.class);
        applicationContext.refresh();
        applicationContext.close();
    }

    @Bean(initMethod = "customInitMethod")
    public InitDemo initDemo(){
        return new InitDemo();
    }

    public static class InitDemo implements InitializingBean {
        @PostConstruct
        public void postConstruct(){
            System.out.println("InitDemo 的 postConstruct初始化方式被实现");
        }
        public void afterPropertiesSet() {
            System.out.println("InitDemo 的 InitializingBean#afterPropertiesSet初始化方式被实现");
        }
        public void customInitMethod(){
            System.out.println("InitDemo 的 customInitMethod初始化方式被实现");
        }
    }
}

Bean的销毁操作

  • @PreDestroy 标注方法
  • 实现 DisposableBean 接口的 destroy() 方法
  • 自定义销毁方法
    • XML 配置:<bean destroy=”destroy” … />
    • Java 注解:@Bean(destroy=”destroy”)
    • Java API:AbstractBeanDefinition#setDestroyMethodName(String)
public class BeanDestroyDemo {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(BeanDestroyDemo.class);
        applicationContext.refresh();
        applicationContext.close();
    }

    @Bean(destroyMethod = "customDestroyMethod")
    public DestroyDemo destroyDemo(){
        return new DestroyDemo();
    }

    public static class DestroyDemo implements DisposableBean {
        @PreDestroy
        public void preDestroy(){
            System.out.println("DestroyDemo 的 @PreDestroy 销毁方式被实现");
        }
        public void destroy() throws Exception {
            System.out.println("DestroyDemo 的 DisposableBean#destroy 销毁方式被实现");
        }
        public void customDestroyMethod(){
            System.out.println("DestroyDemo 的 @Bean(destroyMethod = "customDestroyMethod") 销毁方式被实现");
        }
    }
}

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>