Spring注解学习之:Bean的初始化和销毁

首先,一个Bean是有生命周期的,IOC容器帮我创建--->初始化---->销毁Bean;通过配置文件的方式,可以再<bean/>标签中进行参数设定,init-method属性和destroy-method的属性。通过该属性,分别指定没有参数的方法,进行初始化和销毁操作;同样的,我们可以通过注解的形式,来自定义初始化或者销毁方法;

1、@Bean(initMethod = "",destroyMethod = "")

1、定义一个Student类
public class Student {
    public Student() {
        System.out.println("Student构造器方法开始执行...");
    }

    public void init(){
        System.out.println("Student初始化方法开始执行...");
    }
    public void destroy(){
        System.out.println("Student销毁方法开始执行...");
    }
}

------------------------------------------------------------
2、MyConfig.class
@Configuration
public class MyConfig {

    @Bean(initMethod = "init",destroyMethod = "destroy")
    public Student student(){
        return new Student();
    }
}

首先第一种情况,只仅仅创建IOC容器,看下会有什么结果,上代码:

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootAnnocationApplicationTests {


    @Test
    public void contextLoads() {
        ApplicationContext alicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
    }

}



结果:
Student构造器方法开始执行...
Student初始化方法开始执行...
2019-04-25 10:15:26.529  INFO 9576 --- [       Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
Student销毁方法开始执行...

可以看到,只是仅仅创建IOC容器,Student的无参构造方法,初始化方法,销毁方法都有执行,why?因为我们在创建bean的时候,默认是单实例的,而单实例的Bean会在IOC创建的时候创建,销毁的时候销毁。我们获取两个student,看看==是否为true,上代码:

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootAnnocationApplicationTests {


    @Test
    public void contextLoads() {
        ApplicationContext alicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        Object student1 = alicationContext.getBean("student");
        Object student2 = alicationContext.getBean("student");
        System.out.println(student1 == student2);
    }

}


结果:
Student构造器方法开始执行...
Student初始化方法开始执行...
true
2019-04-25 10:21:49.300  INFO 5612 --- [       Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
Student销毁方法开始执行...

打印结果符合预期效果!那这里修改一下Bean的作用域为prototype,看下打印结果,上代码:

MyConfig.class

@Configuration
public class MyConfig {


    @Bean(initMethod = "init",destroyMethod = "destroy")
    @Scope("prototype")
    public Student student(){
        return new Student();
    }
}


--------------------------------------------------------
测试一:只创建IOC容器,看打印结果:
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootAnnocationApplicationTests {


    @Test
    public void contextLoads() {
        ApplicationContext alicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
    }

}

结果什么也没有

-----------------------------------------------------------
测试一:创建IOC容器,获取2次Bean,看打印结果:
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootAnnocationApplicationTests {


    @Test
    public void contextLoads() {
        ApplicationContext alicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        Object student1 = alicationContext.getBean("student");
        Object student2 = alicationContext.getBean("student");
        System.out.println(student1 == student2);
    }

}

结果:
Student构造器方法开始执行...
Student初始化方法开始执行...
Student构造器方法开始执行...
Student初始化方法开始执行...
false

当把Bean的作用域转为Prototype之后,创建IOC的时候,并没有打印Student的无参构造方法和初始化方法,每次getBean的时候,都要打印,而且==为false,符合多实例Bean的定义;还有一点要注意:多实例下的Bean,IOC容器直管创建,不管销毁!!!!故而看不到有打印“Student销毁方法开始执行...”这句话。

2、通过Bean实现InitializingBean, DisposableBean 接口,来实现Bean的初始化和销毁方法;InitializingBean接口有一个afterPropertiesSet()的方法,该方法就是说再完成Bean的创建以及属性设定完成之后执行,相当于初始化;DisposableBean接口有一个destroy()方法,用于销毁Bean;上代码:

1、自定义一个Student的bean,实现InitializingBean, DisposableBean接口

public class Student implements InitializingBean, DisposableBean {
    public Student() {
        System.out.println("Student构造器方法开始执行...");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Student,afterPropertiesSet方法开始执行...");

    }

    @Override
    public void destroy() throws Exception {
        System.out.println("Student,destroy方法开始执行...");
    }
}
-------------------------------------------------------------------------
2、MyConfig.class
@Configuration
public class MyConfig {
    @Bean
    public Student student(){
        return new Student();
    }
}
------------------------------------------------------------------------
3、测试类及打印结果
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootAnnocationApplicationTests {
    @Test
    public void contextLoads() {
        ApplicationContext alicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
    }

}

结果:
Student构造器方法开始执行...
Student,afterPropertiesSet方法开始执行...
2019-04-25 10:37:53.386  INFO 9252 --- [       Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
Student,destroy方法开始执行...

当然,这里的Bean是单实例的,所以在IOC创建的时候就打印了,把Bean改为多实例的,和上面的情况一样,这里就不说了;

3、JSR250的@PostConstruct来初始化,@PreDestroy来销毁

4、BeanPostProcesser方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值