diff --git a/src/org/redkale/boot/NodeServer.java b/src/org/redkale/boot/NodeServer.java index 01c3f23e8..bcc7139fa 100644 --- a/src/org/redkale/boot/NodeServer.java +++ b/src/org/redkale/boot/NodeServer.java @@ -296,10 +296,8 @@ public abstract class NodeServer { final Set sg = application.findGlobalGroup(this.sncpGroup); for (FilterEntry entry : entrys) { //service实现类 final Class type = entry.getType(); - if (type.isInterface()) continue; if (Modifier.isFinal(type.getModifiers())) continue; if (!Modifier.isPublic(type.getModifiers())) continue; - if (Modifier.isAbstract(type.getModifiers())) continue; if (!isSNCP() && factory.find(entry.getName(), type) != null) continue; final Set sameGroupAddrs = new LinkedHashSet<>(); final Map> diffGroupAddrs = new HashMap<>(); @@ -315,9 +313,13 @@ public abstract class NodeServer { } List diffGroupTransports = new ArrayList<>(); diffGroupAddrs.forEach((k, v) -> diffGroupTransports.add(loadTransport(k, server.getProtocol(), v))); - + final boolean localed = (sameGroupAddrs.isEmpty() && diffGroupAddrs.isEmpty()) || sameGroupAddrs.contains(this.sncpAddress) || type.getAnnotation(LocalService.class) != null;//本地模式 + if (localed && (type.isInterface() || Modifier.isAbstract(type.getModifiers()))) continue; //本地模式不能实例化接口和抽象类的Service类 + final ServiceType st = type.getAnnotation(ServiceType.class); + final Class resType = st == null ? type : st.value(); + if (st != null && (!isSNCP() && factory.find(entry.getName(), resType) != null)) continue; ServiceWrapper wrapper; - if ((sameGroupAddrs.isEmpty() && diffGroupAddrs.isEmpty()) || sameGroupAddrs.contains(this.sncpAddress) || type.getAnnotation(LocalService.class) != null) { //本地模式 + if (localed) { //本地模式 sameGroupAddrs.remove(this.sncpAddress); List sameGroupTransports = new ArrayList<>(); for (InetSocketAddress iaddr : sameGroupAddrs) { @@ -326,7 +328,7 @@ public abstract class NodeServer { sameGroupTransports.add(loadTransport(this.sncpGroup, server.getProtocol(), tset)); } Service service = Sncp.createLocalService(entry.getName(), getExecutor(), type, this.sncpAddress, groups, sameGroupTransports, diffGroupTransports); - wrapper = new ServiceWrapper(type, service, this.sncpGroup, entry); + wrapper = new ServiceWrapper(resType, service, this.sncpGroup, entry); if (fine) logger.fine("[" + Thread.currentThread().getName() + "] Load Service " + service); } else { sameGroupAddrs.remove(this.sncpAddress); @@ -338,7 +340,7 @@ public abstract class NodeServer { }); if (sameGroupAddrs.isEmpty()) throw new RuntimeException(type.getName() + " has no remote address on group (" + groups + ")"); Service service = Sncp.createRemoteService(entry.getName(), getExecutor(), type, this.sncpAddress, groups, loadTransport(g.toString(), server.getProtocol(), sameGroupAddrs)); - wrapper = new ServiceWrapper(type, service, "", entry); + wrapper = new ServiceWrapper(resType, service, "", entry); if (fine) logger.fine("[" + Thread.currentThread().getName() + "] Load Service " + service); } if (factory.find(wrapper.getName(), wrapper.getType()) == null) { diff --git a/src/org/redkale/net/sncp/Sncp.java b/src/org/redkale/net/sncp/Sncp.java index 0653e3996..b8b92b45e 100644 --- a/src/org/redkale/net/sncp/Sncp.java +++ b/src/org/redkale/net/sncp/Sncp.java @@ -815,7 +815,7 @@ public abstract class Sncp { * public String findSomeThing(){ * return _client.remote(_convert, _transport, 3); * } - * + * * @Override * public String updateSomeThing(String id){ * return _client.remote(_convert, _transport, 4, id); @@ -841,8 +841,8 @@ public abstract class Sncp { if (serviceClass == null) return null; if (!Service.class.isAssignableFrom(serviceClass)) return null; int mod = serviceClass.getModifiers(); + boolean realed = !(java.lang.reflect.Modifier.isAbstract(mod) || serviceClass.isInterface()); if (!java.lang.reflect.Modifier.isPublic(mod)) return null; - if (java.lang.reflect.Modifier.isAbstract(mod)) return null; final String supDynName = serviceClass.getName().replace('.', '/'); final String clientName = SncpClient.class.getName().replace('.', '/'); final String clientDesc = Type.getDescriptor(SncpClient.class); @@ -852,7 +852,7 @@ public abstract class Sncp { final String anyValueDesc = Type.getDescriptor(AnyValue.class); ClassLoader loader = Sncp.class.getClassLoader(); String newDynName = supDynName.substring(0, supDynName.lastIndexOf('/') + 1) + REMOTEPREFIX + serviceClass.getSimpleName(); - final SncpClient client = new SncpClient(name, executor, hash(serviceClass), true, createLocalServiceClass(name, serviceClass), clientAddress, groups); + final SncpClient client = new SncpClient(name, executor, hash(serviceClass), true, realed ? createLocalServiceClass(name, serviceClass) : serviceClass, clientAddress, groups); try { Class newClazz = Class.forName(newDynName.replace('/', '.')); T rs = (T) newClazz.newInstance(); @@ -883,7 +883,7 @@ public abstract class Sncp { AsmMethodVisitor mv; AnnotationVisitor av0; - cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, supDynName, null); + cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, serviceClass.isInterface() ? "java/lang/Object" : supDynName, serviceClass.isInterface() ? new String[]{supDynName} : null); { av0 = cw.visitAnnotation("Ljavax/annotation/Resource;", true); av0.visit("name", name); @@ -916,7 +916,7 @@ public abstract class Sncp { mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "", "()V", null, null)); //mv.setDebug(true); mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, supDynName, "", "()V", false); + mv.visitMethodInsn(INVOKESPECIAL, serviceClass.isInterface() ? "java/lang/Object" : supDynName, "", "()V", false); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); diff --git a/src/org/redkale/service/ServiceType.java b/src/org/redkale/service/ServiceType.java new file mode 100644 index 000000000..3048edc1e --- /dev/null +++ b/src/org/redkale/service/ServiceType.java @@ -0,0 +1,28 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.redkale.service; + +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Service的资源类型 + * + *

+ * 详情见: http://www.redkale.org + * + * @author zhangjx + */ +@Inherited +@Documented +@Target({TYPE}) +@Retention(RUNTIME) +public @interface ServiceType { + + Class value(); + +}