前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >让dubbo支持@Autowired注解

让dubbo支持@Autowired注解

作者头像
小贝壳
发布2020-03-05 14:53:47
3.9K0
发布2020-03-05 14:53:47
举报
文章被收录于专栏:贝塔博客贝塔博客

参考文章:http://dubbo.apache.org/zh-cn/docs/user/configuration/api.html

直接利用dubbo手动注册方式,对service进行注册,然后Controller 直接 @Autowired xxxService 就可以了。

代码语言:javascript
复制
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.annotation.Reference;
import com.zh.tourist.service.FeedbackService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/
  dubbo自动注入支持,让dubbo支持spring的@org.springframework.beans.factory.annotation.Autowired 并且兼容 @com.alibaba.dubbo.config.annotation.Reference
 
  @author panjing
  @link http://dubbo.apache.org/zh-cn/docs/user/configuration/api.html
 */
//@Configuration
public class DubboAutowiredSupport implements BeanDefinitionRegistryPostProcessor {
    private Environment env;
    private static final Log LOG = LogFactory.getLog(DubboAutowiredSupport.class);
    //接口实例缓存
    private static Map<Class, Object> instanceCache = new HashMap<>();
    //应用程序信息
    private ApplicationConfig application;
    //注册中心信息
    private RegistryConfig registry;
    private Boolean registryCheck;
    private Integer registryTimeout;
    public DubboAutowiredSupport() {
    }
    /
      获取dubbo的bean
     
      @param clazz
      @param <T>
      @return
     /
    public <T> T getBean(Class clazz) {
        Object instance = instanceCache.get(clazz);
        if (instance != null) {
            return (T) instance;
        }
        // 注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供方的连接
        // 引用远程服务
        ReferenceConfig<T> reference = new ReferenceConfig<>(); // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
        reference.setApplication(application);
        reference.setRegistry(registry); // 多个注册中心可以用setRegistries()
        reference.setInterface(clazz);
        reference.setCheck(registryCheck);
        reference.setTimeout(registryTimeout);
        //reference.setVersion("1.0.0");
        // 和本地bean一样使用xxxService
        instance = reference.get(); // 注意:此代理对象内部封装了所有通讯细节,对象较重,请缓存复用
        instanceCache.put(clazz, instance);
        return (T) instance;
    }
    public static void main(String[] args) {
        FeedbackService service = new DubboAutowiredSupport().getBean(FeedbackService.class);
        System.out.println(service);
    }
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        //获取所有dubbo的service,进行缓存
        if (env == null) {
            this.env = beanFactory.getBean(Environment.class);
            // 当前应用配置
            application = new ApplicationConfig();
            application.setName(env.getProperty("dubbo.application.name"));
            // 连接注册中心配置
            registry = new RegistryConfig();
            registry.setAddress(env.getProperty("dubbo.registry.address"));
            registry.setProtocol(env.getProperty("dubbo.protocol"));
            registryCheck = Boolean.valueOf(env.getProperty("dubbo.consumer.check", "false"));
            registryTimeout = Integer.valueOf(env.getProperty("dubbo.consumer.timeout"));
            registry.setCheck(registryCheck);
            registry.setTimeout(registryTimeout);
        }
        //获取到所有的控制器后,把bean注入进去
        String[] names = beanFactory.getBeanNamesForAnnotation(Controller.class);
        LOG.info(String.format("Controller 数量:%s", names.length - 1));
        for (String name : names) {
            if ("basicErrorController".equals(name)) {
                continue;
            }
            try {
                Object bean = beanFactory.getBean(name);
                if (bean != null) {
                    processAutowired(bean);
                }
            } catch (Exception e) {
                LOG.info(e);
            }
        }
    }
    /
      处理bean的自动注入
     
      @param bean
     /
    private void processAutowired(Object bean) {
        try {
            Class clazz = bean.getClass();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                //如果有Autowried注解,或者dubbo的注解,并且为null的时候
                field.setAccessible(true);
                //字段没有注入的时候进行注入
                if (field.get(bean) == null && (field.getAnnotation(Autowired.class) != null || field.getAnnotation(Reference.class) != null)) {
                    Class fieldType = field.getType();
                    //获取实例
                    Object instance = getBean(fieldType);
                    field.set(bean, instance);
                    LOG.info(String.format("%s 注入bean %s", clazz.getSimpleName(), fieldType));
                }
            }
        } catch (Exception e) {
            //抛出运行时异常中断初始化过程
            throw new RuntimeException(e);
        }
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-12-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
微服务引擎 TSE
微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档