面试了才知道初始化Bean不仅只有new那么简单

简介: 面试了才知道初始化Bean不仅只有new那么简单

@PostConstruct 标注方法

所有我们来讲解一下如果使用@PostConstruct 标注方法来初始化Bean

一、首先我们先创建一个初始化对象

/**
 * @author Java面试教程
 * @date 2022-11-22 21:37
 */
public interface UserFactory {
}
/**
 * @author Java面试教程
 * @date 2022-11-22 21:37
 */
public class DefaultUserFactory implements UserFactory{
    //基于@PostConstruct注解
    @PostConstruct
    public void init(){
        System.out.println("DefaultUserFactory 初始化中...");
    }
}

二、把UserFactroy注册为bean

@Configuration
public class Demo {
    @Bean
    public UserFactory createUserFactory(){
        return new DefaultUserFactory();
    }
}

这里使用@Configuration是为了初始化的时候使用applicationContext.register(Demo.class),让程序把@Bean扫描到然后把Bean注册进去。

三、初始化Bean

@Configuration
public class Demo {
    public static void main(String[] args)
    {
        //创建BeanFactory容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        //注册当前类,主要目的是获取@Bean
        applicationContext.register(Demo.class);
        //启动应用上下文
        applicationContext.refresh();
        //依赖查找
        UserFactory bean = applicationContext.getBean(UserFactory.class);
        //关闭应用上下文
        applicationContext.close();
    }
    @Bean
    public UserFactory createUserFactory(){
        return new DefaultUserFactory();
    }
}

运行的是@PostConstruct这个方法会被自动回调,打印出我们设置好的内容。

Connected to the target VM, address: '127.0.0.1:52103', transport: 'socket'
DefaultUserFactory 初始化中...
Disconnected from the target VM, address: '127.0.0.1:52103', transport: 'socket'

自定义初始化

为了区分不同的初始化,我们这里定义一个方法来执行

public interface UserFactory {
    void initUserFactory();
}
/**
 * @author Java面试教程
 * @date 2022-11-22 21:37
 */
public class DefaultUserFactory implements UserFactory{
    //基于@PostConstruct注解
    @PostConstruct
    public void init(){
        System.out.println("DefaultUserFactory 初始化中...");
    }
    public void initUserFactory(){
        System.out.println("自定义初始化方法 initUserFactory()...");
    }
}

这里我们自定义一个initUserFactory方法,然后把方法名放到@Bean注解中。

@Configuration
public class Demo {
    public static void main(String[] args)
    {
        //创建BeanFactory容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        //注册当前类,主要目的是获取@Bean
        applicationContext.register(Demo.class);
        //启动应用上下文
        applicationContext.refresh();
        //依赖查找
        UserFactory bean = applicationContext.getBean(UserFactory.class);
        //关闭应用上下文
        applicationContext.close();
    }
    @Bean(initMethod = "initUserFactory")
    public UserFactory createUserFactory(){
        return new DefaultUserFactory();
    }
}

这样就会打印出来两个初始化方法的内容

Connected to the target VM, address: '127.0.0.1:53619', transport: 'socket'
DefaultUserFactory 初始化中...
自定义初始化方法 initUserFactory()...
Disconnected from the target VM, address: '127.0.0.1:53619', transport: 'socket'

实现InitializatingBean接口的afterPropertiesSet()方法

我们要去实现Spring它自己的一个接口,通过覆盖InitializatingBean接口的afterPropertiesSet方法。

public class DefaultUserFactory implements UserFactory, InitializingBean {
    //基于@PostConstruct注解
    @PostConstruct
    public void init(){
        System.out.println("DefaultUserFactory 初始化中...");
    }
    public void initUserFactory(){
        System.out.println("自定义初始化方法 initUserFactory()...");
    }
    @Override
    public void afterPropertiesSet() throws Exception
    {
        System.out.println("InitializingBean的afterPropertiesSety()...");
    }
}

运行后发现,三种方式共存且存在一定顺序

Connected to the target VM, address: '127.0.0.1:54298', transport: 'socket'
DefaultUserFactory 初始化中...
InitializingBean的afterPropertiesSety()...
自定义初始化方法 initUserFactory()...
Disconnected from the target VM, address: '127.0.0.1:54298', transport: 'socket'

它们的优先级:@PostConstruct注解 > 实现InitializatingBean接口的afterPropertiesSet()方法 > 自定义方法初始化

它们的顺序在任何spring版本都不会变化的。

结束语

关于Bean的实例化和初始化,现在业务开发中或许已经用不到了,但是如果你的目标是深耕于Java领域的话,那么以后难免涉及框架的二次开发,那么Bean的实例化和初始化就有必要提前的好好了解一下。

相关文章
|
6天前
|
XML Java 数据格式
【springboot原理篇】Bean的加载方式,面试必看
【springboot原理篇】Bean的加载方式,面试必看
|
8月前
|
Java 程序员 Spring
Spring中bean类的生命周期|面试必问如何回答
Spring中bean类的生命周期|面试必问如何回答
|
8月前
|
前端开发
前端经典面试题 | New操作符的原理
前端经典面试题 | New操作符的原理
|
9月前
|
Java
第一季:3类和实例初始化【Java面试题】
第一季:3类和实例初始化【Java面试题】
42 0
|
9月前
|
XML 存储 Java
以后面试别再说你只会用@Autowired实例化Bean了
以后面试别再说你只会用@Autowired实例化Bean了
38 0
|
10月前
|
Java 编译器
04-面试:类的初始化做了什么?初始化的时机是?
类的初始化是指在首次使用类时,JVM对类进行的初始化操作。在类初始化阶段,JVM会执行一系列的步骤。
61 0
04-面试:类的初始化做了什么?初始化的时机是?
|
消息中间件 JavaScript 小程序
阿里云面试:Spring 中 Bean 的生命周期是怎样的?
阿里云面试:Spring 中 Bean 的生命周期是怎样的?
|
XML Java 数据库连接
看了这一篇Spring容器Bean的生命周期,面试再也不用怕了
上一篇我们介绍了Spring IOC容器的启动过程以及bean的实例化过程,这一篇我们接着来学习另外一个知识点,就是Bean的生命周期,我们知道直接通过(new XX())来创建的实例,当这个实例没有被引用时就会被垃圾回收机制回收,但是通过IOC容器实例化的Bean的生命周期又是如何呢?
246 0
看了这一篇Spring容器Bean的生命周期,面试再也不用怕了
|
XML Java API
Java 面试必备的 Spring Bean 生命周期总结
前言 Spring 作为 IOC 容器,管理的对象称之为 bean,Java 对象在 ClassLoader 中有自己的创建和清理过程,那么 Spring Bean 在容器中也有自己的生命周期。
308 0
Java 面试必备的 Spring Bean 生命周期总结
|
Java Spring
面试常见问题-Bean的生命周期?
面试常见问题-Bean的生命周期?
71 0