Spring扩展点案例
首先Spring扩展点有三个
1、BeanPostProcessor这个可以在Bean实例前后进行增强
2、BeanFactoryPostProcessor这个是用来修改Bean的元数据的
3、FactoryBean是通过java来进行初始化而不是xml
创建一个Bean的流程
我们模拟一个 “订单服务(OrderService)” 的开发场景,流程如下:
- FactoryBean:封装
OrderService 的复杂初始化(比如加载订单模板配置、初始化缓存)。
- BeanFactoryPostProcessor:在
OrderService 实例化前,动态修改其元数据(比如根据环境切换订单超时时间)。
- BeanPostProcessor:在
OrderService 初始化后,增强其方法(比如添加订单操作的日志记录)。
整个项目是标准 Spring Boot 结构,靠 @SpringBootApplication 自动启动容器,无需手动创建 ApplicationContext。
实际案例
1、首先有一个核心业务类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class OrderService { private int orderTimeout; private String orderTemplate;
@PostConstruct public void init() { System.out.println("OrderService初始化完成:超时时间=" + orderTimeout + "分钟,模板=" + orderTemplate); }
public void createOrder(String orderId) { System.out.println("创建订单:" + orderId + ",超时时间:" + orderTimeout + "分钟"); }
public void setOrderTimeout(int orderTimeout) { this.orderTimeout = orderTimeout; } public void setOrderTemplate(String orderTemplate) { this.orderTemplate = orderTemplate; } }
|
2、FactoryBean 实现 : OrderServiceFactoryBean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| @Component public class OrderServiceFactoryBean implements FactoryBean<OrderService> {
@Override public OrderService getObject() throws Exception { OrderService orderService = new OrderService(); String template = loadOrderTemplateFromConfig(); orderService.setOrderTemplate(template); orderService.setOrderTimeout(30); return orderService; }
private String loadOrderTemplateFromConfig() { System.out.println("FactoryBean:从配置中心加载订单模板"); return "标准版订单模板(含物流信息)"; }
@Override public Class<?> getObjectType() { return OrderService.class; }
@Override public boolean isSingleton() { return true; } }
|
3、BeanFactoryPostProcessor 实现:OrderMetadataProcessor(修改元数据)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| @Component public class OrderMetadataProcessor implements BeanFactoryPostProcessor, Ordered {
@Value("${spring.profiles.active:dev}") private String activeEnv;
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { BeanDefinition factoryBeanDef = beanFactory.getBeanDefinition("orderServiceFactoryBean"); if (OrderService.class.equals(factoryBeanDef.getFactoryBeanObjectType())) { int timeout = "dev".equals(activeEnv) ? 30 : 60; BeanWrapper wrapper = new BeanWrapperImpl(OrderService.class); wrapper.setPropertyValue("orderTimeout", timeout); System.out.println("BeanFactoryPostProcessor:环境=" + activeEnv + ",已修改OrderService超时时间为" + timeout + "分钟"); } }
@Override public int getOrder() { return 1; } }
|
4、BeanPostProcessor 实现:OrderLogPostProcessor(增强实例)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| @Component public class OrderLogPostProcessor implements BeanPostProcessor, Ordered {
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof OrderService) { System.out.println("BeanPostProcessor(前):OrderService即将初始化,准备校验参数"); } return bean; }
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof OrderService) { System.out.println("BeanPostProcessor(后):OrderService初始化完成,生成日志代理"); return Proxy.newProxyInstance( OrderService.class.getClassLoader(), new Class[]{OrderService.class}, (proxy, method, args) -> { if ("createOrder".equals(method.getName())) { System.out.println("【订单日志】开始执行createOrder,订单ID:" + args[0]); Object result = method.invoke(bean, args); System.out.println("【订单日志】createOrder执行完成,订单ID:" + args[0]); return result; } return method.invoke(bean, args); } ); } return bean; }
@Override public int getOrder() { return 1; } }
|
5、启动类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @SpringBootApplication public class OrderApplication { @Autowired private OrderService orderService;
@Bean public CommandLineRunner testOrderService() { return args -> { System.out.println("\n===== 测试OrderService方法 ====="); orderService.createOrder("ORDER_20240520_001"); }; }
public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
|
