bean的生命周期
bean创建----初始化—销毁的过程
容器管理bean的生命周期
我们可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
1)指定初始化和销毁方法
指定init-method和destroy-method
初始化:对象创建完成(默认都是单例模式的饿汉模式哦,这种情况就是容器创建的时候就创建了一个bean的单实例),并赋值好,调用初始化方法
销毁:容器关闭的时候(但是多实例的Bean是不进行销毁的)
当spring容器关闭的时候,他们就会执行容器中单实例Bean的销毁方法(容器实例.close());
2)类实现InitializingBean,DisposableBean这两个接口,并重写两个方法
3)使用JSR250中的两个注解
@PostConstruct 在bean创建完成,属性赋值完成,执行初始化
@PreDestroy 在容器销毁对象之前
4)BeanPostProcessor接口,bean的后置处理器
在bean初始化前后的一些处理工作:
postProcessBeforeInitialization:在初始化之前工作
postProcessAfterInitialization:在初始化之后工作
属性赋值
1)使用@Value赋值
2)自动装配
spring利用依赖注入DI,完成对ioc容器中各个组件的依赖关系的赋值
@Autowired
private Dao dao;
1)默认优先安置类型去容器中找对应的组件:applicationContext.getBean(Dao.class);找到就赋值,
2)如果有多个,再将属性的名称作为组件的id去容器中查找
applicationContext.getBean(“dao”);
3)使用@Qualifier(“dao”),指定需要装配的组件id,而不是使用默认的属性名
4)自动装配默认一定要在容器中有这个属性的Bean,没有就会报错,如何让他有就注入,没有就算了呢@Autowired(required = false)
5)@Primary 让spring在自动装配的时候,首选这个bean,这个和@Qualifier一起用的时候,还是Qualifier它的优先级高,听他的
Spring还支持使用@Resource(JSR250)和@Inject(JSR330)
[java规范的注解,上面那个@Autowired是spring规范的注解]
@Resource
private BookDao bookDao;
也是可以的,默认安装组件的名称装配,没有能支持@Primary功能和不支持@Autowired(required=false)这个功能
@Inject 需要导入一个javax.inject的依赖,和autowired一样,能支持@Primary功能和不支持@Autowired(required=false)这个功能
推荐使用@Autowired
为什么自动装配能生效呢?
是因为AutowiredAnnotationBeanPostProcessor这个后置处理器解析完成自动装配功能
@Autowired可以标在构造器,参数,方法,属性(上面演示的都是属性)
1 标在方法上(一般是set方法),spring容器创建当前对象,就会调用方法,完成赋值,方法使用的参数默认从ioc容器中获取
2 构造器 , 如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以从ioc容器中获取
3 参数,@Bean标注的方法创建对象的时候,方法参数的值自动从ioc容器中获取,不加@Autowired也是哦
自动义组件想要用spring容器底层的一些组件(ApplicationContext,BeanFactory… XXX)
只要让自定义组件实现XXXAware,继承方法,在创建对象的时候,会调用接口规定的方法注入相关组件,Aware,类似于回调的方法
XXXAware的功能是使用XXXAwareProcessor(后置处理器)实现的
profile:spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能
开发环境,测试环境,生产环境
数据源 ( a) (b) © 不希望修改代码,切换这三类组件
环境搭建
@Profile写在配置类上,只有是指定的环境,这个类才生效
没有标注环境标识的bean在任何环境下都是加载的
根据某种环境,激活某种数据源呢?测试环境用测试数据源
使用@Profile注解,指定组件在哪个环境的情况下才能被注册到容器中,不指定的话,任何环境下都能注册这个组件
只有dev环境被激活,dev这个数据源才能被注册进来,默认就是default环境
怎么切换环境呢?
1最快捷的,使用命令行动态参数,在虚拟机参数位置加载+Dspring.profiles.active = test;
2 代码方式:不能用有参构造器,----相当于无参构造器的过程用代码写出来
no1) 创建一个applicationContext
no2)设置需要激活的环境
applicationContext.getEnvironment().setActiveProfiles(“test”,“dev”);
no3)设置主配置类
applicationContext.register(MainConfig.class)
no4)启动刷新容器
application.refresh();