Spring容器扩展点
Spring容器扩展点
- BeanDefinitionRegistryPostProcessor
- BeanFactoryPostProcessor
- ImportSelector
- ImportBeanDefinitionRegistor
- BeanPostProcessor
- InstantiationAwareBeanPostProcessor--postProcessBeforeInstantiation
- SmartInstantiationAwareBeanPostProcessor--determineCandidateConstructors
- MergedBeanDefinitionPostProcessor--postProcessMergedBeanDefinition
- SmartInstantiationAwareBeanPostProcessor--getEarlyBeanReference
- InstantiationAwareBeanPostProcessor--postProcessAfterInstantiation
- InstantiationAwareBeanPostProcessor--postProcessProperties
- BeanPostProcessor--postProcessBeforeInitialization
- BeanPostProcessor--postProcessAfterInitialization
- Aware--初始化阶段调用
- 多种Bean初始化方法执行顺序
- Bean创建完成之后
- 多种Bean销毁方法执行顺序
BeanDefinitionRegistryPostProcessor
用来注册BeanDefinition,后期可生成bean。processor本身也会注册为Bean。
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
//可以使用builder来获取BeanDefinition, 也可以手动创建
// BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(OrderService.class);
// BeanDefinition beanDefinition1 = builder.getBeanDefinition();
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(OrderService.class);
beanDefinition.getPropertyValues().add("orderId", 001);
registry.registerBeanDefinition("orderService", beanDefinition);
}
@Configuration
@ComponentScan
public class AppConfig {
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
OrderService orderService = (OrderService) applicationContext.getBean("orderService");
System.out.println(orderService);
}
}
BeanFactoryPostProcessor
可以注册/修改BeanDefinition,或者修改Bean工厂里面的Bean。processor本身也会注册为Bean。
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
OrderService orderService = (OrderService) configurableListableBeanFactory.getBean("orderService");
orderService.setOrderId(2L);
}
}
ImportSelector
配置@Import使用,导入需要生成Bean的类,最终生成的Bean名称与类名相同。selector本身不会成为Bean。
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.hoitung.fyz.SpringPostProcessor.OrderService"};
}
}
@Configuration
//@ComponentScan
@Import(MyImportSelector.class)
public class AppConfig {
}
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
//OrderService orderService = (OrderService) applicationContext.getBean("orderService");
OrderService orderService = applicationContext.getBean(OrderService.class);
System.out.println(orderService);
}
}
ImportBeanDefinitionRegistor
配合@Import使用,可以注册BeanDefinition,本身不会生成Bean。有个很重要的功能是可以获取@Import注解所在类的其他注解信息。MyBatis整合Spring使用了该方法。
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(OrderService.class);
BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
beanDefinitionRegistry.registerBeanDefinition("orderServiceImport", beanDefinition);
//AnnotationMetadata 可获取import注解所在类的其他注解信息
System.out.println(annotationMetadata.getAnnotationAttributes(ComponentScan.class.getName()));
}
}
@Configuration
@ComponentScan
@Import(MyImportBeanDefinitionRegistrar.class)
public class AppConfig {
}
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
//OrderService orderService = (OrderService) applicationContext.getBean("orderService");
OrderService orderService = applicationContext.getBean(OrderService.class);
System.out.println(orderService);
}
}
BeanPostProcessor
InstantiationAwareBeanPostProcessor–postProcessBeforeInstantiation
在createBean中实例化前调用,如果改后置处理器返回了一个Bean,后续流程不会走。
@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
//此处返回实例对象,中断bean的生命周期
if(beanName.equals("orderServiceImport")) {
System.out.println(beanName+"实例化前返回对象,会中断bean的生命周期");
return new OrderService();
} else {
//此处返回null,还会继续bean的生命周期
return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
}
}
}
SmartInstantiationAwareBeanPostProcessor–determineCandidateConstructors
bean实例化时调用,返回实例化可使用的构造函数。
@Component
public class MySmartInstantiationAwareBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
if(beanClass == OrderService.class) {
try {
return new Constructor[]{beanClass.getConstructor(Long.class)};
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
return SmartInstantiationAwareBeanPostProcessor.super.determineCandidateConstructors(beanClass, beanName);
}
}
public class OrderService implements BeanNameAware {
private Long orderId;
private String beanName;
public OrderService(Long orderId) {
System.out.println("使用只有一个参数的构造器");
this.orderId = orderId;
}
public OrderService(Long orderId, String beanName) {
System.out.println("使用有两个参数的构造器");
this.orderId = orderId;
this.beanName = beanName;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
@Override
public void setBeanName(String s) {
beanName = s;
}
@Override
public String toString() {
return "OrderService{" +
"orderId=" + orderId +
", beanName='" + beanName + '\'' +
'}';
}
}
@Configuration
@ComponentScan
@Import(MyImportBeanDefinitionRegistrar.class)
public class AppConfig {
@Bean
public Long orderId() {
return 10001L;
}
}
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
//OrderService orderService = (OrderService) applicationContext.getBean("orderService");
OrderService orderService = applicationContext.getBean(OrderService.class);
System.out.println(orderService);
}
}
运行结果:
使用只有一个参数的构造器
OrderService{orderId=10001, beanName='orderServiceImport'}
MergedBeanDefinitionPostProcessor–postProcessMergedBeanDefinition
实例化后,为属性注入做准备,预解析@Autowired @Value。可以使用该方法修改beanDefinition属性注入的值。
@Component
public class MyMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition rootBeanDefinition, Class<?> aClass, String s) {
if(aClass == OrderService.class) {
System.out.println(s+"实例化后给属性注入做准备,可以给BeanDefinition指定注入的值");
rootBeanDefinition.getPropertyValues().add("orderId", 9000);
}
}
}
public class OrderService implements BeanNameAware {
private Long orderId;
private String beanName;
// public OrderService(Long orderId) {
// System.out.println("使用只有一个参数的构造器");
// this.orderId = orderId;
// }
//
// public OrderService(Long orderId, String beanName) {
// System.out.println("使用有两个参数的构造器");
// this.orderId = orderId;
// this.beanName = beanName;
// }
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
@Override
public void setBeanName(String s) {
beanName = s;
}
@Override
public String toString() {
return "OrderService{" +
"orderId=" + orderId +
", beanName='" + beanName + '\'' +
'}';
}
}
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
//OrderService orderService = (OrderService) applicationContext.getBean("orderService");
OrderService orderService = applicationContext.getBean(OrderService.class);
System.out.println(orderService);
}
}
运行结果:
orderServiceImport实例化后给属性注入做准备,可以给BeanDefinition指定注入的值
OrderService{orderId=9000, beanName='orderServiceImport'}
SmartInstantiationAwareBeanPostProcessor–getEarlyBeanReference
主要用于处理循环依赖问题。getEarlyBeanReference方法允许在Bean完全初始化之前,提前返回一个Bean的早期引用,其他依赖该Bean的Bean可以使用这个早期引用,从而避免循环依赖导致的死锁问题。
InstantiationAwareBeanPostProcessor–postProcessAfterInstantiation
postProcessAfterInstantiation方法是Spring Bean生命周期中的一个重要扩展点,允许开发者在Bean实例化之后、属性填充之前执行自定义逻辑。返回true继续属性填充,返回false表示跳过属性填充。
@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
// public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
// //此处返回实例对象,中断bean的生命周期
// if(beanName.equals("orderServiceImport")) {
// System.out.println(beanName+"实例化前返回对象,会中断bean的生命周期");
// return new OrderService(1001L);
// } else {
// //此处返回null,还会继续bean的生命周期
// return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
// }
// }
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if(bean instanceof OrderService) {
System.out.println(beanName+"跳过属性注入");
return false;
}
return true;
}
}
运行结果:
orderServiceImport跳过属性注入
OrderService{orderId=null, beanName='orderServiceImport'}
InstantiationAwareBeanPostProcessor–postProcessProperties
属性填充阶段,开发者可以通过该方法对属性值进行修改或替换。
@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if(bean instanceof OrderService) {
MutablePropertyValues mpv = pvs instanceof MutablePropertyValues ? (MutablePropertyValues) pvs : new MutablePropertyValues(pvs);
mpv.add("userName", "test");
return mpv;
}
return null;
}
}
public class OrderService implements BeanNameAware {
@Autowired
private Long orderId;
@Autowired
private String userName;
private String beanName;
public void setUserName(String userName) {
this.userName = userName;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
@Override
public void setBeanName(String s) {
beanName = s;
}
@Override
public String toString() {
return "OrderService{" +
"orderId=" + orderId +
", userName='" + userName + '\'' +
", beanName='" + beanName + '\'' +
'}';
}
}
运行结果:
OrderService{orderId=10001, userName='test', beanName='orderServiceImport'}
BeanPostProcessor–postProcessBeforeInitialization
Bean的初始化方法执行之前,对Bean进行一些额外的处理
BeanPostProcessor–postProcessAfterInitialization
在Bean初始化方法执行之后调用,此时已经有完整的bean。
Aware–初始化阶段调用
ApplicationContextAware
BeanFactoryAware
BeanNameAware
EmbeddedValueResolverAware–spel表达式解析
EnvironmentAware
ApplicationEventPublisherAware–获取事件发布器,发布事件继承ApplicationEvent,实现ApplicationListener监听
public class OrderService implements BeanNameAware, ApplicationEventPublisherAware {
@Autowired
private Long orderId;
@Autowired
private String userName;
private String beanName;
private ApplicationEventPublisher applicationEventPublisher;
public void placeOrder() {
applicationEventPublisher.publishEvent(new OrderEvent(this, "orderEvent"));
}
public void setUserName(String userName) {
this.userName = userName;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
@Override
public void setBeanName(String s) {
beanName = s;
}
@Override
public String toString() {
return "OrderService{" +
"orderId=" + orderId +
", userName='" + userName + '\'' +
", beanName='" + beanName + '\'' +
'}';
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
}
public class OrderEvent extends ApplicationEvent {
public OrderEvent(Object source, String msg) {
super(source);
System.out.println(msg);
}
}
@Component
public class OrderEventListener implements ApplicationListener<OrderEvent> {
@Override
public void onApplicationEvent(OrderEvent orderEvent) {
System.out.println("监听到事件:"+orderEvent.toString());
}
}
MessageSourceAware–国际化
ResourceLoaderAware-资源加载器,加载类路径下的文件
@Component
public class ResourceUtil implements ResourceLoaderAware {
private ResourceLoader resourceLoader;
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
public void showResourceData() throws IOException {
Resource resource = resourceLoader.getResource("classpath:spring.yml");
BufferedReader br = new BufferedReader(new InputStreamReader(resource.getInputStream()));
while(true) {
String s = br.readLine();
if(StringUtils.isEmpty(s)) {
break;
}
System.out.println(s);
}
}
}
resource下增加一个配置文件spring.xml:
order:
userName: zls
运行结果:
order:
userName: zls
多种Bean初始化方法执行顺序
@PostConstruct
实现接口InitializingBean的afterPropertiesSet方法
指定bean的init-method
Bean创建完成之后
SmartInitializingSingleton接口–所有Bean初始化完成之后调用
SmartLifecycle接口–spring容器加载完之后,可以做缓存预热,定时器启动关闭等
ContextRefreshedEvent–容器加载完成之后会发布这个事件,可以监听这个事件
ContextStoppedEvent
ContextClosedEvent
多种Bean销毁方法执行顺序
@PreDestroy
实现DisposableBean接口的destroy方法
指定bean的destroy-method