Tabla de contenido
Dirección de referencia del artículo , complementado y optimizado algunos contenidos.
1. Información general
- Que es Bean
Los objetos llamados beans son la columna vertebral de la aplicación y son administrados por el contenedor Spring IoC. Un bean es un objeto que crea una instancia, ensambla y administra el contenedor Spring IoC.
- La forma de crear Bean
Spring proporciona configuración xml, configuración de anotaciones o configuración de Java para realizar la creación e inyección de Bean
- Relación con el contenedor de IoC
El contenedor Spring IoC (ApplicationContext) es responsable de escanear Beans, inicialización de Bean, configuración y administración de dependencias
2. Notas relacionadas
- Declarar la anotación de Bean
@Component
Componentes sin un rol claro@Service
Utilizado en la capa de lógica empresarial@Repository
Usar en la capa de acceso a datos@Controller
Usar en la capa de control@RestController
Esencialmente una combinación de @Controller + @ResponseBody@Configuration
Componente y similar , pero con todos los@Bean
métodos anotados será proxy dinámico, por lo que la llamada es la misma instancia del método devuelve
- otro
-
@Scope
Especificar el alcance del Beansingleton
: Hay una y solo una instancia de Bean en el contenedor de Spring. Siempre que el contenedor de Spring no se destruya o salga, la instancia de Bean siempre sobreviviráprototype
: Habrá una nueva instancia cada vez que se obtenga un Bean, y el contenedor Spring no puede ser responsable de todo el ciclo de vida de la instancia de Bean devuelta.request
: La solicitud solo es aplicable a programas Web, cada solicitud HTTP generará un nuevo bean, y el bean solo es válido en la solicitud HTTP actual.Cuando finaliza la solicitud, el ciclo de vida del objeto finaliza.session
: La sesión solo es aplicable a los programas Web. El alcance de la sesión significa que se generará un nuevo bean para cada solicitud HTTP, y el bean solo es válido en la sesión HTTP actual.application
: La aplicación solo se aplica a programas web, alcance global
-
@Bean
Los beans de nivel de método se utilizan generalmente con @Configuration. De forma predeterminada, el beanName es el mismo que el nombre del método -
@PostConstruct
Especifique initMethod, correspondiente a init-method en la configuración XML -
@PreDestroy
Especifique destroyMethod, correspondiente a destroy-method en la configuración XML
3. Ciclo de vida del frijol
Macroscópicamente hablando, el ciclo de vida de un Bean se divide en: definición, inicialización, uso y destrucción. Desde el punto de vista del código, es el siguiente.
diagrama de flujo
Diagrama de secuencia
4. Demostración
La demostración incluye el código de cinco módulos, a saber, clase de arranque Spring, objeto Bean, BeanFactoryPostProcessor, BeanPostProcessor, InstantiationAwareBeanPostProcessorAdapter
4.1 Usuario.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 Ejecute el programa y vea los resultados
Debido a la gran cantidad de registros impresos, solo se intercepta información importante
现在开始初始化容器
// 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()