不用被动注入的方式, 主动从 Spring Boot 应用容器中的获取 Bean 的方法

Posted 东海陈光剑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不用被动注入的方式, 主动从 Spring Boot 应用容器中的获取 Bean 的方法相关的知识,希望对你有一定的参考价值。

package com.bytedance.kunlun.interpreter.util;

import org.springframework.beans.BeansException;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

import org.springframework.stereotype.Component;

@Component

public class SpringContextUtil implements ApplicationContextAware {

// Spring应用上下文环境

    private static ApplicationContext applicationContext;

/**

* 实现ApplicationContextAware接口的回调方法,设置上下文环境

*

    * @param applicationContext

    */

    public void setApplicationContext(ApplicationContext applicationContext) {

SpringContextUtil.applicationContext = applicationContext;

}

/**

* @return ApplicationContext

*/

    public static ApplicationContext getApplicationContext() {

return applicationContext;

}

/**

* 获取对象

*

    * @param name

    * @return Object

    * @throws BeansException

    */

    public static Object getBean(String name)throws BeansException {

return applicationContext.getBean(name);

}

}

PS: @Component 注解.

从容器中主动获取Bean的使用方式

package com.bytedance.kunlun.interpreter;

import com.bytedance.kunlun.interpreter.parser.SpecificationParser;

import com.bytedance.kunlun.interpreter.spec.IQuerySpecification;

import com.bytedance.kunlun.interpreter.util.JsonUtil;

import com.bytedance.kunlun.interpreter.util.SpringContextUtil;

import com.bytedance.kunlun.sdk.drivermanager.model.DriverType;

import com.bytedance.kunlun.sdk.drivermanager.model.EngineType;

import com.bytedance.kunlun.sdk.interpreter.api.KunlunInterpreter;

import com.bytedance.kunlun.sdk.interpreter.model.*;

import org.springframework.stereotype.Service;

import java.util.ArrayDeque;

import java.util.ArrayList;

import java.util.List;

import java.util.Queue;

/**

* Kunlun 编译器实现类

*/

@Service

public class KunlunInterpreterImpl implements KunlunInterpreter {

SpecificationParser specificationParser;

@Override

    public Statement interpret(KunlunRule rule)throws Exception {

// 选择引擎

        selectEngine(rule);

KunlunExpression expression = rule.getExpression();

// BFS 解析嵌套子句

        bfsParseExpression(expression);

// 解析构建 ASTQuery 抽象语法树

        IQuerySpecification specification =specificationParser.parse(rule);

// 物理资源映射,生成真正执行的物理 SQL Statement

        Statement statement =new Statement();

if (specification !=null) {

statement.setSelectSql(specification.genSelectSql());

statement.setCountSql(specification.genSelectCountSql());

statement.setGroupBySql(specification.genSelectGroupBySql());

statement.setKvSql(specification.genSelectSqlForKV());

}

return statement;

}

private void selectEngine(KunlunRule rule) {

// 引擎选择

        if (EngineType.OLAP.equals(rule.getEngineSelector().getEngineType())

&&DriverType.CLICKHOUSE.equals(rule.getEngineSelector().getDriverType())) {

specificationParser = (SpecificationParser)SpringContextUtil.getBean("specificationParserClickHouse");

}else if (EngineType.OLAP.equals(rule.getEngineSelector().getEngineType())

&&DriverType.HIVE.equals(rule.getEngineSelector().getDriverType())) {

specificationParser = (SpecificationParser)SpringContextUtil.getBean("specificationParserHive");

}else {

throw new IllegalArgumentException("engine not supported yet!");

}

}

/**

* BFS 遍历表达式树

*

    * @param kunlunExpression

    * @throws Exception

    */

    private void bfsParseExpression(KunlunExpression kunlunExpression)throws Exception {

Queuequeue =new ArrayDeque<>();

ListexpressionList =new ArrayList<>();

// 根节点入队列

        queue.offer(kunlunExpression);

while (!queue.isEmpty()) {

// 出队列

            KunlunExpression expr =queue.poll();

ListsubExpressionList =expr.getSubExpression();

if (subExpressionList !=null && !subExpressionList.isEmpty()) {

for (KunlunExpression e :subExpressionList) {

// 子节点入队列

                    queue.offer(e);

}

}

expressionList.add(expr);

}

for (KunlunExpression e :expressionList) {

System.out.println(e);

// 解析

            parseExpression(e);

}

}

/**

* 解析表达式

*

    * @param kunlunExpression

    * @throws Exception

    */

    private void parseExpression(KunlunExpression kunlunExpression)throws Exception {

ExpressionLogicOperatorEnum logic = kunlunExpression.getLogic();

if (logic ==null) {

throw new RuntimeException("can't get operator from kunlunExpression:" +JsonUtil.toString(kunlunExpression));

}

FieldCondition fieldCondition = kunlunExpression.getFilterField();

if (fieldCondition !=null) {

// 获取特征值运算符

            this.processFieldFeature(specificationParser, kunlunExpression);

}else {

specificationParser.compose(kunlunExpression);

}

}

private void processFieldFeature(SpecificationParser specificationParser,KunlunExpression kunlunExpression)throws Exception {

FieldCondition fieldCondition = kunlunExpression.getFilterField();

FieldArithmeticOperatorEnum operator =fieldCondition.getOperator();

switch (operator) {

case GREATER_THAN:

specificationParser.greaterThan(kunlunExpression);

break;

case GREATER_EQUAL_THAN:

specificationParser.greaterEqualThan(kunlunExpression);

break;

case LESS_THAN:

specificationParser.lessThan(kunlunExpression);

break;

case LESS_EQUAL_THAN:

specificationParser.lessEqualThan(kunlunExpression);

break;

case EQUAL:

specificationParser.equals(kunlunExpression);

break;

case IN:

specificationParser.in(kunlunExpression);

break;

case BETWEEN:

specificationParser.between(kunlunExpression);

break;

case LIKE:

specificationParser.like(kunlunExpression);

break;

default:

throw new RuntimeException("unsupported operator.");

}

}

}

以上是关于不用被动注入的方式, 主动从 Spring Boot 应用容器中的获取 Bean 的方法的主要内容,如果未能解决你的问题,请参考以下文章

spring中的ioc是啥单词的缩写?

spring总结

spring中啥是ioc

Spring_day01

SSM-Spring基础

Spring源码阅读Spring容器启动原理(下)-Bean实例的创建和依赖注入