公司的一個小的公共SDK,須要將每一個項目的方法調用的切面日誌輸出。session
其實該需求很是明確ide
如上圖所示,採用 BeanPostProcessor(該圖未經原做者受權,若有侵犯將當即刪除) https://www.zhihu.com/question/48427693/answer/723146648?utm_source=wechat_session&utm_medium=social&utm_oi=71495346814976post
採用Java反射的方式進行修改。 http://www.javashuo.com/article/p-ofkxaaqw-ks.htmlthis
@Component public class LogAspectBeanPostProcessor implements BeanPostProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(LogAspectBeanPostProcessor.class); @Value("${aspect.log.pointcut:test}") private String pointValue; @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } /** * 功能描述: 採用反射的方式處理該問題 * * @param: * @return: * @auther: kukuxiahuni * @date: 2019-09-18 17:09 * @modify_auther: kukuxiahuni * @modify_time: 2019-09-18 17:09 **/ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { Object object = bean; if (bean instanceof ControllerAspect) { Class beanClass = bean.getClass(); try { /** * 切面 */ Method aroundMethod = beanClass.getDeclaredMethod("methodPoint"); /** * 切點註解 */ Pointcut pointcut = aroundMethod.getAnnotation(Pointcut.class); if (LOGGER.isInfoEnabled()) { LOGGER.info("註解原始值={}", pointcut.value()); } if (Objects.isNull(pointcut)) { return object; } /** * 註解使用中實質爲代理類 */ InvocationHandler invocationHandler = Proxy.getInvocationHandler(pointcut); // 獲取 AnnotationInvocationHandler 的 memberValues 字段 Field declaredField = invocationHandler.getClass().getDeclaredField("memberValues"); declaredField.setAccessible(true); Map<String, Object> valMap = (Map<String, Object>) declaredField.get(invocationHandler); valMap.put("value", this.pointValue); info(LOGGER, () -> { String s = "新值爲:" + pointcut.value(); return s; }); } catch (NoSuchMethodException | NoSuchFieldException | IllegalAccessException e) { LOGGER.error("處理新值失敗", e); } } return object; } /** * 功能描述: TODO * * @param: * @return: * @auther: kukuxiahuni * @date: 2019-09-18 17:44 * @modify_auther: kukuxiahuni * @modify_time: 2019-09-18 17:44 **/ private final void info(Logger logger, Supplier<String> content) { if (logger.isInfoEnabled()) { logger.info(content.get()); } } }