组件生命周期
认识组件的声明周期
实验1
通过@Bean指定组件的生命周期
package com.guigu.spring.ioc.bean;
@Data
public class User {
private String username;
private String password;
private Car car;
@Autowired
public void setCar(Car car) {
System.out.println("自动注入: 属性值" + car);
this.car = car;
}
public User() {
System.out.println("User 构造器...");
}
/**
* 组件初始化
*/
public void initUser() {
System.out.println("User组件初始化");
}
/**
* 组件销毁
*/
public void destoryUser() {
System.out.println("User组件销毁");
}
}
package com.guigu.spring.ioc.config;
@Configuration
public class UserConfig {
@Bean(initMethod = "initUser", destroyMethod = "destoryUser")
public User user() {
return new User();
}
}
package com.guigu.spring.ioc;
/**
* 主入口文件
*/
@SpringBootApplication
public class Spring01IocApplication {
/**
* 组件的声明周期
*/
public static void main(String[] args) {
ConfigurableApplicationContext ioc = SpringApplication.run(Spring01IocApplication.class, args);
}
}
实验2
了解 InitializingBean接口 和 DisposableBean接口的 调用时机
package com.guigu.spring.ioc.bean;
@Data
public class User implements InitializingBean, DisposableBean {
private String username;
private String password;
private Car car;
@Autowired
public void setCar(Car car) {
System.out.println("setter自动注入: 属性值" + car);
this.car = car;
}
public User() {
System.out.println("User 构造器...");
}
/**
* 组件初始化
*/
public void initUser() {
System.out.println("User组件初始化");
}
/**
* 组件销毁
*/
public void destoryUser() {
System.out.println("User组件销毁");
}
/**
* 属性设置之后调用: set赋值完成了
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("[InitializingBean]接口调用afterPropertiesSet方法");
}
@Override
public void destroy() throws Exception {
System.out.println("[DisposableBean]接口调用destroy方法");
}
}
实验3
了解 @PostConstruct 和 @PreDestroy 的执行时机
package com.guigu.spring.ioc.bean;
@Data
public class User implements InitializingBean, DisposableBean {
private String username;
private String password;
private Car car;
/**
* 构造器后置处理钩子
* 构造器之后执行
*/
@PostConstruct
public void postConstruct() {
System.out.println("@PostConstruct....");
}
/**
* 销毁预处理钩子
*/
@PreDestroy
public void preDestroy() {
System.out.println("@PreDestroy....");
}
}
实验4
理解后置处理器机制: 前面的周期都是本质都是通知, 处理机制本质是拦截, 可以直接修改bean
package com.guigu.spring.ioc.processor;
@Component // 拦截所有Bean的后置处理器
public class MyTestBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("[postProcessBeforeInitialization]: " + beanName);
if(bean instanceof User hello) {
hello.setUsername("张三测试");
System.out.println("User: " + bean);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("[postProcessAfterInitialization]: " + beanName);
return bean;
}
}
单元测试
使用单元测试测试容器
- @SpringBootTest注解用来开启测试,
- 是测试那个主程序类呢? 根据包进行匹配,
- 所以单元测试类所在的包要和主程序所在的包保持一致
注入组件并查看
package com.guigu.spring.ioc;
@SpringBootTest // 测试SpringBoot功能, 测试容器
class Spring01IocApplicationTests {
@Autowired
Car car;
@Test
void contextLoads() {
System.out.println(car);
}
}
查看容器的创建
查看单元测试方法的结果