Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * 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 koper.aop; import koper.sender.MessageSender; import org.aspectj.lang.ProceedingJoinPoint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * * AbstractSendMessageAdvice * * @author kk raymondhekk9527@gmail.com * @since 1.0 * 2016120 */ public abstract class AbstractSendMessageAdvice implements ApplicationContextAware { private static Logger log = LoggerFactory.getLogger(AbstractSendMessageAdvice.class); protected ApplicationContext applicationContext; @Autowired protected MessageSender messageSender; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } /** * @param messageSender the messageSender to set */ public void setMessageSender(MessageSender messageSender) { this.messageSender = messageSender; } /** * @return the messageSender */ public MessageSender getMessageSender() { if (messageSender != null) return messageSender; else return (MessageSender) applicationContext.getBean("messageSender"); } /** * SendMsg * @param pjp * @return * @throws Throwable */ public Object around(ProceedingJoinPoint pjp) throws Throwable { Object result = null; Method method = getMethod(pjp); String beforeTopic = getBeforeSendMsgTopicOnMethod(method); Object[] args = pjp.getArgs(); if (beforeTopic != null) { // if(log.isDebugEnabled()) // log.debug("BeforeTopic='{}',Method={} " ,beforeTopic, method); sendMessageBefore(method, beforeTopic, args); } String afterTopic = getAfterSendMsgTopicOnMethod(method); try { //? result = pjp.proceed(args); if (afterTopic != null) { // if(log.isDebugEnabled()) // log.debug("AfterTopic='{}', Method {}" ,afterTopic, method); sendMessageAfter(method, afterTopic, args, result); } } catch (Throwable e) { // if(log.isDebugEnabled()) // log.debug("sendMessageAfterException exception " + e); try { sendMessageAfterException(method, afterTopic, args, e); } catch (Throwable t) { /* do nothing */ } throw e; } if (log.isDebugEnabled()) log.debug("SendMsgBeforeInvokeAdvice result " + result); return result; } /** * Send message after method invocation,using args and return values * @param targetClass * @param method * @param args */ protected void sendMessageBefore(Method method, String topic, Object[] args) { // if(log.isDebugEnabled()) // log.debug("[????]Send message before invoke, Topic={},Method={}, Args:{}",topic,method,Arrays.asList(args)); } /** * Send message before method invocation, using args * @param targetClass * @param method * @param args */ protected void sendMessageAfter(Method method, String topic, Object[] args, Object result) { // if(log.isDebugEnabled()) // log.debug("[????]Send message after invoke,Topic={}, Method={}, Args:{},Result:{}",topic, method,Arrays.asList(args),result); } /** * * @param targetClass * @param method * @param args */ protected void sendMessageAfterException(Method method, String topic, Object[] args, Throwable t) { // if(log.isDebugEnabled()) // log.debug("[????]Send message after invoke,Topic={}, Method={}, Args:{},Throwable:{}",topic,method,Arrays.asList(args),t); } /** * Get before Topic Name on Method * @param pjp * @return * @throws NoSuchMethodException */ protected String getBeforeSendMsgTopicOnMethod(Method method) throws NoSuchMethodException { SendMessageBefore sendMsgannotation = method.getAnnotation(SendMessageBefore.class); String topic = sendMsgannotation != null ? sendMsgannotation.topic() : null; if (topic == null) { topic = buildTopicName(method); topic = fixTopicName(topic); } return topic; } /** * Get after Topic Name on Method * @param pjp * @return * @throws NoSuchMethodException */ protected String getAfterSendMsgTopicOnMethod(Method method) throws NoSuchMethodException { SendMessageAfter sendMsgannotation = method.getAnnotation(SendMessageAfter.class); String topic = sendMsgannotation != null ? sendMsgannotation.topic() : null; if (topic == null) { topic = buildTopicName(method); topic = fixTopicName(topic); } return topic; } /** * ?topic name * @param method */ protected String buildTopicName(Method method) { String topic = method.getDeclaringClass().getName() + "." + method.getName(); return topic; } private final static Map<String, Method> methodCache = new ConcurrentHashMap<>(1024); /** * Get method of joinpoint * @param pjp * @return */ protected Method getMethod(ProceedingJoinPoint pjp) { Class<?> clazz = pjp.getTarget().getClass(); String methodName = pjp.getSignature().getName(); Method method = null; int argCount = pjp.getArgs().length; // Object[] args = pjp.getArgs(); // Class<?>[] argClasses = new Class[args.length]; // for (int i = 0; i < args.length; i++) { // Class<?> argClass = args[i].getClass(); // // argClass = convertActualClass( argClass ); // argClasses[i] = args[i]!=null ? args[i].getClass() : null; // } try { String key = clazz.getName() + "." + methodName + "#" + argCount; if ((method = methodCache.get(key)) == null) { method = getMethodFromClass(clazz, methodName, argCount); if (method != null) { methodCache.put(key, method); } else { log.error("AOP pointcut method not found! methodName={},argCount={}", methodName, argCount); } } } catch (Exception e) { throw new RuntimeException("Method not found!" + clazz.getName() + "." + methodName, e); } return method; } /** * methodName ?? * @param clazz * @param methodName * @param argCount * @return * @throws NoSuchMethodException */ protected Method getMethodFromClass(Class<?> clazz, String methodName, int argCount) throws NoSuchMethodException { Method[] methods = clazz.getMethods(); for (Method method0 : methods) { String methodName0 = method0.getName(); if (methodName0.equals(methodName) && method0.getParameterCount() == argCount) { return method0; } } return null; } // private static Map<String,Class<?>> primitiveClassMap = new HashMap<String,Class<?>>(); // static { // primitiveClassMap.put(Integer.class.getName(), int.class); // primitiveClassMap.put(Long.class.getName(), long.class); // primitiveClassMap.put(Boolean.class.getName(), boolean.class); // primitiveClassMap.put(Double.class.getName(), double.class); // primitiveClassMap.put(Float.class.getName(), float.class); // primitiveClassMap.put(Byte.class.getName(), byte.class); // primitiveClassMap.put(Short.class.getName(), short.class); // } // // /** // * @param argClass // * @return // */ // private Class<?> convertActualClass(Class<?> argClass) { // if(argClass.isPrimitive()) { // return primitiveClassMap.get(argClass.getName()); // }else // return argClass; // } protected String fixTopicName(String topicName0) { String topicNameStr = topicName0; return topicNameStr; } }