目录
文章参考地址,补充并优化了些内容
1. 概述
- 什么是Bean
被称作 bean 的对象是构成应用程序的支柱也是由 Spring IoC 容器管理的。bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。
- 创建Bean的方式
Spring提供xml配置、注解配置或Java配置来实现Bean的创建和注入
- 与IoC容器的关系
Spring IoC(ApplicationContext)容器负责进行扫描Bean、进行Bean的初始化、配置和依赖管理
2. 相关注解
- 声明Bean的注解
@Component
没有明确角色的组件@Service
在业务逻辑层使用@Repository
在数据访问层使用@Controller
在控制层使用@RestController
本质上是@Controller + @ResponseBody的组合@Configuration
和Component类似,但其所有带@Bean
注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例
- 其他
-
@Scope
指定Bean的作用域singleton
:Spring 容器中有且只有一个Bean实例,只要Spring容器不销毁或退出,该Bean实例就会一直存活prototype
:每次获取Bean的时候会有一个新的实例,Spring容器不能对返回Bean实例的整个生命周期负责request
:request只适用于Web程序,每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,当请求结束后,该对象的生命周期即告结束session
:session只适用于Web程序,session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效application
:application只适用于Web程序,全局作用域
-
@Bean
方法级别的Bean,一般和 @Configuration 使用,默认情况下beanName与方法名相同 -
@PostConstruct
指定initMethod,对应XML配置中的 init-method -
@PreDestroy
指定destroyMethod,对应XML配置中的 destroy-method
3. Bean的生命周期
宏观上来说Bean的生命周期分为:定义、初始化、使用、销毁。从代码角度拆开来看,如下。
流程图
序列图
4. 演示
演示涉及五个模块的代码,分别是Spring启动类、Bean对象、BeanFactoryPostProcessor、BeanPostProcessor、InstantiationAwareBeanPostProcessorAdapter
4.1 User.java
@Component
public class User implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
private String name;
private BeanFactory beanFactory;
private String beanName;
public User() {
System.out.println("【构造器】调用User的构造器实例化");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("【注入属性】注入属性name");
this.name = name;
}
/**
* 通过<bean>的init-method属性指定的初始化方法
*/
@PostConstruct
public void userInit() {
System.out.println("【init-method】调用<bean>的init-method属性指定的初始化方法");
}
/**
* 这是BeanFactoryAware接口方法
*
* @param beanFactory
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) {
System.out.println("【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()");
this.beanFactory = beanFactory;
}
/**
* 这是BeanNameAware接口方法
*
* @param beanName
*/
@Override
public void setBeanName(String beanName) {
System.out.println("【BeanNameAware接口】调用BeanNameAware.setBeanName()");
this.beanName = beanName;
}
/**
* 这是InitializingBean接口方法
*/
@Override
public void afterPropertiesSet() {
System.out.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");
}
/**
* 这是DisposableBean接口方法
*/
@Override
public void destroy() {
System.out.println("【DisposableBean接口】调用Disposable.destroy()");
}
/**
* 通过<bean>的destroy-method属性指定的初始化方法
*/
@PreDestroy
public void userDestroy() {
System.out.println("【destroy-method】调用<bean>的destroy-method属性指定的初始化方法");
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("User{");
sb.append("name='").append(name).append('\'');
sb.append('}');
return sb.toString();
}
}
4.2 MyBeanFactoryPostProcessor.java
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor() {
super();
System.out.println("这是BeanFactoryPostProcessor实现类构造器");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) {
System.out.println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
BeanDefinition bd = arg0.getBeanDefinition("user");
bd.getPropertyValues().addPropertyValue("name", "picheng");
}
}
4.3 MyBeanPostProcessor.java
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor() {
super();
System.out.println("这是BeanPostProcessor实现类构造器!");
}
@Override
public Object postProcessAfterInitialization(Object arg0, String arg1) {
System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!");
return arg0;
}
@Override
public Object postProcessBeforeInitialization(Object arg0, String arg1) {
System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!");
return arg0;
}
}
4.4 MyInstantiationAwareBeanPostProcessor.java
@Component
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
public MyInstantiationAwareBeanPostProcessor() {
super();
System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");
}
/**
* 接口方法、实例化Bean之前调用
*/
@Override
public Object postProcessBeforeInstantiation(Class beanClass,
String beanName) {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法");
return null;
}
/**
* 接口方法、实例化Bean之后调用
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法");
return bean;
}
/**
* 接口方法、设置某个属性时调用
*/
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法");
return pvs;
}
}
4.5 DemoApplication.java
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
System.out.println("现在开始初始化容器");
ApplicationContext context = SpringApplication.run(DemoApplication.class, args);
System.out.println("容器初始化成功");
// get user,并使用
User user = context.getBean("user", User.class);
System.out.println(user);
System.out.println("现在开始关闭容器!");
((ConfigurableApplicationContext) context).close();
}
}
4.6 运行程序,查看运行结果
由于打印日志较多,只截取重要信息
现在开始初始化容器
// Porcessor初始化
这是BeanFactoryPostProcessor实现类构造器
BeanFactoryPostProcessor调用postProcessBeanFactory方法
这是BeanPostProcessor实现类构造器!
这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!
// Bean初始化
InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法
【构造器】调用User的构造器实例化
InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法
【注入属性】注入属性name
【BeanNameAware接口】调用BeanNameAware.setBeanName()
【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()
BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!
【init-method】调用<bean>的init-method属性指定的初始化方法
【InitializingBean接口】调用InitializingBean.afterPropertiesSet()
BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!
InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法
容器初始化成功
// Bean使用
User{name='picheng'}
// Bean销毁
现在开始关闭容器!
【destroy-method】调用<bean>的destroy-method属性指定的初始化方法
【DisposableBean接口】调用Disposable.destroy()