diff --git a/src/main/java/com/newlandframework/rpc/core/DefaultModular.java b/src/main/java/com/newlandframework/rpc/core/DefaultModular.java new file mode 100644 index 0000000..b2f141a --- /dev/null +++ b/src/main/java/com/newlandframework/rpc/core/DefaultModular.java @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2018 Newland Group Holding Limited + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.newlandframework.rpc.core; + +import com.newlandframework.rpc.model.MessageRequest; + +/** + * @author tangjie<https://github.com/tang-jie> + * @filename:DefaultModular.java + * @description:DefaultModular功能模块 + * @blogs http://www.cnblogs.com/jietang/ + * @since 2018/2/1 + */ +public class DefaultModular implements Modular { + @Override + public <T> ModuleProvider<T> invoke(ModuleInvoker<T> invoker, MessageRequest request) { + return new ModuleProvider<T>() { + @Override + public ModuleInvoker<T> getInvoker() { + return invoker; + } + + @Override + public void destoryInvoker() { + invoker.destroy(); + } + }; + } +} + diff --git a/src/main/java/com/newlandframework/rpc/core/Modular.java b/src/main/java/com/newlandframework/rpc/core/Modular.java new file mode 100644 index 0000000..ee380fc --- /dev/null +++ b/src/main/java/com/newlandframework/rpc/core/Modular.java @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2018 Newland Group Holding Limited + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.newlandframework.rpc.core; + +import com.newlandframework.rpc.model.MessageRequest; + +/** + * @author tangjie<https://github.com/tang-jie> + * @filename:Modular.java + * @description:Modular功能模块 + * @blogs http://www.cnblogs.com/jietang/ + * @since 2018/2/1 + */ +public interface Modular { + <T> ModuleProvider<T> invoke(ModuleInvoker<T> invoker, MessageRequest request); +} + diff --git a/src/main/java/com/newlandframework/rpc/core/ModuleInvoker.java b/src/main/java/com/newlandframework/rpc/core/ModuleInvoker.java new file mode 100644 index 0000000..a30ca26 --- /dev/null +++ b/src/main/java/com/newlandframework/rpc/core/ModuleInvoker.java @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2018 Newland Group Holding Limited + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.newlandframework.rpc.core; + +import com.newlandframework.rpc.model.MessageRequest; + +/** + * @author tangjie<https://github.com/tang-jie> + * @filename:ModuleInvoker.java + * @description:ModuleInvoker功能模块 + * @blogs http://www.cnblogs.com/jietang/ + * @since 2018/1/31 + */ +public interface ModuleInvoker<T> { + Class<T> getInterface(); + + Object invoke(MessageRequest request) throws Throwable; + + void destroy(); +} + diff --git a/src/main/java/com/newlandframework/rpc/core/ModuleProvider.java b/src/main/java/com/newlandframework/rpc/core/ModuleProvider.java new file mode 100644 index 0000000..2db0e17 --- /dev/null +++ b/src/main/java/com/newlandframework/rpc/core/ModuleProvider.java @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2018 Newland Group Holding Limited + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.newlandframework.rpc.core; + +/** + * @author tangjie<https://github.com/tang-jie> + * @filename:ModuleProvider.java + * @description:ModuleProvider + * @blogs http://www.cnblogs.com/jietang/ + * @since 2018/1/31 + */ +public interface ModuleProvider<T> { + ModuleInvoker<T> getInvoker(); + + void destoryInvoker(); +} + diff --git a/src/main/java/com/newlandframework/rpc/core/ReflectionUtils.java b/src/main/java/com/newlandframework/rpc/core/ReflectionUtils.java index bd43ed9..2df555f 100644 --- a/src/main/java/com/newlandframework/rpc/core/ReflectionUtils.java +++ b/src/main/java/com/newlandframework/rpc/core/ReflectionUtils.java @@ -234,7 +234,7 @@ private void listField(Field f, boolean html) { } public void listMethod(Executable member, boolean html) { - provider.append(html ? "<br>  " : "\n " + modifiers(member.getModifiers())); + provider.append(html ? "<br>  " : "\n " + modifiers(member.getModifiers() & (~Modifier.FINAL))); if (member instanceof Method) { provider.append(getType(((Method) member).getReturnType()) + " "); } @@ -339,6 +339,9 @@ public List<String> getClassMethodSignature(Class<?> cls) { int modifiers = member.getModifiers(); if (Modifier.isAbstract(modifiers) && Modifier.isPublic(modifiers)) { signatureMethod.append(modifiers(Modifier.PUBLIC)); + if (Modifier.isFinal(modifiers)) { + signatureMethod.append(modifiers(Modifier.FINAL)); + } } else { signatureMethod.append(modifiers); } diff --git a/src/main/java/com/newlandframework/rpc/filter/ChainFilter.java b/src/main/java/com/newlandframework/rpc/filter/ChainFilter.java new file mode 100644 index 0000000..678eda5 --- /dev/null +++ b/src/main/java/com/newlandframework/rpc/filter/ChainFilter.java @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2018 Newland Group Holding Limited + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.newlandframework.rpc.filter; + +import com.newlandframework.rpc.core.ModuleInvoker; +import com.newlandframework.rpc.model.MessageRequest; + +/** + * @author tangjie<https://github.com/tang-jie> + * @filename:ChainFilter.java + * @description:ChainFilter功能模块 + * @blogs http://www.cnblogs.com/jietang/ + * @since 2018/1/31 + */ +public interface ChainFilter { + Object invoke(ModuleInvoker<?> invoker, MessageRequest request) throws Throwable; +} + diff --git a/src/main/java/com/newlandframework/rpc/filter/ModuleFilterChainWrapper.java b/src/main/java/com/newlandframework/rpc/filter/ModuleFilterChainWrapper.java new file mode 100644 index 0000000..2b3ed9c --- /dev/null +++ b/src/main/java/com/newlandframework/rpc/filter/ModuleFilterChainWrapper.java @@ -0,0 +1,89 @@ +/** + * Copyright (C) 2018 Newland Group Holding Limited + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.newlandframework.rpc.filter; + +import com.newlandframework.rpc.core.Modular; +import com.newlandframework.rpc.core.ModuleInvoker; +import com.newlandframework.rpc.core.ModuleProvider; +import com.newlandframework.rpc.model.MessageRequest; + +import java.util.List; + +/** + * @author tangjie<https://github.com/tang-jie> + * @filename:ModuleFilterChainWrapper.java + * @description:ModuleFilterChainWrapper功能模块 + * @blogs http://www.cnblogs.com/jietang/ + * @since 2018/2/2 + */ +public class ModuleFilterChainWrapper implements Modular { + private Modular modular; + private List<ChainFilter> filters; + + public ModuleFilterChainWrapper(Modular modular) { + if (modular == null) { + throw new IllegalArgumentException("module is null"); + } + this.modular = modular; + } + + @Override + public <T> ModuleProvider<T> invoke(ModuleInvoker<T> invoker, MessageRequest request) { + return modular.invoke(buildChain(invoker), request); + } + + private <T> ModuleInvoker<T> buildChain(ModuleInvoker<T> invoker) { + ModuleInvoker last = invoker; + + if (filters.size() > 0) { + for (int i = filters.size() - 1; i >= 0; i--) { + ChainFilter filter = filters.get(i); + ModuleInvoker<T> next = last; + last = new ModuleInvoker<T>() { + @Override + public Object invoke(MessageRequest request) throws Throwable { + return filter.invoke(next, request); + } + + @Override + public Class<T> getInterface() { + return invoker.getInterface(); + } + + @Override + public String toString() { + return invoker.toString(); + } + + @Override + public void destroy() { + invoker.destroy(); + } + }; + } + } + return last; + } + + public List<ChainFilter> getFilters() { + return filters; + } + + public void setFilters(List<ChainFilter> filters) { + this.filters = filters; + } +} + diff --git a/src/main/java/com/newlandframework/rpc/filter/support/ClassLoaderChainFilter.java b/src/main/java/com/newlandframework/rpc/filter/support/ClassLoaderChainFilter.java new file mode 100644 index 0000000..84dc520 --- /dev/null +++ b/src/main/java/com/newlandframework/rpc/filter/support/ClassLoaderChainFilter.java @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2018 Newland Group Holding Limited + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.newlandframework.rpc.filter.support; + +import com.newlandframework.rpc.core.ModuleInvoker; +import com.newlandframework.rpc.filter.ChainFilter; +import com.newlandframework.rpc.model.MessageRequest; + +/** + * @author tangjie<https://github.com/tang-jie> + * @filename:ClassLoaderChainFilter.java + * @description:ClassLoaderChainFilter功能模块 + * @blogs http://www.cnblogs.com/jietang/ + * @since 2018/1/31 + */ +public class ClassLoaderChainFilter implements ChainFilter { + @Override + public Object invoke(ModuleInvoker<?> invoker, MessageRequest request) throws Throwable { + ClassLoader ocl = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(invoker.getInterface().getClassLoader()); + + Object result = null; + try { + result = invoker.invoke(request); + return result; + } catch (Throwable throwable) { + throwable.printStackTrace(); + throw throwable; + } finally { + Thread.currentThread().setContextClassLoader(ocl); + } + } +} + diff --git a/src/main/java/com/newlandframework/rpc/filter/support/EchoChainFilter.java b/src/main/java/com/newlandframework/rpc/filter/support/EchoChainFilter.java new file mode 100644 index 0000000..0b17b60 --- /dev/null +++ b/src/main/java/com/newlandframework/rpc/filter/support/EchoChainFilter.java @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2018 Newland Group Holding Limited + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.newlandframework.rpc.filter.support; + +import com.newlandframework.rpc.core.ModuleInvoker; +import com.newlandframework.rpc.filter.ChainFilter; +import com.newlandframework.rpc.model.MessageRequest; + +/** + * @author tangjie<https://github.com/tang-jie> + * @filename:EchoChainFilter.java + * @description:EchoChainFilter功能模块 + * @blogs http://www.cnblogs.com/jietang/ + * @since 2018/1/31 + */ +public class EchoChainFilter implements ChainFilter { + @Override + public Object invoke(ModuleInvoker<?> invoker, MessageRequest request) throws Throwable { + Object o = null; + try { + System.out.println("EchoChainFilter##TRACE MESSAGE-ID:" + request.getMessageId()); + o = invoker.invoke(request); + return o; + } catch (Throwable throwable) { + throwable.printStackTrace(); + throw throwable; + } + } +} + diff --git a/src/main/java/com/newlandframework/rpc/listener/ModuleListener.java b/src/main/java/com/newlandframework/rpc/listener/ModuleListener.java new file mode 100644 index 0000000..8babbde --- /dev/null +++ b/src/main/java/com/newlandframework/rpc/listener/ModuleListener.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2018 Newland Group Holding Limited + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.newlandframework.rpc.listener; + +import com.newlandframework.rpc.core.ModuleProvider; +import com.newlandframework.rpc.model.MessageRequest; + +/** + * @author tangjie<https://github.com/tang-jie> + * @filename:ModuleListener.java + * @description:ModuleListener + * @blogs http://www.cnblogs.com/jietang/ + * @since 2018/1/31 + */ +public interface ModuleListener { + void exported(ModuleProvider<?> provider, MessageRequest request); + + void unExported(ModuleProvider<?> provider, MessageRequest request); +} + diff --git a/src/main/java/com/newlandframework/rpc/listener/ModuleListenerChainWrapper.java b/src/main/java/com/newlandframework/rpc/listener/ModuleListenerChainWrapper.java new file mode 100644 index 0000000..5092e8a --- /dev/null +++ b/src/main/java/com/newlandframework/rpc/listener/ModuleListenerChainWrapper.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2018 Newland Group Holding Limited + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.newlandframework.rpc.listener; + +import com.newlandframework.rpc.core.Modular; +import com.newlandframework.rpc.core.ModuleInvoker; +import com.newlandframework.rpc.core.ModuleProvider; +import com.newlandframework.rpc.model.MessageRequest; + +import java.util.Collections; +import java.util.List; + +/** + * @author tangjie<https://github.com/tang-jie> + * @filename:ModuleListenerChainWrapper.java + * @description:ModuleListenerChainWrapper功能模块 + * @blogs http://www.cnblogs.com/jietang/ + * @since 2018/2/2 + */ +public class ModuleListenerChainWrapper implements Modular { + private Modular modular; + private List<ModuleListener> listeners; + + public ModuleListenerChainWrapper(Modular modular) { + if (modular == null) { + throw new IllegalArgumentException("module is null"); + } + this.modular = modular; + } + + @Override + public <T> ModuleProvider<T> invoke(ModuleInvoker<T> invoker, MessageRequest request) { + return new ModuleProviderWrapper(modular.invoke(invoker, request), Collections.unmodifiableList(listeners), request); + } + + public List<ModuleListener> getListeners() { + return listeners; + } + + public void setListeners(List<ModuleListener> listeners) { + this.listeners = listeners; + } +} diff --git a/src/main/java/com/newlandframework/rpc/listener/ModuleProviderWrapper.java b/src/main/java/com/newlandframework/rpc/listener/ModuleProviderWrapper.java new file mode 100644 index 0000000..1cb01c3 --- /dev/null +++ b/src/main/java/com/newlandframework/rpc/listener/ModuleProviderWrapper.java @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2018 Newland Group Holding Limited + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.newlandframework.rpc.listener; + +import com.newlandframework.rpc.core.ModuleInvoker; +import com.newlandframework.rpc.core.ModuleProvider; +import com.newlandframework.rpc.model.MessageRequest; + +import java.util.List; + +/** + * @author tangjie<https://github.com/tang-jie> + * @filename:ModuleProviderWrapper.java + * @description:ModuleProviderWrapper功能模块 + * @blogs http://www.cnblogs.com/jietang/ + * @since 2018/1/31 + */ +public class ModuleProviderWrapper<T> implements ModuleProvider<T> { + private ModuleProvider<T> provider; + private MessageRequest request; + private List<ModuleListener> listeners; + + public ModuleProviderWrapper(ModuleProvider<T> provider, List<ModuleListener> listeners, MessageRequest request) { + if (provider == null) { + throw new IllegalArgumentException("provider is null"); + } + this.provider = provider; + this.listeners = listeners; + this.request = request; + if (listeners != null && listeners.size() > 0) { + RuntimeException exception = null; + for (ModuleListener listener : listeners) { + if (listener != null) { + try { + listener.exported(this, request); + } catch (RuntimeException t) { + exception = t; + } + } + } + if (exception != null) { + throw exception; + } + } + } + + @Override + public ModuleInvoker<T> getInvoker() { + return provider.getInvoker(); + } + + @Override + public void destoryInvoker() { + try { + provider.destoryInvoker(); + } finally { + if (listeners != null && listeners.size() > 0) { + RuntimeException exception = null; + for (ModuleListener listener : listeners) { + if (listener != null) { + try { + listener.unExported(this, request); + } catch (RuntimeException t) { + exception = t; + } + } + } + if (exception != null) { + throw exception; + } + } + } + } +} + diff --git a/src/main/java/com/newlandframework/rpc/listener/support/ModuleListenerAdapter.java b/src/main/java/com/newlandframework/rpc/listener/support/ModuleListenerAdapter.java new file mode 100644 index 0000000..0e9da9d --- /dev/null +++ b/src/main/java/com/newlandframework/rpc/listener/support/ModuleListenerAdapter.java @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2018 Newland Group Holding Limited + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.newlandframework.rpc.listener.support; + +import com.newlandframework.rpc.core.ModuleProvider; +import com.newlandframework.rpc.listener.ModuleListener; +import com.newlandframework.rpc.model.MessageRequest; +import org.apache.commons.lang3.StringUtils; + +/** + * @author tangjie<https://github.com/tang-jie> + * @filename:ModuleListenerAdapter.java + * @description:ModuleListenerAdapter功能模块 + * @blogs http://www.cnblogs.com/jietang/ + * @since 2018/2/1 + */ +public class ModuleListenerAdapter implements ModuleListener { + @Override + public void exported(ModuleProvider<?> provider, MessageRequest request) { + System.out.println(StringUtils.center("[ModuleListenerAdapter##exported]", 48, "*")); + } + + @Override + public void unExported(ModuleProvider<?> provider, MessageRequest request) { + System.out.println(StringUtils.center("[ModuleListenerAdapter##unExported]", 48, "*")); + } +} + diff --git a/src/main/java/com/newlandframework/rpc/netty/AbstractMessageRecvInitializeTask.java b/src/main/java/com/newlandframework/rpc/netty/AbstractMessageRecvInitializeTask.java index 8dae44f..96768d3 100644 --- a/src/main/java/com/newlandframework/rpc/netty/AbstractMessageRecvInitializeTask.java +++ b/src/main/java/com/newlandframework/rpc/netty/AbstractMessageRecvInitializeTask.java @@ -15,9 +15,13 @@ */ package com.newlandframework.rpc.netty; +import com.newlandframework.rpc.core.Modular; +import com.newlandframework.rpc.core.ModuleInvoker; +import com.newlandframework.rpc.core.ModuleProvider; import com.newlandframework.rpc.core.RpcSystemConfig; import com.newlandframework.rpc.model.MessageRequest; import com.newlandframework.rpc.model.MessageResponse; +import com.newlandframework.rpc.spring.BeanFactoryUtils; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.NameMatchMethodPointcutAdvisor; @@ -40,6 +44,7 @@ public abstract class AbstractMessageRecvInitializeTask implements Callable<Bool protected static final String METHOD_MAPPED_NAME = "invoke"; protected boolean returnNotNull = true; protected long invokeTimespan; + protected Modular modular = BeanFactoryUtils.getBean("modular"); public AbstractMessageRecvInitializeTask(MessageRequest request, MessageResponse response, Map<String, Object> handlerMap) { this.request = request; @@ -78,6 +83,31 @@ public Boolean call() { } } + private Object invoke(MethodInvoker mi, MessageRequest request) throws Throwable { + if (modular != null) { + ModuleProvider provider = modular.invoke(new ModuleInvoker() { + + @Override + public Class getInterface() { + return mi.getClass().getInterfaces()[0]; + } + + @Override + public Object invoke(MessageRequest request) throws Throwable { + return mi.invoke(request); + } + + @Override + public void destroy() { + + } + }, request); + return provider.getInvoker().invoke(request); + } else { + return mi.invoke(request); + } + } + private Object reflect(MessageRequest request) throws Throwable { ProxyFactory weaver = new ProxyFactory(new MethodInvoker()); NameMatchMethodPointcutAdvisor advisor = new NameMatchMethodPointcutAdvisor(); @@ -85,7 +115,7 @@ private Object reflect(MessageRequest request) throws Throwable { advisor.setAdvice(new MethodProxyAdvisor(handlerMap)); weaver.addAdvisor(advisor); MethodInvoker mi = (MethodInvoker) weaver.getProxy(); - Object obj = mi.invoke(request); + Object obj = invoke(mi, request); invokeTimespan = mi.getInvokeTimespan(); setReturnNotNull(((MethodProxyAdvisor) advisor.getAdvice()).isReturnNotNull()); return obj; diff --git a/src/main/java/com/newlandframework/rpc/netty/HashMessageRecvInitializeTask.java b/src/main/java/com/newlandframework/rpc/netty/HashMessageRecvInitializeTask.java index 13948be..0a67865 100644 --- a/src/main/java/com/newlandframework/rpc/netty/HashMessageRecvInitializeTask.java +++ b/src/main/java/com/newlandframework/rpc/netty/HashMessageRecvInitializeTask.java @@ -63,7 +63,6 @@ protected void injectInvoke() { Method method = ReflectionUtils.getDeclaredMethod(cls, request.getMethodName(), request.getTypeParameters()); utils.listMethod(method, false); String signatureMethod = utils.getProvider().toString().trim(); - int index = getHashVisitorListIndex(signatureMethod); List<ModuleMetricsVisitor> metricsVisitor = HashModuleMetricsVisitor.getInstance().getHashVisitorList().get(index); visitor.set(metricsVisitor.get(hashKey)); diff --git a/src/main/java/com/newlandframework/rpc/spring/BeanFactoryUtils.java b/src/main/java/com/newlandframework/rpc/spring/BeanFactoryUtils.java new file mode 100644 index 0000000..5db0649 --- /dev/null +++ b/src/main/java/com/newlandframework/rpc/spring/BeanFactoryUtils.java @@ -0,0 +1,90 @@ +/** + * Copyright (C) 2018 Newland Group Holding Limited + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.newlandframework.rpc.spring; + + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static org.springframework.beans.factory.BeanFactoryUtils.beanNamesForTypeIncludingAncestors; +import static org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors; + +/** + * @author tangjie<https://github.com/tang-jie> + * @filename:BeanFactoryUtils.java + * @description:BeanFactoryUtils功能模块 + * @blogs http://www.cnblogs.com/jietang/ + * @since 2018/2/1 + */ +public class BeanFactoryUtils implements BeanFactoryAware { + private static BeanFactory beanFactory; + + private static boolean isContains(String[] values, String value) { + if (value != null && value.length() > 0 && values != null && values.length > 0) { + for (String v : values) { + if (value.equals(v)) { + return true; + } + } + } + return false; + } + + public static <T> T getBean(String name) { + if (beanFactory == null) { + return null; + } + try { + return (T) beanFactory.getBean(name); + } catch (NoSuchBeanDefinitionException e) { + return null; + } + } + + public static <T> T getOptionalBean(ListableBeanFactory beanFactory, String beanName, Class<T> beanType) { + String[] allBeanNames = beanNamesForTypeIncludingAncestors(beanFactory, beanType); + if (!isContains(allBeanNames, beanName)) { + return null; + } + Map<String, T> beansOfType = beansOfTypeIncludingAncestors(beanFactory, beanType); + return beansOfType.get(beanName); + } + + public static <T> List<T> getBeans(ListableBeanFactory beanFactory, String[] beanNames, Class<T> beanType) { + String[] allBeanNames = beanNamesForTypeIncludingAncestors(beanFactory, beanType); + List<T> beans = new ArrayList<T>(beanNames.length); + for (String beanName : beanNames) { + if (isContains(allBeanNames, beanName)) { + beans.add(beanFactory.getBean(beanName, beanType)); + } + } + return Collections.unmodifiableList(beans); + } + + @Override + public void setBeanFactory(BeanFactory factory) throws BeansException { + this.beanFactory = factory; + } +} + diff --git a/src/main/resources/rpc-invoke-config-server.xml b/src/main/resources/rpc-invoke-config-server.xml index 4889efb..ac8c0a0 100644 --- a/src/main/resources/rpc-invoke-config-server.xml +++ b/src/main/resources/rpc-invoke-config-server.xml @@ -6,6 +6,8 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.newlandframework.com/nettyrpc http://www.newlandframework.com/nettyrpc/nettyrpc.xsd"> <context:property-placeholder location="classpath:rpc-server.properties"/> + <bean id="beanFactory" class="com.newlandframework.rpc.spring.BeanFactoryUtils"/> + <nettyrpc:service id="demoAddService" interfaceName="com.newlandframework.rpc.services.AddCalculate" ref="calcAddService"></nettyrpc:service> <nettyrpc:service id="demoMultiService" interfaceName="com.newlandframework.rpc.services.MultiCalculate" @@ -32,4 +34,30 @@ <bean id="storeService" class="com.newlandframework.rpc.services.impl.StoreImpl"></bean> <bean id="simpleFilter" class="com.newlandframework.rpc.filter.support.SimpleFilter"></bean> + + <!--NettyRPC Listeners And FilterChain Config by tangjie--> + <bean id="listeners" class="com.newlandframework.rpc.listener.ModuleListenerChainWrapper"> + <constructor-arg name="modular"> + <bean class="com.newlandframework.rpc.core.DefaultModular"></bean> + </constructor-arg> + <property name="listeners"> + <list> + <ref bean="listenerAdapter"/> + </list> + </property> + </bean> + <bean id="modular" class="com.newlandframework.rpc.filter.ModuleFilterChainWrapper"> + <constructor-arg name="modular" ref="listeners"/> + <property name="filters"> + <list> + <ref bean="classLoaderChainFilter"/> + <ref bean="echoChainFilter"/> + </list> + </property> + </bean> + <!--Listeners--> + <bean id="listenerAdapter" class="com.newlandframework.rpc.listener.support.ModuleListenerAdapter"/> + <!--FilterChain--> + <bean id="classLoaderChainFilter" class="com.newlandframework.rpc.filter.support.ClassLoaderChainFilter"/> + <bean id="echoChainFilter" class="com.newlandframework.rpc.filter.support.EchoChainFilter"/> </beans> diff --git a/src/test/resources/rpc-invoke-config-jdbc-server.xml b/src/test/resources/rpc-invoke-config-jdbc-server.xml index 5557e2d..37a9be2 100644 --- a/src/test/resources/rpc-invoke-config-jdbc-server.xml +++ b/src/test/resources/rpc-invoke-config-jdbc-server.xml @@ -6,6 +6,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.newlandframework.com/nettyrpc http://www.newlandframework.com/nettyrpc/nettyrpc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <context:property-placeholder location="classpath:rpc-server.properties"/> + <bean id="beanFactory" class="com.newlandframework.rpc.spring.BeanFactoryUtils"/> <nettyrpc:service id="demoAddService" interfaceName="com.newlandframework.rpc.services.AddCalculate" ref="calcAddService"></nettyrpc:service> <nettyrpc:service id="demoMultiService" interfaceName="com.newlandframework.rpc.services.MultiCalculate"