@Bean的生命周期
bean创建—初始化—销毁
容器管理bean的生命周期
我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
构造(对象创建)
单实例:在容器启动的时候创建对象
多实例:在每次获取的时候创建对象
初始化:
对象创建完成,并赋值好,调用初始化方法
销毁:
容器关闭的时候销毁
1.指定初始化和销毁方法;
以前基于配置,有init-method、destory-method属性去配置方法,方法必须没有参数,但是可以抛任何异常
public class Car{
public Car(){
}
public void init(){}
public void destory(){}
}
@Configuration
public class MyConfig{
@Bean
public Car car{
return new Car();
}
}
现在通过@Bean指定init-method、destory-method
2.通过让Bean实现InitializingBean接口(定义初始化逻辑)
DisposableBean接口(定义销毁逻辑)
@Component
public class Cat implements InitializingBean, DisposableBean {
public Cat(){}
//在容器关闭的时候进行调用
@Override
public void destroy() throws Exception {
}
//在Bean创建完成,并且属性都赋值好后调用
@Override
public void afterPropertiesSet() throws Exception {
}
}
3.@PostConstruct和@PreDestory;使用JSR250
@PostConstruct:在bean创建完成并且属性赋值好后,来执行初始化方法;标注在方法上
@PreDestory:在容器销毁bean之前通知我们进行清理工作
public class Dog{
public Dog(){}
//对象创建并赋值后调用
@PostConstruct
public void init(){}
//容器移除对象之前调用
@PreDestory
public void destory(){}
}
4.BeanPostProcessor接口:bean的后置处理器
在bean初始化前后进行一些处理工作
postProcessBeforeInitialization:初始化之前进行后置处理工作
postProcessAfterInitialization:初始化之后进行后置处理工作
Spring底层对BeanPostProcessor的使用:
bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,XXX等等的功能,都是通过BeanPostProcessor来完成的
@Value赋值:
1.基本数值
2.可以写SpEL;#{}
3.可以写
;
取
出
配
置
文
件
(
运
行
环
境
变
量
)
中
的
值
先
使
用
@
P
r
o
p
e
r
t
y
S
o
u
r
c
e
读
取
外
部
配
置
文
件
中
的
K
/
V
保
存
到
运
行
环
境
变
量
中
;
加
载
完
外
部
的
配
置
文
件
以
后
使
用
{};取出配置文件(运行环境变量)中的值 先使用@PropertySource读取外部配置文件中的K/V保存到运行环境变量中;加载完外部的配置文件以后使用
;取出配置文件(运行环境变量)中的值先使用@PropertySource读取外部配置文件中的K/V保存到运行环境变量中;加载完外部的配置文件以后使用{}取出配置文件的值
@PropertySource(value={"classpath:/person.properties"})
@Configuration
public class MainConfigOfPropertyValues{
@Bean
public Person person(){
return new Person();
}
}
public class Person{
@Value("张三")
private String name;
@Value("#{20-2}")
private Integer age;
@Value("${person.nickName}")
private String nickName;
}
person.properties文件内容
person.nickName=......
自动装配:
Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系赋值;
1.@Autowired:自动注入
1).默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);
2).如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找
applicationContext.getBean(“bookDao”);
3).@Qualifier(“bookDao”):使用@Qualifier指定需要装配的组件的id,而不是使用属性名
4).自动装配默认一定要将属性赋值好,没有就会报错;
5).@Primary:让Spring进行自动装配的时候,默认会使用首选的bean;
也可以继续使用@Qualifier指定需要装配的bean的名字
2.Spring还支持使用@Resource(JSR250)和@Inject(JSR330)【Java规范的注解】
@Resource:可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的
@Resource(name=“bookDao2”)
没有支持@Primary功能,没有支持@Autowired(require=“false”);
@Inject:要使用此注解需要导入依赖,javax.inject,和Autowired的功能一样,但是没有require=false的功能
@Autowired是Spring定义的,而@Resource和@Inject是Java的规范
3.@Autowired:可以标注在构造器、参数、方法、属性上;都是从容器中获取参数组件的值
1)标注在方法上:Spring容器创建当前对象,就会调用方法,完成赋值;方法使用的参数,自定义类型的值从ioc容器中进行获取
@Autowired
public void setCar(Car car){
this.car = car;
}
@Bean标注的方法创建对象的时候,方法参数的值从容器中获取
@Bean
public Color color(Car car){ //car从容器中获取
Color color = new Color();
color.setCar(car);
return color;
}
默认加在ioc容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作
构造器要用的组件、参数,也是从容器中获取的
2)标注在构造器:如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取
3)放在参数位置;
4.自定义组件想要使用Spring容器底层的一些组件(ApplicationContext、BeanFactory、XXX)
自定义组件实现XXXAware接口:在创建对象的时候,会调用接口规定的方法注入相关组件;参照Aware接口设计
把Spring底层一些组件注入到自定义的Bean中;
XXXAware的功能是使用XXXProcessor(后置处理器)来实现的;
ApplicationContextAware===>ApplicationContextAwareProcessor