手机网站平台升级开不了机了

在调用服务之前,先得获得服务的引用。 ReferenceBean 就是服务的引用。它实现了一个FactoryBean接口,在我们需要一个服务时,FactoryBean接口的getObject() 方法会被调用。[code]public Object getObject() throws Exception {
return get(); //返回服务的代理。
// get() -&init()-&createProxy(map)
// 过程主要是一些参数的检查,初始化等准备工作
// 我们重点看看createProxy 方法,参数为服务需要的所有配置信息
private T createProxy(Map&String, String& map) {
URL tmpUrl = new URL("temp", "localhost", 0, map);
final boolean isJvmR
if (isInjvm() == null) {
if (url != null && url.length() & 0) { //指定URL的情况下,不做本地引用
isJvmRefer =
} else if (InjvmProtocol.getInjvmProtocol().isInjvmRefer(tmpUrl)) {
//默认情况下如果本地有服务暴露,则引用本地服务.
isJvmRefer =
isJvmRefer =
isJvmRefer = isInjvm().booleanValue();
if (isJvmRefer) {
URL url = new URL(Constants.LOCAL_PROTOCOL, NetUtils.LOCALHOST, 0, interfaceClass.getName()).addParameters(map);
invoker = refprotocol.refer(interfaceClass, url);
if (logger.isInfoEnabled()) {
("Using injvm service " + interfaceClass.getName());
if (url != null && url.length() & 0) { // 用户指定URL,指定的URL可能是对点对直连地址,也可能是注册中心URL
String[] us = Constants.SEMICOLON_SPLIT_PATTERN.split(url);
if (us != null && us.length & 0) {
for (String u : us) {
URL url = URL.valueOf(u);
if (url.getPath() == null || url.getPath().length() == 0) {
url = url.setPath(interfaceName);
if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
urls.add(url.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));
urls.add(ClusterUtils.mergeUrl(url, map));
} else { // 通过注册中心配置拼装URL
List&URL& us = loadRegistries(false);
if (us != null && us.size() & 0) {
for (URL u : us) {
URL monitorUrl = loadMonitor(u);
if (monitorUrl != null) {
map.put(Constants.MONITOR_KEY, URL.encode(monitorUrl.toFullString()));
urls.add(u.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));
if (urls == null || urls.size() == 0) {
throw new IllegalStateException("No such any registry to reference " + interfaceName
+ " on the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + ", please config &dubbo:registry address=\"...\" /& to your spring config.");
if (urls.size() == 1) {
invoker = refprotocol.refer(interfaceClass, urls.get(0));
List&Invoker&?&& invokers = new ArrayList&Invoker&?&&();
URL registryURL =
for (URL url : urls) {
// 我们重点看下这里,invokers 存放所有可用的服务调用者
// 然后集群策略会根据这些调用者做一些负载均衡处理。
// 见下一段
invokers.add(refprotocol.refer(interfaceClass, url));
if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
registryURL = // 用了最后一个registry url
if (registryURL != null) { // 有 注册中心协议的URL
// 对有注册中心的Cluster 只用 AvailableCluster
URL u = registryURL.addParameter(Constants.CLUSTER_KEY, AvailableCluster.NAME);
// 加入集群,返回一个集群调用者。它内部会做一些负载均衡的处理。
// 默认的集群策略为failfast,默认的负载均衡为随机,如果调用者只有2个,则为轮询。
invoker = cluster.join(new StaticDirectory(u, invokers));
else { // 不是 注册中心的URL
invoker = cluster.join(new StaticDirectory(invokers));
。。。// 省略
// 创建服务代理
return (T) proxyFactory.getProxy(invoker);
}接下来 我们看看 refprotocol.refer(interfaceClass, url)
refprotocol 其实是一个代理,代理谁不知道,只有在调用时才能确定。 这个代理类是动态生成,动态编译的。后面有机会我们再讲。 通过这个动态代理的使用,最终会调用到 RegistryProtocol.refer 方法。[code]public &T& Invoker&T& refer(Class&T& type, URL url) throws RpcException {
url = url.setProtocol(url.getParameter(Constants.REGISTRY_KEY, Constants.DEFAULT_REGISTRY)).removeParameter(Constants.REGISTRY_KEY);
//根据URL获得对应的注册器。
// 如果是ZK,则 registry 为ZookeeperRegistry
Registry registry = registryFactory.getRegistry(url);
if (RegistryService.class.equals(type)) {
return proxyFactory.getInvoker((T) registry, type, url);
// group="a,b" or group="*"
// 如果消费者使用了分组
Map&String, String& qs = StringUtils.parseQueryString(url.getParameterAndDecoded(Constants.REFER_KEY));
String group = qs.get(Constants.GROUP_KEY);
if (group != null && group.length() & 0 ) {
if ( ( MA_SPLIT_PATTERN.split( group ) ).length & 1
|| "*".equals( group ) ) {
return doRefer( getMergeableCluster(), registry, type, url );
// 返回调用器
return doRefer(cluster, registry, type, url);
private &T& Invoker&T& doRefer(Cluster cluster, Registry registry, Class&T& type, URL url) {
// RegistryDirectory 可以把它理解成注册资源,其中包含了消费者,服务,路由等相关信息。
// 调用者需要这些信息来进行调用
RegistryDirectory&T& directory = new RegistryDirectory&T&(type, url);
directory.setRegistry(registry); // 注册器
directory.setProtocol(protocol); // 协议
URL subscribeUrl = new URL(Constants.CONSUMER_PROTOCOL, NetUtils.getLocalHost(), 0, type.getName(), directory.getUrl().getParameters());
if (! Constants.ANY_VALUE.equals(url.getServiceInterface())
&& url.getParameter(Constants.REGISTER_KEY, true)) {
// 注册消费者
registry.register(subscribeUrl.addParameters(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY,
Constants.CHECK_KEY, String.valueOf(false)));
// 会从注册中心获得对应的服务提供者的信息
directory.subscribe(subscribeUrl.addParameter(Constants.CATEGORY_KEY,
Constants.PROVIDERS_CATEGORY
+ "," + Constants.CONFIGURATORS_CATEGORY
+ "," + Constants.ROUTERS_CATEGORY));
// 默认的cluster 为FailFastCluster
// 返回 FailfastClusterInvoker
return cluster.join(directory);
}接下来,我们看看 FailfastClusterInvoker 。FailfastClusterInvoker 继承 AbstractClusterInvoker 实现了Invoker 接口。 我们看看AbstractClusterInvoker.invoke[code]public Result invoke(final Invocation invocation) throws RpcException {
checkWheatherDestoried();// 检查此调用者是否被销毁
LoadB // 负载均衡算法
// 获得对应的Invoker。主要从RegistryDirectory 中获取。
List&Invoker&T&& invokers = list(invocation);
if (invokers != null && invokers.size() & 0) {
// 确定负载均衡算法,默认为随机
loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(invokers.get(0).getUrl()
.getMethodParameter(invocation.getMethodName(),Constants.LOADBALANCE_KEY, Constants.DEFAULT_LOADBALANCE));
loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(Constants.DEFAULT_LOADBALANCE);
//如果是异步操作默认添加invocation id
RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
// 调用FailfastClusterInvoker.doInvoke
return doInvoke(invocation, invokers, loadbalance);
}我们看看 list(invocation) 是怎么获取的。 调用关系为 list(invocation) -& AbstractDirectory.list(invocation) -&RegistryDirectory.doList(invocation)[code]// RegistryDirectory.doList
public List&Invoker&T&& doList(Invocation invocation) {
if (forbidden) { // 如果被禁止消费
throw new RpcException(RpcException.FORBIDDEN_EXCEPTION, "Forbid consumer " +
NetUtils.getLocalHost() + " access service " + getInterface().getName() + " from registry " + getUrl().getAddress() + " use dubbo version " + Version.getVersion() + ", Please check registry access list (whitelist/blacklist).");
List&Invoker&T&& invokers =
// methodInvokerMap 为方法到调用器的映射
Map&String, List&Invoker&T&&& localMethodInvokerMap = this.methodInvokerM // local reference
if (localMethodInvokerMap != null && localMethodInvokerMap.size() & 0) {
String methodName = RpcUtils.getMethodName(invocation);
Object[] args = RpcUtils.getArguments(invocation);
if(args != null && args.length & 0 && args[0] != null
&& (args[0] instanceof String || args[0].getClass().isEnum())) {
invokers = localMethodInvokerMap.get(methodName + "." + args[0]); // 可根据第一个参数枚举路由
if(invokers == null) {
invokers = localMethodInvokerMap.get(methodName);
if(invokers == null) {
invokers = localMethodInvokerMap.get(Constants.ANY_VALUE);
if(invokers == null) {
Iterator&List&Invoker&T&&& iterator = localMethodInvokerMap.values().iterator();
if (iterator.hasNext()) {
invokers = iterator.next();
return invokers == null ? new ArrayList&Invoker&T&&(0) :
}重点在 methodInvokerMap 中。那么其中的数据是这么来的呢?答案在 RegistryProtocol.doRefer 中的 directory.subscribe 。上面也提到过。[code]// RegistryDirectory
public void subscribe(URL url) {
setConsumerUrl(url);
registry.subscribe(url, this); //订阅,回调notify方法
// notify() -& refreshInvoker() -& toInvokers()
// methodInvokerMap 的赋值就在 refreshInvoker 中而 invoker 也会被初始化为 InvokerDelegete。InvokerDelegete的创建在toInvokers方法中。 InvokerDelegete 是 RegistryDirectory 中内部类。也就是一个代理。 最终会根据 protocol 调用最终的 Invoker。 例如:dubbo
protocol=&DubboProtocol
invoker=& DubboInvoker[code]// DubboProtocol
public &T& Invoker&T& refer(Class&T& serviceType, URL url) throws RpcException {
// modified by lishen
// 序列优化。主要是SerializationOptimizer
// 将需要序列化的类放入SerializationOptimizer
optimizeSerialization(url);
// create rpc invoker.
// 创建RPC 调用者
// 底层通信主要看选择了那种client
DubboInvoker&T& invoker = new DubboInvoker&T&(serviceType, url, getClients(url), invokers);
invokers.add(invoker);
// 获得client,连接
private ExchangeClient[] getClients(URL url){
//是否共享连接
boolean service_share_connect =
int connections = url.getParameter(Constants.CONNECTIONS_KEY, 0);
//如果connections不配置,则共享连接,否则每服务每连接
if (connections == 0){
service_share_connect =
connections = 1;
ExchangeClient[] clients = new ExchangeClient[connections];
for (int i = 0; i & clients. i++) {
if (service_share_connect){
// 获得共享连接,没有则创建(调initClient(url))
// 能不能共享主要看 url.address
clients[i] = getSharedClient(url);
clients[i] = initClient(url); // 创建client
* 创建新连接.
private ExchangeClient initClient(URL url) {
// client type setting.
String str = url.getParameter(Constants.CLIENT_KEY, url.getParameter(Constants.SERVER_KEY, Constants.DEFAULT_REMOTING_CLIENT));
String version = url.getParameter(Constants.DUBBO_VERSION_KEY);
boolean compatible = (version != null && version.startsWith("1.0."));
// 设置DubboCodec 编码器 (序列化的操作就在里面)
url = url.addParameter(Constants.CODEC_KEY, Version.isCompatibleVersion() && compatible ? COMPATIBLE_CODEC_NAME : DubboCodec.NAME);
//默认开启heartbeat
url = url.addParameterIfAbsent(Constants.HEARTBEAT_KEY, String.valueOf(Constants.DEFAULT_HEARTBEAT));
// BIO存在严重性能问题,暂时不允许使用
if (str != null && str.length() & 0 && ! ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str)) {
throw new RpcException("Unsupported client type: " + str + "," +
" supported client type is " + StringUtils.join(ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions(), " "));
//设置连接应该是lazy的
if (url.getParameter(Constants.LAZY_CONNECT_KEY, false)){
client = new LazyConnectExchangeClient(url ,requestHandler);
// 重点看这里,获得一个连接
client = Exchangers.connect(url ,requestHandler);
} catch (RemotingException e) {
throw new RpcException("Fail to create remoting client for service(" + url
+ "): " + e.getMessage(), e);
}创建一个连接,最终定为到了Exchangers.connect(url ,requestHandler);[code]// Exchangers
public static ExchangeClient connect(URL url, ExchangeHandler handler) throws RemotingException {
if (url == null) {
throw new IllegalArgumentException("url == null");
if (handler == null) {
throw new IllegalArgumentException("handler == null");
// 如果没有编码器,则设置一个ExchangeCodec编码器
// 但前面已经设置过了
// 后面会讲
url = url.addParameterIfAbsent(Constants.CODEC_KEY, "exchange");
// 获得一个连接
return getExchanger(url).connect(url, handler);
public static Exchanger getExchanger(URL url) {
String type = url.getParameter(Constants.EXCHANGER_KEY, Constants.DEFAULT_EXCHANGER); // 默认为header
return getExchanger(type);
public static Exchanger getExchanger(String type) {
// 最终获得 HeaderExchanger
// 怎么获得前面也讲过,主要通过类路径扫描定义文件
// header -& HeaderExchanger
return ExtensionLoader.getExtensionLoader(Exchanger.class).getExtension(type);
}我们在看看HeaderExchanger[code]// HeaderExchanger
public ExchangeClient connect(URL url, ExchangeHandler handler) throws RemotingException {
// 根据底层client 封装一个HeaderExchangeClient
// 重点看Transporters.connect。
return new HeaderExchangeClient(Transporters.connect(url, new DecodeHandler(new HeaderExchangeHandler(handler))));
}Transporters.connect 最终会调用 ExtensionLoader.getExtensionLoader(Transporter.class).getAdaptiveExtension() 如果没有特别指定,将最终使用NettyTransporter。 netty为默认的通信方式。(见Transporter.class 的注解) 在NettyTransporter中会直接new NettyClient[code]// NettyClient
// 此方法将由父类的构造方法调用,然后再调用connect()
protected void doOpen() throws Throwable {
NettyHelper.setNettyLoggerFactory();
bootstrap = new ClientBootstrap(channelFactory);
// @see org.jboss.netty.channel.socket.SocketChannelConfig
bootstrap.setOption("keepAlive", true); //长连接
bootstrap.setOption("tcpNoDelay", true);
bootstrap.setOption("connectTimeoutMillis", getTimeout());
final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() {
// getcodec()获取到的是DubboCodes编码器。序列化的操作就在对应的Codes类中
NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyClient.this);
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("decoder", adapter.getDecoder()); //解码
pipeline.addLast("encoder", adapter.getEncoder());// 编码
pipeline.addLast("handler", nettyHandler); //处理器
}doOpen() 调用完回调用doConnect,来完成通道的建立。 并保存在 NettyClient.this.channel = newC 数据的发送在父类的send方法。 发送方法的调用来源于DubboInvoker.doInvoke 方法。
如果您想留下此文,您可以将其发送至您的邮箱(将同时以邮件内容&PDF形式发送)
相关文章推荐
(Ctrl+Enter提交) &&
已有0人在此发表见解
&在& 14:47收藏到了
&&在信息爆炸的时代,您的知识需要整理,沉淀,积累!Lai18为您提供一个简单实用的文章整理收藏工具,在这里您可以收藏对您有用的技术文章,自由分门别类,在整理的过程中,用心梳理自己的知识!相信,用不了多久,您收藏整理的文章将是您一生的知识宝库!
· 蜀ICP备号-1被事务代理的spring service 不能使用注解方式发布dubbo服务的问题解决 - serv - ITeye技术网站
使用 @com.alibaba.dubbo.config.annotation.Service 发布dubbo服务的时候,当服务类没有加入@Transactional的时候没有问题.
但是当加入事务后,spring bean 事务代理, dubbo的 AnnotationBean 扫描 类执行下面的代码的时候就获取不到对应的注解,也就发布不了服务:
Service service = bean.getClass().getAnnotation(Service.class);
if (service != null) {
因为被cglib 或者 java proxy 代理的类获取不到该dubbo service注解.
让代理类可以获取@com.alibaba.dubbo.config.annotation.Service , name就需要在 该注解上加入
java.lang.annotation.Inherited
意思是: 使代理类继承该注解,使之可以通过bean.getClass().getAnnotation(Service.class) 获取到.
这样 dubbo的export() 发布逻辑可以正常执行 . 那么dubbo服务即可正常发布了.
需要侵入dubbo的源码,不过貌似没别的好些的办法.否则就只能手动通过 javaconfig 或者 xml 去发布服务.
因为dubbo使用的spring 版本默认比较老. 所以通过dubbo.xml的 方式发布会跟默认的spring 上下文的bean加载冲突.报一些莫名其妙的问题. 比如 bean找不到之类的. 原因就是 因为dubbo的bean初始化和 现有的工程的spring 高版本的初始化机制冲突.
那么通过这种方式.就不侵入现有的spring bean上下文. 只是 加载了一个 AnnotationBean 这么个bean 由这个bean 去扫描有dubbo service注解的类,找到对应的bean并且export() 发布服务出去.
下载次数: 185
(973.2 KB)
下载次数: 221
浏览 15834
论坛回复 /
(2 / 7026)
noddle0592 写道noddle0592 写道正好有碰到这个问题,多谢楼主公布方法,先试试看经尝试,楼主的方法行不通楼主方法无法使用的原因如下:1.经过spring的动态代理生成的类使用String beanClassName = bean.getClass().getName();获取到的类名已经不是当前类的类名,所以isMatchPackage方法中就不匹配了。2.经过spring的动态代理生成的类使用Service service = bean.getClass().getAnnotation(Service.class);查找注解时,就算加入Inherited也无用。因为代理的父类中也不存在Service注解。本人的解决方法如下在com.alibaba.dubbo.config.spring.AnnotationBean.java文件内1.添加两个方法&&& /**&&&& * 获取动态代理类的原始类全名称&&&& * @param bean 动态代理类的类对象&&&& * @return 原始类的类全名称&&&& */&&& private String getProxyBeanClassName(Object bean) {&&&&
// 此时bean为代理类,需要获取真正的类名&&&&
Class&?& interfaceCls = bean.getClass().getInterfaces()[0];&&&&
// 接口的实现类正好是在接口的impl包下,并且实现类名称为接口名称加上Impl结尾&&&&
StringBuilder nameBuilder = new StringBuilder();&&&&
nameBuilder.append(interfaceCls.getPackage().getName()).append(".impl.").append(interfaceCls.getSimpleName()).append("Impl");&&&&
return nameBuilder.toString();&&& }&&& &&& /**&&&& * 是否是由动态代理生成的类&&&& */&&& private boolean isProxy(Object bean) {&&&
if (bean instanceof Proxy) {&&&
&&& }2.修改isMatchPackage方法内的String beanClassName = bean.getClass().getName();为String beanClassName = this.isProxy(bean) ? this.getProxyBeanClassName(bean) : bean.getClass().getName();3.修改postProcessAfterInitialization方法内的Service service = bean.getClass().getAnnotation(Service.class);为Service service =try { service = this.isProxy(bean) ? Class.forName(this.getProxyBeanClassName(bean)).getAnnotation(Service.class) :
bean.getClass().getAnnotation(Service.class);} catch (ClassNotFoundException e) { // don't care}你这样子修改后能不能解决问题?会不会带来其它的问题不混淆代码就没什么问题。当你要混淆代码的时候,找不到类的问题就会出现
noddle0592 写道正好有碰到这个问题,多谢楼主公布方法,先试试看经尝试,楼主的方法行不通楼主方法无法使用的原因如下:1.经过spring的动态代理生成的类使用String beanClassName = bean.getClass().getName();获取到的类名已经不是当前类的类名,所以isMatchPackage方法中就不匹配了。2.经过spring的动态代理生成的类使用Service service = bean.getClass().getAnnotation(Service.class);查找注解时,就算加入Inherited也无用。因为代理的父类中也不存在Service注解。本人的解决方法如下在com.alibaba.dubbo.config.spring.AnnotationBean.java文件内1.添加两个方法&&& /**&&&& * 获取动态代理类的原始类全名称&&&& * @param bean 动态代理类的类对象&&&& * @return 原始类的类全名称&&&& */&&& private String getProxyBeanClassName(Object bean) {&&&&
// 此时bean为代理类,需要获取真正的类名&&&&
Class&?& interfaceCls = bean.getClass().getInterfaces()[0];&&&&
// 接口的实现类正好是在接口的impl包下,并且实现类名称为接口名称加上Impl结尾&&&&
StringBuilder nameBuilder = new StringBuilder();&&&&
nameBuilder.append(interfaceCls.getPackage().getName()).append(".impl.").append(interfaceCls.getSimpleName()).append("Impl");&&&&
return nameBuilder.toString();&&& }&&& &&& /**&&&& * 是否是由动态代理生成的类&&&& */&&& private boolean isProxy(Object bean) {&&&
if (bean instanceof Proxy) {&&&
&&& }2.修改isMatchPackage方法内的String beanClassName = bean.getClass().getName();为String beanClassName = this.isProxy(bean) ? this.getProxyBeanClassName(bean) : bean.getClass().getName();3.修改postProcessAfterInitialization方法内的Service service = bean.getClass().getAnnotation(Service.class);为Service service =try { service = this.isProxy(bean) ? Class.forName(this.getProxyBeanClassName(bean)).getAnnotation(Service.class) :
bean.getClass().getAnnotation(Service.class);} catch (ClassNotFoundException e) { // don't care}你这样子修改后能不能解决问题?会不会带来其它的问题
正好有碰到这个问题,多谢楼主公布方法,先试试看经尝试,楼主的方法行不通楼主方法无法使用的原因如下:1.经过spring的动态代理生成的类使用String beanClassName = bean.getClass().getName();获取到的类名已经不是当前类的类名,所以isMatchPackage方法中就不匹配了。2.经过spring的动态代理生成的类使用Service service = bean.getClass().getAnnotation(Service.class);查找注解时,就算加入Inherited也无用。因为代理的父类中也不存在Service注解。本人的解决方法如下在com.alibaba.dubbo.config.spring.AnnotationBean.java文件内1.添加两个方法&&& /**&&&& * 获取动态代理类的原始类全名称&&&& * @param bean 动态代理类的类对象&&&& * @return 原始类的类全名称&&&& */&&& private String getProxyBeanClassName(Object bean) {&&&&
// 此时bean为代理类,需要获取真正的类名&&&&
Class&?& interfaceCls = bean.getClass().getInterfaces()[0];&&&&
// 接口的实现类正好是在接口的impl包下,并且实现类名称为接口名称加上Impl结尾&&&&
StringBuilder nameBuilder = new StringBuilder();&&&&
nameBuilder.append(interfaceCls.getPackage().getName()).append(".impl.").append(interfaceCls.getSimpleName()).append("Impl");&&&&
return nameBuilder.toString();&&& }&&& &&& /**&&&& * 是否是由动态代理生成的类&&&& */&&& private boolean isProxy(Object bean) {&&&
if (bean instanceof Proxy) {&&&
&&& }2.修改isMatchPackage方法内的String beanClassName = bean.getClass().getName();为String beanClassName = this.isProxy(bean) ? this.getProxyBeanClassName(bean) : bean.getClass().getName();3.修改postProcessAfterInitialization方法内的Service service = bean.getClass().getAnnotation(Service.class);为Service service =try { service = this.isProxy(bean) ? Class.forName(this.getProxyBeanClassName(bean)).getAnnotation(Service.class) :
bean.getClass().getAnnotation(Service.class);} catch (ClassNotFoundException e) { // don't care}
xiangboren 写道楼主,修改了不好用呢,你能把修改过的发布一下吗或说的在详细一下吗,多谢已经上传多谢
楼主,修改了不好用呢,你能把修改过的发布一下吗或说的在详细一下吗,多谢已经上传
楼主你好,关于使用注解发布dubbo服务,不知道你有没有遇到过这样的问题?当这个服务类里面使用@Resource注解注入其它bean,发布服务可以成功,但是消费放调用的时候,会发现注入的bean=null,就是说发布dubbo服务的类里面不能使用@Resource注解。是的。不可以用的。resource 不会检查注入的bean是否已经实例化,不强依赖。
浏览: 344730 次
来自: 北京
lz,您的diagram-viewer可以访问吗?
我也遇到了被事务代理的spring service 不能使用注 ...
处理的方法,就是在ListWorker中增加对TYPE指令设置 ...
抱歉,光这么改貌似还有问题,会导致一个文件上传完毕之后不能自动 ...
虽然好几年前的帖子了,不过我最近要用到,发现源码里有个很大的坑 ...

我要回帖

更多关于 手机网站平台 的文章

 

随机推荐