基于BeanPostProcessor接口+自定义注解玩转策略模式

开发 前端
有人说不要用业务类实现InitializingBean接口,可以借助自定义的注解来实现类似的逻辑。那我们换这种思路实现下。

前言

有人说不要用业务类实现InitializingBean接口,可以借助自定义的注解来实现类似的逻辑。那我们换这种思路实现下。

定义注解PayType

/**
* 消息通知类型注解
* @author francis
*
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PayType {
/**
* 支付类型
* @return
*/
PayTypeEnum value();
}

其中PayTypeEnum枚举

@Getter
@AllArgsConstructor
public enum PayTypeEnum {
WX("WX", "微信"),
ZFB("A","支付宝支付"),;
private String type;
private String desc;
}

BeanPostProcessor(Bean后置处理器)

功能:它是Spring中定义的接口,在Spring容器的创建过程中(具体为Bean初始化前后)会回调BeanPostProcessor中定义的两个方法。

  • postProcessBeforeInitialization方法

会在每一个bean对象的初始化方法调用之前回调

  • postProcessAfterInitialization方法

会在每个bean对象的初始化方法调用之后被回调

源码如下:

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;

public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}

两个方法入参说明:

bean:容器正在创建的那个bean的引用beanName:容器正在创建的那个bean的名称

策略工厂实现BeanPostProcessor接口

getClass() 返回此 Object 的运行时该对象的类. 该方法返回一个Class对象, 可以通过该对象可以获取某个类的相关信息, 如构造方法 属性 方法 等

import com.example.demo.celuemoshi.PayService;
import com.example.demo.celuemoshi.PayTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Slf4j
public class StrategyFactory2 implements BeanPostProcessor {
private static final Map<PayTypeEnum, PayService> serviceMap = new ConcurrentHashMap<>();
/**
* @param bean 实例化bean的引用
* @param beanName 实例化bean的名字
* @return
* @throws
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 只对实现了PayService的类做操作
if (bean instanceof PayService) {
//获取对象运行时该对象的类
Class<?> clazz = bean.getClass();
//获取自定义的注解
PayType annotation = clazz.getAnnotation(PayType.class);
//绑定对应关系
serviceMap.put(annotation.value(), (PayService) bean);
}
return bean;
}
/**
* 寻找对应得策略处理器
*/
public PayService getHandler(PayTypeEnum type){
return serviceMap.get(type);
}
}

业务类加上@PayType

@Service
@Slf4j
@PayType(PayTypeEnum.ZFB)
public class AliService implements PayService {

public Boolean pay(String type) {
log.info("调用阿里支付={}",type);
return true;
}
}
import com.example.demo.strategy2.PayType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@Slf4j
@PayType(PayTypeEnum.WX)
public class WxServiceA implements PayService {


@Override
public Boolean pay(String type) {
log.info("调用微信支付={}",type);
return true;
}
}

定义一个控制器测试

import com.example.demo.celuemoshi.StrategyFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PayController {

@GetMapping("pay/{type}")
public boolean pay(@PathVariable("type") String type){
StrategyFactory.getService(type);
return true;
}
}

测试结果

测试微信支付:http://localhost:10001/pay/wx

测试阿里支付:http://localhost:10001/pay/zfb

责任编辑:武晓燕 来源: 今日头条
相关推荐

2021-12-30 12:30:01

Java注解编译器

2009-07-06 13:49:29

2015-02-12 15:33:43

微信SDK

2015-02-12 15:38:26

微信SDK

2024-10-14 17:18:27

2023-12-04 07:27:54

SpringMVC方法

2023-10-11 07:57:23

springboot微服务

2023-10-24 13:48:50

自定义注解举值验证

2024-04-03 09:18:03

Redis数据结构接口防刷

2013-04-10 18:40:59

微信公众平台接口开发

2023-06-06 08:01:18

自定义接口响应

2017-08-03 17:00:54

Springmvc任务执行器

2023-10-09 07:37:01

2023-12-28 08:22:33

响应数据转换

2020-11-25 11:20:44

Spring注解Java

2021-02-20 11:40:35

SpringBoot占位符开发技术

2024-10-09 10:46:41

springboot缓存redis

2022-02-17 07:10:39

Nest自定义注解

2024-07-02 11:42:53

SpringRedis自定义

2024-04-01 08:11:20

点赞
收藏

51CTO技术栈公众号