利用ApplicationContextAwareshixian实现业务中根据不同标识进行分发

先简单说一下应用场景:

有时我们的业务中需要根据一个不同的标识,进入不同的处理结果,一个简单的例子的例子就是我们在调用支付宝接口或者微信的接口是,进行不同方式的加密,发送到不同的接口,然后处理返回的结果方式也不同,这时就可以使用了。

先简单说一下ApplicationContextAwareshixian接口的作用:

public interface ApplicationContextAware extends Aware {
    void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

在Web应用中,Spring容器通常采用声明式方式配置产生:开发者只要在web.xml中配置一个Listener,该Listener将会负责初始化Spring容器,MVC框架可以直接调用Spring容器中的Bean,无需访问Spring容器本身。在这种情况下,容器中的Bean处于容器管理下,无需主动访问容器,只需接受容器的依赖注入即可。

但在某些特殊的情况下,Bean需要实现某个功能,但该功能必须借助于Spring容器才能实现,此时就必须让该Bean先获取Spring容器,然后借助于Spring容器实现该功能。为了让Bean获取它所在的Spring容器,可以让该Bean实现ApplicationContextAware接口。

Spring容器会检测容器中的所有Bean,如果发现某个Bean实现了ApplicationContextAware接口,Spring容器会在创建该Bean之后,自动调用该Bean的setApplicationContextAware()方法,调用该方法时,会将容器本身作为参数传给该方法——该方法中的实现部分将Spring传入的参数(容器本身)赋给该类对象的applicationContext实例变量,因此接下来可以通过该applicationContext实例变量来访问容器本身。

下面来看代码如何实现分发
1、创建一个Spring boot项目,结构目录如下:
这里写图片描述
2、引入jar包依赖:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath />
    </parent>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

3、编写统一使用的抽象类

public abstract class TradingI implements Ordered {
    //进行一些数据的效验
    public abstract void verification(JSONObject object);
    //真正的进行业务处理
    public abstract JSONObject tradeIng(JSONObject Object);
}

4、然后编写微信的处理方式:WxTradingImpl.java

@Component(value = "thradingImplwx")
public class WxTradingImpl extends TradingI{

    int order = 2;
    @Override
    public int getOrder() {
        return this.order;
    }

    public void verification(JSONObject object) {
        System.out.println("微信交易验证");       
    }

    public JSONObject tradeIng(JSONObject Object) {
        System.out.println("执行微信交易流程");
        return null;
    }

}

5、编写支付宝处理流程:ZfbTradingImpl.java

@Component(value = "thradingImplzfb")
public class ZfbTradingImpl extends TradingI {

    int order = 1;
    @Override
    public int getOrder() {
        return this.order;
    }

    public void verification(JSONObject object) {
        System.out.println("支付宝交易验证");      
    }

    public JSONObject tradeIng(JSONObject Object) {
        System.out.println("进入交易流程");
        return null;
    }

}

注意上方的@Component来声明我们注册的bean的名称,为了我们能更好的区分这里我时用的是: “thradingImpl” + “标识”
TradingInit.java内容

@Component
public class TradingInit implements ApplicationContextAware{

    public static Map<String, TradingI> glc = new LinkedHashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.initTradChannel(applicationContext);       
    }

    private void initTradChannel(ApplicationContext applicationContext) {
        glc = BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, TradingI.class, true, false);
    }
}

TradService.java 内容:

@Service(value = "tradService")
public class TradService {
    public JSONObject invokeTrad(JSONObject object) {
        Map<String, TradingI> glc = TradingInit.glc;
        String channel = object.getString("channel");
        TradingI trad = glc.get("thradingImpl"+channel);
        trad.verification(null);
        trad.tradeIng(null);
        return object;
    }
}

为了方便测试,我们写一个接口进行测试

@RestController
public class TestController {
    @Autowired
    TradService service;
    @RequestMapping("/trad")
    public void test(String t) {
        JSONObject obj = new JSONObject();
        obj.put("channel", t);
        service.invokeTrad(obj);
    }
}

还有一个简单的配置,application.properties

server.context-path=/seq_src
server.port=9094

这样的话,我们只需要传入接口t的值,就可以进行测试了:
t = wx时:
这里写图片描述

t=zfb时:
这里写图片描述

内容很简单,就不放在GItHub了

猜你喜欢

转载自blog.csdn.net/qq_30243515/article/details/82121257
今日推荐