Projek ini menambah sistem pemantauan untuk memantau panggilan antara muka setiap sistem Pada peringkat awal, ia berdasarkan pakej pergantungan yang biasa dirujuk oleh setiap projek. Aspek AOP ditambahkan untuk memantau panggilan antara muka setiap sistem, tetapi ini mempunyai kelemahan Pertama, laluan antara muka projek yang berbeza, menyebabkan laluan berbilang aspek ditulis untuk aspek AOP. sesetengah sistem tidak perlu dipantau Kerana pakej awam diperkenalkan dan dipantau, ia terlalu mengganggu. Untuk menyelesaikan masalah ini, anda boleh menggunakan atribut boleh pasang springboot.
@Slf4j public class MonitorLogInterceptor extends MidExpandSpringMethodInterceptor<MonitorAspectAdviceProperties> { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { Object result = null; HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); //拿到请求的url String requestURI = request.getRequestURI(); if (StringUtils.isEmpty(requestURI)) { return result; } try { result = methodInvocation.proceed(); } catch (Exception e) { buildRecordData(methodInvocation, result, requestURI, e); throw e; } //参数数组 buildRecordData(methodInvocation, result, requestURI, null); return result;
Kita dapat melihat bahawa ia melaksanakanMidExpandSpringMethodInterceptor8742468051c85b06f0a0af9e3e506b5c
@Slf4j public abstract class MidExpandSpringMethodInterceptor<T> implements MethodInterceptor { @Setter @Getter protected T properties; /** * 主动注册,生成AOP工厂类定义对象 */ protected String getExpression() { return null; } @SuppressWarnings({"unchecked"}) public AbstractBeanDefinition doInitiativeRegister(Properties properties) { String expression = StringUtils.isNotBlank(this.getExpression()) ? this.getExpression() : properties.getProperty("expression"); if (StringUtils.isBlank(expression)) { log.warn("中台SpringAop插件 " + this.getClass().getSimpleName() + " 缺少对应的配置文件 或者 是配置的拦截路径为空 导致初始化跳过"); return null; } BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(AspectJExpressionPointcutAdvisor.class); this.setProperties((T) JsonUtil.toBean(JsonUtil.toJson(properties), getProxyClassT())); definition.addPropertyValue("advice", this); definition.addPropertyValue("expression", expression); return definition.getBeanDefinition(); } /** * 获取代理类上的泛型T * 单泛型 不支持多泛型嵌套 */ private Class<?> getProxyClassT() { Type genericSuperclass = this.getClass().getGenericSuperclass(); ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass; return (Class<?>) parameterizedType.getActualTypeArguments()[0]; } }
Dan akhirnya Ia melaksanakan MethodInterceptor Antara muka ini ialah pemintas kaedah dan digunakan untuk proksi dinamik dalam pengaturcaraan Spring AOP. Melaksanakan antara muka ini boleh meningkatkan kaedah yang perlu dipertingkatkan tidak Menambah sebarang kaedah seperti @Component dan @Service untuk menyuntik kelas ke dalam kacang spring. Dalam direktori fail, tambahkan fail spring.factories dengan kandungan:
com.dst.mid.common.expand.springaop.MidExpandSpringMethodInterceptor=com.dst.mid.monitor.intercept .MonitorLogInterceptor
dilaksanakan dengan kaedahDengan cara ini, ia boleh didaftarkan terus semasa proses permulaan dan diletakkan di dalam bekas spring. Soalan lain ialah, kini kelas pelaksanaan aspek tersedia, di manakah aspeknya?
@Configuration @Slf4j @Import(MidExpandSpringAopAutoStarter.class) public class MidExpandSpringAopAutoStarter implements ImportBeanDefinitionRegistrar { private static final String BEAN_NAME_FORMAT = "%s%sAdvisor"; private static final String OS = "os.name"; private static final String WINDOWS = "WINDOWS"; @SneakyThrows @SuppressWarnings({"rawtypes"}) @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { // 1 获取MidExpandSpringMethodInterceptor类的所有实现集合 List<MidExpandSpringMethodInterceptor> list = SpringFactoriesLoader.loadFactories(MidExpandSpringMethodInterceptor.class, null); if (!CollectionUtils.isEmpty(list)) { String expandPath; Properties properties; BeanDefinition beanDefinition; // 2 遍历类的所有实现集合 for (MidExpandSpringMethodInterceptor item : list) { // 3 获取资源文件名称 资源文件中存储需要加入配置的 expandPath = getExpandPath(item.getClass()); // 4 加载资源文件 properties = PropertiesLoaderUtils.loadAllProperties(expandPath + ".properties"); // 5 赋值beanDefinition为AspectJExpressionPointcutAdvisor if (Objects.nonNull(beanDefinition = item.doInitiativeRegister(properties))) { // 6 向容器中注册类 注意这个beanname是不存在的,但是他赋值beanDefinition为AspectJExpressionPointcutAdvisor是动态代理动态生成代理类所以不会报错 registry.registerBeanDefinition(String.format(BEAN_NAME_FORMAT, expandPath, item.getClass().getSimpleName()), beanDefinition); } } } } /** * 获取资源文件名称 */ private static String getExpandPath(Class<?> clazz) { String[] split = clazz.getProtectionDomain().getCodeSource().getLocation().getPath().split("/"); if (System.getProperty(OS).toUpperCase().contains(WINDOWS)) { return split[split.length - 3]; } else { return String.join("-", Arrays.asList(split[split.length - 1].split("-")).subList(0, 4)); } } }Ini adalah pemprosesan kelas pendaftaran aspek Pertama,
nya, anda boleh meletakkan kelas yang anda ingin daftarkan ke dalam bekas spring pada pelaksanaannya
ImportBeanDefinitionRegistrar
registerBeanDefinitions
1 Dapatkan semua koleksi pelaksanaan kelas MidExpandSpringMethodInterceptor
2 Lintas semua koleksi pelaksanaan kelas
3 Dapatkan nama fail Sumber Fail sumber menyimpan
4 yang perlu ditambahkan pada konfigurasi 4. Muatkan fail sumber
5. proksi yang menjana kelas proksi secara dinamik, jadi tiada ralat akan dilaporkan
Lihat Pada ketika ini, masih terdapat masalah
Ia sebenarnya untuk mendaftarkan kelas ke dalam bekas, tetapi satu langkah lagi ialah ia perlu diimbas oleh bekas Kaedah sebelumnya adalah untuk mengimbas melalui laluan dalam projek, tetapi kami adalah pemalam dan tidak boleh Bergantung pada projek, tetapi mengendalikannya dengan cara anda sendiri kali ini, anda perlu menggunakanMelalui pemprosesan di atas, pemprosesan plug-in pemantauan direalisasikan Kemudian apabila menggunakannya, anda hanya perlu memperkenalkan projek ini kepada projek yang berbeza yang perlu dipantau.
Atas ialah kandungan terperinci Bagaimana untuk membangunkan pemalam Springboot. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!