@scope 申明bean的作用范围
1. 创建Car
public class Car {
private String name;
private int price;
public Car(){
System.out.println("car constructor...");
}
}
2.将Car放入bean中管理
public class MainConfig {
@Bean
public Car car(){
System.out.println("add bean car into spring");
return new Car();
}
}
3.启动spring容器
@Test
public void test04(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("IOC started");
}
运行结果如下

因此spring注册组件默认是在创建IOC容器的时候创建的
将启动spring容器的代码中创建两个car
@Test
public void test04(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("IOC started");
Car car1 = applicationContext.getBean(Car.class);
Car car2 = applicationContext.getBean(Car.class);
System.out.println(car1==car2);
}
运行结果如下

因此,可知bean默认是单例的。在创建IOC容器的时候创建的,每当获取的时候都是同一个实例。
当在配置中添加@Lazy的时候,对相应的组件将会实行懒加载。调用的时候才会去实现初始化。
配置修改如下
public class MainConfig {
@Bean
@Lazy
public Car car(){
System.out.println("add bean car into spring");
return new Car();
}
}
运行结果如下
从结果可看出,懒加载的时候。调用时才回去加载bean。并且只加载一次。
spring有如下四种作用域
prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。每次获取的时候才会调用方法创建对象;
singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。以后每次获取就是直接从容器(map.get())中拿,request:同一次请求创建一个实例session:同一个session创建一个实例
可以用@Scope申明Bean的生命周期
spring @Scope注解
修改配置成如下
public class MainConfig {
@Scope("prototype")
@Bean
public Car car(){
System.out.println("add bean car into spring");
return new Car();
}
再次运行
由结果可知。原型模式。spring初始化的时候并未去加载bean。而是在每次调用的时候再去加载。为多实例。
Spring bean的生命周期
bean的生命周期:bean创建—初始化----销毁的过程容器管理bean的生命周期:我们可以自定义初始化和销毁方法;容器在bean进行到当>前生命周期的时候来调用我们自定义的初始化和销毁方法
1.指定初始化和销毁方法
在申明组件的时候,加上初始化和销毁的方法
public class Car {
private String name;
private int price;
public Car(){
System.out.println("car constructor...");
}
public void init(){
System.out.println("car ... init...");
}
public void destroy(){
System.out.println("car ... destroy...");
}
}
通过@Bean指定init-method和destroy-method
public class MainConfig {
@Bean(initMethod = "init",destroyMethod = "destroy")
public Car car(){
System.out.println("add bean car into spring");
return new Car();
}
}
开启和销毁容器
@Test
public void test04(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("IOC started");
Car car1 = applicationContext.getBean(Car.class);
((AnnotationConfigApplicationContext) applicationContext).close();
}
运行结果如下图
由图可知:在组件创建的时候init方法被调用。在组件销毁的时候,destroy方法被调用。
当组件被申明为原型模式
public class MainConfig {
@Scope("prototype")
@Bean(initMethod = "init",destroyMethod = "destroy")
public Car car(){
System.out.println("add bean car into spring");
return new Car();
}
运行结果如下图所示
从结果可看出,如果bean是多实例,spring只负责创建Bean,在容器关闭时并不销毁bean。
实现InitializingBean(定义初始化逻辑) DisposableBean(定义销毁逻辑)
代码如下
public class Car implements InitializingBean, DisposableBean {
private String name;
private int price;
public Car(){
System.out.println("car constructor...");
}
@Override
public void destroy(){
System.out.println("car ... destroy...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("car ... afterPropertiesSet...");
}
}
运行结果如下
BeanPostProcessor
BeanPostProcessor,针对所有Spring上下文中所有的bean,配置一个BeanPostProcessor,然后对所有的bean进行一个初始化之前和之后的代理。BeanPostProcessor接口中有两个方法: postProcessBeforeInitialization和postProcessAfterInitialization。 postProcessBeforeInitialization方法在bean初始化之前执行, postProcessAfterInitialization方法在bean初始化之后执行。
1.创建MyBeanPostProcessor继承BeanPostProcessor接口,重写postProcessBeforeInitialization和postProcessAfterInitialization两个方法。
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("------------------------------");
System.out.println("对象------" + beanName + "postProcessBeforeInitialization-----"+bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("------------------------------");
System.out.println("对象-----" + beanName + "postProcessAfterInitialization-----"+bean);
return bean;
}
}
2.将MyBeanPostProcessor加入容器管理
@Configuration
public class MainConfig {
@Bean(initMethod = "init",destroyMethod = "destroy")
public Car car(){
System.out.println("add bean car into spring");
return new Car();
}
@Bean
public MyBeanPostProcessor myBeanPostProcessor(){
return new MyBeanPostProcessor();
}
}
3.启动spring容器
@Test
public void test04(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("IOC started");
Car car1 = applicationContext.getBean(Car.class);
((AnnotationConfigApplicationContext) applicationContext).close();
}
运行结果如下图
由结果可知:在每个bean的初始化前后都调用了BeanPostProcessor
网友评论