参考文章: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);
}
}
}