table of Contents
Article reference address , supplemented and optimized some content
1 Overview
- What is Bean
Objects called beans are the backbone of the application and are managed by the Spring IoC container. A bean is an object that is instantiated, assembled, and managed by the Spring IoC container.
- The way to create Bean
Spring provides xml configuration, annotation configuration or Java configuration to realize the creation and injection of Bean
- Relationship with IoC container
The Spring IoC (ApplicationContext) container is responsible for scanning Beans, Bean initialization, configuration and dependency management
2. Related Notes
- Declare Bean's annotation
@Component
Components without a clear role@Service
Used in the business logic layer@Repository
Use in the data access layer@Controller
Use in the control layer@RestController
Essentially a combination of @Controller + @ResponseBody@Configuration
Component and similar , but with all@Bean
annotated methods will be dynamic proxy, so the call is the same instance of the method returns
- other
-
@Scope
Specify the scope of the Beansingleton
: There is one and only one Bean instance in the Spring container. As long as the Spring container does not destroy or exit, the Bean instance will always surviveprototype
: There will be a new instance every time a Bean is obtained, and the Spring container cannot be responsible for the entire life cycle of the returned Bean instancerequest
: Request is only applicable to Web programs, each HTTP request will generate a new bean, and the bean is only valid in the current HTTP request. When the request is over, the life cycle of the object ends.session
: Session is only applicable to Web programs. The scope of session means that a new bean will be generated for each HTTP request, and the bean is only valid in the current HTTP session.application
: Application only applies to Web programs, global scope
-
@Bean
Method-level beans are generally used with @Configuration. By default, the beanName is the same as the method name -
@PostConstruct
Specify initMethod, corresponding to init-method in XML configuration -
@PreDestroy
Specify destroyMethod, corresponding to destroy-method in XML configuration
3. Bean's life cycle
Macroscopically speaking, the life cycle of a Bean is divided into: definition, initialization, use, and destruction. From the code point of view, it is as follows.
flow chart
Sequence Diagram
4. Demo
The demo involves the code of five modules, namely Spring boot class, Bean object, 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 Run the program and view the results
Due to the large number of printed logs, only important information is intercepted
现在开始初始化容器
// 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()