在使用 Spring
框架后,对象以 Bean
的形式统一交给 IOC 容器去创建和管理。现阶段主流的方式是基于 SpringBoot
框架,基于注解的方式实现 Bean
的创建,但在原生 Spring
框架中其实存在三种创建 Bean 的方式。
一、基础类
BeanProcess
实体类,虽然加了@Component
等三个注解,但只在注解方式创建Bean
时用到了。
package com.nineya.spring.bean.register.entity;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Getter
@Setter
@ToString
@Component("test")
public class BeanProcess {
private String name;
@PostConstruct
public void initMethod() {
System.out.println("Bean InitMethodName: name = " + name);
}
@PreDestroy
public void destroyMethod() {
System.out.println("Bean DestroyMethodName: name = " + name);
}
}
- 后置处理器类
BeanFactoryPostProcessor
后置处理器。
package com.nineya.spring.bean.register.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public class NineyaBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("后置处理器BeanFactoryPostProcessor: postProcessBeanFactory");
}
}
BeanPostProcessor
后置处理器。
package com.nineya.spring.bean.register.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class NineyaBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("后置处理器BeanPostProcessor: postProcessAfterInitialization(" + beanName + ") :" + bean);
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("后置处理器BeanPostProcessor: postProcessBeforeInitialization(" + beanName + ") :" + bean);
return bean;
}
}
二、三种创建方式
2.1 JavaApi 方式
JavaApi
方式没有注册 BeanFactoryPostProcessor
后置处理器的接口,应该在注册添加完所有 BeanDefinition
后,手动调用执行 BeanFactoryPostProcessor
后置处理器方法。
private static void javaApi() {
// 创建bean工厂
DefaultListableBeanFactory context = new DefaultListableBeanFactory();
//构造bean定义
GenericBeanDefinition gbd = new GenericBeanDefinition();
gbd.setBeanClass(BeanProcess.class);
// 设置属性
List<PropertyValue> propertyValues = new ArrayList<>();
propertyValues.add(new PropertyValue("name", "test"));
gbd.setPropertyValues(new MutablePropertyValues(propertyValues));
// 设置生命周期方法
gbd.setInitMethodName("initMethod");
gbd.setDestroyMethodName("destroyMethod");
//注册到环境上下文
context.registerBeanDefinition("test", gbd);
context.addBeanPostProcessor(new NineyaBeanPostProcessor());
new NineyaBeanFactoryPostProcessor().postProcessBeanFactory(context);
// 通过class取得bean
BeanProcess beanProcess = context.getBean(BeanProcess.class);
System.out.println(beanProcess + " : " + beanProcess.hashCode());
}
2.2 xml方式
创建 bean
的 bean/register/spring.xml
文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.nineya.spring.bean.register.entity.BeanProcess" name="test" init-method="initMethod" destroy-method="destroyMethod">
<property name="name" value="test" />
</bean>
<!-- 注册处理器 -->
<bean class="com.nineya.spring.bean.register.processor.NineyaBeanPostProcessor"/>
<bean class="com.nineya.spring.bean.register.processor.NineyaBeanFactoryPostProcessor"/>
</beans>
读取 xml
文件创建 bean
工厂。
private static void xmlFile() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean/register/spring.xml");
// 通过class取得bean
BeanProcess beanProcess = context.getBean(BeanProcess.class);
System.out.println(beanProcess + " : " + beanProcess.hashCode());
}
2.3 注解方式
private static void annotation() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// 配置注解扫描路径
context.scan(BeanRegisterMain.class.getPackage().getName());
context.refresh();
// 通过class取得bean
BeanProcess beanProcess = context.getBean(BeanProcess.class);
System.out.println(beanProcess + " : " + beanProcess.hashCode());
}