Spring学习笔记:Spring Bean的初始化

2021-01-12  本文已影响0人  大力papa

本文仅供学习交流使用,侵权必删。
不作商业用途,转载请注明出处

Spring Bean能通过不同方式进行初始化,下面将展示Spring Bean的各种初始化方式。

通过@PostConstruct

@PostConstruct是java的注解类,如果需要通过这种方式初始化Bean,需要容器具备扫描注解的能力
以下例子通过@PostConstruct的方式展示

public class SubUser {
   private String type;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    /**
     * 通过@PostConstruct设定的初始化方法
     */
    @PostConstruct
    public void initByPostConstruct() {
        System.out.println("init method by  @PostConstruct");
    }
}

public class BeanInitializationDemo {
    public static void main(String[] args) {
     AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext ();
        //注册注解标记的组件class
        applicationContext.register (Config.class);
        //启动spring应用上下文
        applicationContext.refresh ();
        SubUser subUser = applicationContext.getBean ("init-by-bean-annotation", SubUser.class);
        System.out.println (subUser);
        applicationContext.close ();
  }


    static class Config {
        @Bean(name = "init-by-bean-annotation")
        public SubUser subUser() {
            return new SubUser ();
        }
    }

}

通过Xml配置init-method方法

Xml方式是比较熟悉的方式,将定义在Bean类中的初始化方法名设定在init-method

public class SubUser {
   private String type;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

   /**
     * Xml配置的初始化方法
     */
    public void init() {
        System.out.println("init by xml method init config");
    }
}
<!-- 自定义初始化方法-->
    <bean id="init-by-init-method" init-method="init" class="com.kgyam.domain.SubUser"></bean>
public class BeanInitializationDemo {
    public static void main(String[] args) {
    /*
        启动读取xml配置的应用上下文
         */
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext ("classpath:META-INF/bean-initialization-context.xml");
        SubUser subUser = applicationContext.getBean ("init-by-init-method", SubUser.class);
        System.out.println (subUser);
  }
}

通过@Bean的init-method方法

这种方式比较方便,直接在@Bean的注解的init-method上设定Bean类中的初始化方法名

     @Bean(name = "init-by-bean-annotation", initMethod = "initByAnnotation")
        public SubUser subUser() {
            return new SubUser ();
        }

实现InitializingBean

这种方式需要Bean类实现InitializingBean接口重写afterPropertiesSet方法。

下面只展示实现了InitializingBean的Bean定义

public class SubUser implements InitializingBean {
    private String type;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

/**
     * 实现InitializingBean接口的初始化方法
     *
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println(" init by InitializingBean#afterPropertiesSet()");
    }
}

BeanDefinitionBuilder的setInitMethodName

这种方式是通过BeanDefinition的方式设定Bean的初始化方法

        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext ();
        //启动应用上下文
        applicationContext.refresh ();
        /*
        构建BeanDefinitionBuilder
         */
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition (SubUser.class);
        /*
        设置初始化方法
         */
        builder.setInitMethodName ("initByBeanDefinition");
        /*
        设置是否延迟加载
         */
        //builder.setLazyInit(true);
        BeanDefinition beanDefinition = builder.getBeanDefinition ();

        /*
        向容器注册BeanDefinition,
         */
        String beanName = "init-by-bean-definition";
        applicationContext.registerBeanDefinition (beanName, beanDefinition);

        SubUser subUser = applicationContext.getBean (beanName, SubUser.class);
        System.out.println (subUser);
        /*
        关闭应用上下文
         */
        applicationContext.close ();

关于初始化方法的执行顺序

@PostConstruct -> InitializingBean#afterPropertiesSet() -> 自定义init-method

延迟初始化

1. 通过@Lazy

2. 通过Xml配置lazy-init="true"

3. 通过BeanDefinitionBuilder的setLazyInit()

4. 在容器级别默认控制所有Bean延迟初始化,通过beans标签的属性default-lazy-init

<beans default-lazy-init="true">
    <!-- no beans will be pre-instantiated... -->
</beans>
上一篇下一篇

猜你喜欢

热点阅读