dubbo源码学习之dubbo的ioc和aop

  dubbo实现了自己的ioc注入,主要方法是ExtensionLoader里的injectExtension(T instance)方法。

private T injectExtension(T instance) {
        try {
		    //objectFactory是dubbo的ioc容器 类型是ExtensionFactory 为dubbo的ioc提供所有的对象
            if (objectFactory != null) {
                for (Method method : instance.getClass().getMethods()) {
                    if (method.getName().startsWith("set")
                            && method.getParameterTypes().length == 1
                            && Modifier.isPublic(method.getModifiers())) {
                        Class<?> pt = method.getParameterTypes()[0];
                        try {
                            String property = method.getName().length() > 3 ? method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : "";
                           //set扩展名(Object object) 格式的方法 会根据类型和扩展名从 objectFactory中取得对象                         
						   Object object = objectFactory.getExtension(pt, property);
                            if (object != null) {
							    //调用instance对象的moethod方法 并将object作为参数传入
                                method.invoke(instance, object);
                            }
                        } catch (Exception e) {
                            logger.error("fail to inject via method " + method.getName()
                                    + " of interface " + type.getName() + ": " + e.getMessage(), e);
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return instance;
    }


public <T> T getExtension(Class<T> type, String name) {
	    //从SpiExtensionFactory或者SpringExtensionFactory读取对象
        for (ExtensionFactory factory : factories) {
            T extension = factory.getExtension(type, name);
            if (extension != null) {
                return extension;
            }
        }
        return null;
    }



SpiExtensionFactory的获取
public <T> T getExtension(Class<T> type, String name) {
	    //判断接口是否被@spi注解 adaptive对象会根据dubbo的URL对象里面的值来选择接口的实现类对象
        if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
            ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
	   //如果类型支持的实现类大于0就返回extensionLoader的adaptive对象
            if (loader.getSupportedExtensions().size() > 0) {
                return loader.getAdaptiveExtension();
            }
        }
        return null;
    }


SpringExtensionFactory的获取

   public <T> T getExtension(Class<T> type, String name) {
	    //从spring的context容器中根据类型和beanName查找对象
        for (ApplicationContext context : contexts) {
            if (context.containsBean(name)) {
                Object bean = context.getBean(name);
                if (type.isInstance(bean)) {
                    return (T) bean;
                }
            }
        }
        return null;
    }


总的来说dubbo的ioc就是从dubbo的spi容器或者spring的容器中获取bean。



  private T createExtension(String name) {
        Class<?> clazz = getExtensionClasses().get(name);
        if (clazz == null) {
            throw findException(name);
        }
        try {
            T instance = (T) EXTENSION_INSTANCES.get(clazz);
            if (instance == null) {
                EXTENSION_INSTANCES.putIfAbsent(clazz, (T) clazz.newInstance());
                instance = (T) EXTENSION_INSTANCES.get(clazz);
            }
            injectExtension(instance);
            Set<Class<?>> wrapperClasses = cachedWrapperClasses;
            if (wrapperClasses != null && wrapperClasses.size() > 0) {
                for (Class<?> wrapperClass : wrapperClasses) {
		//这个地方是dubbo的aop简单实现 利用装饰模式对原有的类进行装饰 主要是ProtocolListenerWrapper(监听) ProtocolFilterWrapper(过滤)
                    instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
                }
            }
            return instance;
        } catch (Throwable t) {
            throw new IllegalStateException("Extension instance(name: " + name + ", class: " +
                    type + ")  could not be instantiated: " + t.getMessage(), t);
        }
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值