@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的实例化和初始化就有必要提前的好好了解一下。