diff --git a/docs/content/zh-cn/docs/tutorials/module-development/reuse-base-datasource.md b/docs/content/zh-cn/docs/tutorials/module-development/reuse-base-datasource.md index 581248d66..f6d5acabb 100644 --- a/docs/content/zh-cn/docs/tutorials/module-development/reuse-base-datasource.md +++ b/docs/content/zh-cn/docs/tutorials/module-development/reuse-base-datasource.md @@ -7,35 +7,38 @@ weight: 600 强烈建议使用本文档方式,在模块中尽可能**复用基座数据源**,否则模块反复部署就会反复创建、消耗数据源连接,导致模块发布运维会变慢,同时也会额外消耗内存。
## SpringBoot 解法 -在模块的代码中写个 MybatisConfig 类即可,这样事务模板都是复用基座的,只有 Mybatis 的 SqlSessionFactoryBean 需要新创建。
通过`BaseAppUtils.getBean`获取到基座的 Bean 对象,然后注册成模块的 Bean: +在模块的代码中写个 MybatisConfig 类即可,这样事务模板都是复用基座的,只有 Mybatis 的 SqlSessionFactoryBean 需要新创建。
参考 demo:/sofa-serverless/samples/springboot-samples/db/mybatis/biz1 + +通过`SpringBeanFinder.getBaseBean`获取到基座的 Bean 对象,然后注册成模块的 Bean: + ```java @Configuration -@MapperScan(basePackages = "com.alipay.serverless.dal.dao", sqlSessionFactoryRef = "mysqlSqlFactory") +@MapperScan(basePackages = "com.alipay.sofa.biz1.mapper", sqlSessionFactoryRef = "mysqlSqlFactory") @EnableTransactionManagement public class MybatisConfig { - // 注意:不要初始化一个基座的 DataSource,会导致模块被热卸载的时候,基座的数据源被销毁,不符合预期。 - // 但是 transactionManager,transactionTemplate,mysqlSqlFactory 这些资源被销毁没有问题 + //tips:不要初始化一个基座的DataSource,当模块被卸载的是,基座数据源会被销毁,transactionManager,transactionTemplate,mysqlSqlFactory被销毁没有问题 @Bean(name = "transactionManager") public PlatformTransactionManager platformTransactionManager() { - return (PlatformTransactionManager) BaseAppUtils.getBean("transactionManager"); + return (PlatformTransactionManager) getBaseBean("transactionManager"); } @Bean(name = "transactionTemplate") public TransactionTemplate transactionTemplate() { - return (TransactionTemplate) BaseAppUtils.getBean("transactionTemplate"); + return (TransactionTemplate) getBaseBean("transactionTemplate"); } @Bean(name = "mysqlSqlFactory") public SqlSessionFactoryBean mysqlSqlFactory() throws IOException { //数据源不能申明成模块spring上下文中的bean,因为模块卸载时会触发close方法 - ZdalDataSource dataSource = (ZdalDataSource) BaseAppUtils.getBean("dataSource"); + + DataSource dataSource = (DataSource) getBaseBean("dataSource"); SqlSessionFactoryBean mysqlSqlFactory = new SqlSessionFactoryBean(); mysqlSqlFactory.setDataSource(dataSource); mysqlSqlFactory.setMapperLocations(new PathMatchingResourcePatternResolver() - .getResources("classpath:mapper/*.xml")); + .getResources("classpath:mappers/*.xml")); return mysqlSqlFactory; } } diff --git a/docs/content/zh-cn/docs/tutorials/module-development/runtime-service-route.md b/docs/content/zh-cn/docs/tutorials/module-development/runtime-service-route.md new file mode 100644 index 000000000..e69de29bb diff --git a/samples/springboot-samples/db/mybatis/README.md b/samples/springboot-samples/db/mybatis/README.md index 0883ba80a..7b8e40c98 100644 --- a/samples/springboot-samples/db/mybatis/README.md +++ b/samples/springboot-samples/db/mybatis/README.md @@ -116,7 +116,7 @@ biz 包含两个模块,分别为 biz1 和 biz2, 都是普通 springboot,修 注意这里将不同 biz 的web context path 修改成不同的值,以此才能成功在一个 tomcat host 里安装多个 web 应用。 -## 实验步骤 +## 基座、模块各自定义数据源 ### 本地部署 mysql 并启动 @@ -200,6 +200,71 @@ curl http://localhost:8080/biz1mybatis/testmybatis ``` 返回 student 表中的内容,且可以发现使用的数据源已经变为 DruidDataSource +## 模块复用基座数据源 + +### 修改模块配置 + +在上一节「基座、模块各自定义数据源」的基础上 + +1. 移除模块数据源配置,在biz的application.properties文件中注释掉数据源datasource相关配置项 +```properties +#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +#spring.datasource.username=root +#spring.datasource.password=Zfj1995! +#spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false +# +#mybatis.mapper-locations=classpath:mappers/*.xml +# +#spring.datasource.type=com.alibaba.druid.pool.DruidDataSource +#spring.datasource.druid.initial-size=5 +#spring.datasource.druid.min-idle=5 +#spring.datasource.druid.max-active=200 +#spring.datasource.druid.max-wait=60000 +#spring.datasource.druid.time-between-eviction-runs-millis=60000 +#spring.datasource.druid.min-evictable-idle-time-millis=300000 +#spring.datasource.druid.test-while-idle=true +#spring.datasource.druid.test-on-borrow=false +#spring.datasource.druid.test-on-return=false +#spring.datasource.druid.pool-prepared-statements=false +#spring.datasource.druid.filters=stat,wall,slf4j +``` + +2. 添加模块MybatisConfig +```java +@Configuration +@MapperScan(basePackages = "com.alipay.sofa.biz1.mapper", sqlSessionFactoryRef = "mysqlSqlFactory") +@EnableTransactionManagement +public class MybatisConfig { + + //tips:不要初始化一个基座的DataSource,当模块被卸载的是,基座数据源会被销毁,transactionManager,transactionTemplate,mysqlSqlFactory被销毁没有问题 + + @Bean(name = "transactionManager") + public PlatformTransactionManager platformTransactionManager() { + return (PlatformTransactionManager) getBaseBean("transactionManager"); + } + + @Bean(name = "transactionTemplate") + public TransactionTemplate transactionTemplate() { + return (TransactionTemplate) getBaseBean("transactionTemplate"); + } + + @Bean(name = "mysqlSqlFactory") + public SqlSessionFactoryBean mysqlSqlFactory() throws IOException { + //数据源不能申明成模块spring上下文中的bean,因为模块卸载时会触发close方法 + + DataSource dataSource = (DataSource) getBaseBean("dataSource"); + SqlSessionFactoryBean mysqlSqlFactory = new SqlSessionFactoryBean(); + mysqlSqlFactory.setDataSource(dataSource); + mysqlSqlFactory.setMapperLocations(new PathMatchingResourcePatternResolver() + .getResources("classpath:mappers/*.xml")); + return mysqlSqlFactory; + } +} +``` + +同上一节「基座、模块各自定义数据源」启动基座、部署模块、发起验证即可。 + + ## 注意事项 这里主要使用简单应用做验证,如果复杂应用,需要注意模块做好瘦身,基座有的依赖,模块尽可能设置成 provided,尽可能使用基座的依赖。 diff --git a/samples/springboot-samples/db/mybatis/biz1/pom.xml b/samples/springboot-samples/db/mybatis/biz1/pom.xml index 4d6181379..ce833c432 100644 --- a/samples/springboot-samples/db/mybatis/biz1/pom.xml +++ b/samples/springboot-samples/db/mybatis/biz1/pom.xml @@ -54,29 +54,24 @@ test - - - - - - - - - - - + + com.alipay.sofa.serverless + sofa-serverless-app-starter + ${sofa.serverless.runtime.version} + provided + com.alipay.sofa.serverless sofa-serverless-adapter-log4j2 ${sofa.serverless.runtime.version} provided - - - - - - + + com.alipay.sofa + sofa-ark-api + ${sofa.ark.version} + provided + diff --git a/samples/springboot-samples/db/mybatis/biz1/src/main/java/com/alipay/sofa/biz1/Biz1Application.java b/samples/springboot-samples/db/mybatis/biz1/src/main/java/com/alipay/sofa/biz1/Biz1Application.java index 2963847b4..91b1cdbc5 100644 --- a/samples/springboot-samples/db/mybatis/biz1/src/main/java/com/alipay/sofa/biz1/Biz1Application.java +++ b/samples/springboot-samples/db/mybatis/biz1/src/main/java/com/alipay/sofa/biz1/Biz1Application.java @@ -9,7 +9,7 @@ import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication -@MapperScan(basePackages = "com.alipay.sofa.biz1.mapper") +//@MapperScan(basePackages = "com.alipay.sofa.biz1.mapper") public class Biz1Application { private static Logger LOGGER = LoggerFactory.getLogger(Biz1Application.class); diff --git a/samples/springboot-samples/db/mybatis/biz1/src/main/java/com/alipay/sofa/biz1/MybatisConfig.java b/samples/springboot-samples/db/mybatis/biz1/src/main/java/com/alipay/sofa/biz1/MybatisConfig.java new file mode 100644 index 000000000..368ebdf80 --- /dev/null +++ b/samples/springboot-samples/db/mybatis/biz1/src/main/java/com/alipay/sofa/biz1/MybatisConfig.java @@ -0,0 +1,50 @@ +package com.alipay.sofa.biz1; + +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; +import org.springframework.transaction.support.TransactionTemplate; + +import javax.sql.DataSource; +import java.io.IOException; + +import static com.alipay.sofa.serverless.common.api.SpringBeanFinder.getBaseBean; + +/** + * @author: yuanyuan + * @date: 2023/12/5 3:37 下午 + * 模块复用基座 transactionManager、transactionTemplate、以及 dataSource + */ +@Configuration +@MapperScan(basePackages = "com.alipay.sofa.biz1.mapper", sqlSessionFactoryRef = "mysqlSqlFactory") +@EnableTransactionManagement +public class MybatisConfig { + + //tips:不要初始化一个基座的DataSource,当模块被卸载的是,基座数据源会被销毁,transactionManager,transactionTemplate,mysqlSqlFactory被销毁没有问题 + + @Bean(name = "transactionManager") + public PlatformTransactionManager platformTransactionManager() { + return (PlatformTransactionManager) getBaseBean("transactionManager"); + } + + @Bean(name = "transactionTemplate") + public TransactionTemplate transactionTemplate() { + return (TransactionTemplate) getBaseBean("transactionTemplate"); + } + + @Bean(name = "mysqlSqlFactory") + public SqlSessionFactoryBean mysqlSqlFactory() throws IOException { + //数据源不能申明成模块spring上下文中的bean,因为模块卸载时会触发close方法 + + DataSource dataSource = (DataSource) getBaseBean("dataSource"); + SqlSessionFactoryBean mysqlSqlFactory = new SqlSessionFactoryBean(); + mysqlSqlFactory.setDataSource(dataSource); + mysqlSqlFactory.setMapperLocations(new PathMatchingResourcePatternResolver() + .getResources("classpath:mappers/*.xml")); + return mysqlSqlFactory; + } +} diff --git a/samples/springboot-samples/db/mybatis/biz1/src/main/resources/application.properties b/samples/springboot-samples/db/mybatis/biz1/src/main/resources/application.properties index b294ee3d2..c12a2cc1b 100644 --- a/samples/springboot-samples/db/mybatis/biz1/src/main/resources/application.properties +++ b/samples/springboot-samples/db/mybatis/biz1/src/main/resources/application.properties @@ -6,22 +6,22 @@ logging.level.root=INFO logging.level.com.alipay.sofa.arklet=INFO logging.config=classpath:log4j2-spring.xml -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -spring.datasource.username=root -spring.datasource.password=Zfj1995! -spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false - -mybatis.mapper-locations=classpath:mappers/*.xml - -spring.datasource.type=com.alibaba.druid.pool.DruidDataSource -spring.datasource.druid.initial-size=5 -spring.datasource.druid.min-idle=5 -spring.datasource.druid.max-active=200 -spring.datasource.druid.max-wait=60000 -spring.datasource.druid.time-between-eviction-runs-millis=60000 -spring.datasource.druid.min-evictable-idle-time-millis=300000 -spring.datasource.druid.test-while-idle=true -spring.datasource.druid.test-on-borrow=false -spring.datasource.druid.test-on-return=false -spring.datasource.druid.pool-prepared-statements=false -spring.datasource.druid.filters=stat,wall,slf4j \ No newline at end of file +#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +#spring.datasource.username=root +#spring.datasource.password=Zfj1995! +#spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false +# +#mybatis.mapper-locations=classpath:mappers/*.xml +# +#spring.datasource.type=com.alibaba.druid.pool.DruidDataSource +#spring.datasource.druid.initial-size=5 +#spring.datasource.druid.min-idle=5 +#spring.datasource.druid.max-active=200 +#spring.datasource.druid.max-wait=60000 +#spring.datasource.druid.time-between-eviction-runs-millis=60000 +#spring.datasource.druid.min-evictable-idle-time-millis=300000 +#spring.datasource.druid.test-while-idle=true +#spring.datasource.druid.test-on-borrow=false +#spring.datasource.druid.test-on-return=false +#spring.datasource.druid.pool-prepared-statements=false +#spring.datasource.druid.filters=stat,wall,slf4j \ No newline at end of file diff --git a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/log4j2/SOFAServerlessLog4j2SpringContextListener.java b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/log4j2/SOFAServerlessLog4j2SpringContextListener.java index 0308b6850..231b32cf7 100644 --- a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/log4j2/SOFAServerlessLog4j2SpringContextListener.java +++ b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/log4j2/SOFAServerlessLog4j2SpringContextListener.java @@ -37,6 +37,8 @@ /** * 支持将配置转换为 log4j2 context. + * 1. 设置LoggingSystem=SOFAServerlessLog4j2LoggingSystem + * 2. 添加属性到log4j2 ThreadContext * * @author ruoshan * @version $Id: AlipayLog4j2SpringContextListener.java, v 0.1 2018年08月23日 10:32 PM ruoshan Exp $ diff --git a/sofa-serverless-runtime/sofa-serverless-common/src/main/java/com/alipay/sofa/serverless/common/api/SpringBeanFinder.java b/sofa-serverless-runtime/sofa-serverless-common/src/main/java/com/alipay/sofa/serverless/common/api/SpringBeanFinder.java new file mode 100644 index 000000000..0b34ff151 --- /dev/null +++ b/sofa-serverless-runtime/sofa-serverless-common/src/main/java/com/alipay/sofa/serverless/common/api/SpringBeanFinder.java @@ -0,0 +1,45 @@ +/* + * 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 com.alipay.sofa.serverless.common.api; + +import com.alipay.sofa.ark.api.ArkClient; +import com.alipay.sofa.ark.spi.model.Biz; +import com.alipay.sofa.serverless.common.BizRuntimeContext; +import com.alipay.sofa.serverless.common.BizRuntimeContextRegistry; + +/** + * @author: yuanyuan + * @date: 2023/12/8 5:26 下午 + * + * SpringBeanFinder 查找基座bean工具类,无跨classloader支持 + */ +public class SpringBeanFinder { + + public static Object getBaseBean(String name) { + Biz masterBiz = ArkClient.getMasterBiz(); + BizRuntimeContext bizRuntimeContext = BizRuntimeContextRegistry + .getBizRuntimeContext(masterBiz); + return bizRuntimeContext.getRootApplicationContext().getBean(name); + } + + public static T getBaseBean(Class type) { + Biz masterBiz = ArkClient.getMasterBiz(); + BizRuntimeContext bizRuntimeContext = BizRuntimeContextRegistry + .getBizRuntimeContext(masterBiz); + return bizRuntimeContext.getRootApplicationContext().getBean(type); + } +} diff --git a/sofa-serverless-runtime/sofa-serverless-common/src/main/java/com/alipay/sofa/serverless/common/service/ServiceProxyFactory.java b/sofa-serverless-runtime/sofa-serverless-common/src/main/java/com/alipay/sofa/serverless/common/service/ServiceProxyFactory.java index 2ff7375ec..f317390d1 100644 --- a/sofa-serverless-runtime/sofa-serverless-common/src/main/java/com/alipay/sofa/serverless/common/service/ServiceProxyFactory.java +++ b/sofa-serverless-runtime/sofa-serverless-common/src/main/java/com/alipay/sofa/serverless/common/service/ServiceProxyFactory.java @@ -48,38 +48,27 @@ public class ServiceProxyFactory { public static T createServiceProxy(Biz biz, String name, Class serviceType, ClassLoader clientClassLoader) { T service = getService(biz, name); - return (T) doCreateServiceProxy(biz, service, serviceType, clientClassLoader); + return doCreateServiceProxy(biz, service, serviceType, clientClassLoader); } public static T createServiceProxy(Biz biz, Class serviceType, ClassLoader clientClassLoader) { - Class serviceClass; - try { - serviceClass = biz.getBizClassLoader().loadClass(serviceType.getName()); - } catch (ClassNotFoundException e) { - throw new BizRuntimeException(E100005, "Cannot find class " + serviceType.getName() - + " from the biz " + biz.getIdentity()); - } + Class serviceClass = checkBizStateAndGetTargetClass(biz, serviceType); T service = (T) getService(biz, serviceClass); - return (T) doCreateServiceProxy(biz, service, serviceType, clientClassLoader); + return doCreateServiceProxy(biz, service, serviceType, clientClassLoader); } public static Map batchCreateServiceProxy(Biz biz, Class serviceType, ClassLoader clientClassLoader) { - Class serviceClass; - try { - serviceClass = biz.getBizClassLoader().loadClass(serviceType.getName()); - } catch (ClassNotFoundException e) { - throw new BizRuntimeException(E100005, "Cannot find class " + serviceType.getName() - + " from the biz " + biz.getIdentity()); - } + Class serviceClass = checkBizStateAndGetTargetClass(biz, serviceType); Map serviceMap = listService(biz, serviceClass); Map proxyMap = new HashMap<>(); for (String beanName : serviceMap.keySet()) { - proxyMap.put( - beanName, - (T) doCreateServiceProxy(biz, serviceMap.get(beanName), serviceType, - clientClassLoader)); + proxyMap + .put( + beanName, + doCreateServiceProxy(biz, serviceMap.get(beanName), serviceType, + clientClassLoader)); } return proxyMap; } @@ -105,23 +94,6 @@ private static Map listService(Biz biz, Class serviceType) { return new HashMap<>(); } - private static BizRuntimeContext checkBizStateAndGetBizRuntimeContext(Biz biz) { - if (biz == null) { - throw new BizRuntimeException(E100003, "biz is null"); - } - if (biz.getBizState() != BizState.ACTIVATED && biz.getBizState() != BizState.DEACTIVATED) { - throw new BizRuntimeException(E100004, "biz state is not valid"); - } - BizRuntimeContext bizRuntimeContext = BizRuntimeContextRegistry.getBizRuntimeContext(biz); - if (bizRuntimeContext == null) { - throw new BizRuntimeException(E100002, "biz runtime context is null"); - } - if (bizRuntimeContext.getRootApplicationContext() == null) { - throw new BizRuntimeException(E100002, "biz spring context is null"); - } - return bizRuntimeContext; - } - /** * @param biz 目标biz * @param service 目标biz中符合条件的bean @@ -131,7 +103,7 @@ private static BizRuntimeContext checkBizStateAndGetBizRuntimeContext(Biz biz) { */ private static T doCreateServiceProxy(Biz biz, Object service, Class serviceType, ClassLoader clientClassLoader) { if (clientClassLoader == null) { - Class callerClass = ReflectionUtils.getCallerClass(5); + Class callerClass = ReflectionUtils.getCallerClass(6); clientClassLoader = callerClass.getClassLoader(); } @@ -173,4 +145,35 @@ public static Biz determineMostSuitableBiz(String moduleName, String moduleVersi } return biz; } + + private static Class checkBizStateAndGetTargetClass(Biz biz, Class sourceClass) { + checkBizState(biz); + try { + return biz.getBizClassLoader().loadClass(sourceClass.getName()); + } catch (ClassNotFoundException e) { + throw new BizRuntimeException(E100005, "Cannot find class " + sourceClass.getName() + + " from the biz " + biz.getIdentity()); + } + } + + private static BizRuntimeContext checkBizStateAndGetBizRuntimeContext(Biz biz) { + checkBizState(biz); + BizRuntimeContext bizRuntimeContext = BizRuntimeContextRegistry.getBizRuntimeContext(biz); + if (bizRuntimeContext == null) { + throw new BizRuntimeException(E100002, "biz runtime context is null"); + } + if (bizRuntimeContext.getRootApplicationContext() == null) { + throw new BizRuntimeException(E100002, "biz spring context is null"); + } + return bizRuntimeContext; + } + + private static void checkBizState(Biz biz) { + if (biz == null) { + throw new BizRuntimeException(E100003, "biz does not exist"); + } + if (biz.getBizState() != BizState.ACTIVATED && biz.getBizState() != BizState.DEACTIVATED) { + throw new BizRuntimeException(E100004, "biz state is not valid"); + } + } } diff --git a/sofa-serverless-runtime/sofa-serverless-common/src/test/java/com/alipay/sofa/serverless/common/SpringServiceFinderTest.java b/sofa-serverless-runtime/sofa-serverless-common/src/test/java/com/alipay/sofa/serverless/common/SpringServiceAndBeanFinderTest.java similarity index 94% rename from sofa-serverless-runtime/sofa-serverless-common/src/test/java/com/alipay/sofa/serverless/common/SpringServiceFinderTest.java rename to sofa-serverless-runtime/sofa-serverless-common/src/test/java/com/alipay/sofa/serverless/common/SpringServiceAndBeanFinderTest.java index 77f619448..353800694 100644 --- a/sofa-serverless-runtime/sofa-serverless-common/src/test/java/com/alipay/sofa/serverless/common/SpringServiceFinderTest.java +++ b/sofa-serverless-runtime/sofa-serverless-common/src/test/java/com/alipay/sofa/serverless/common/SpringServiceAndBeanFinderTest.java @@ -22,6 +22,7 @@ import com.alipay.sofa.ark.spi.service.biz.BizManagerService; import com.alipay.sofa.serverless.common.api.AutowiredFromBase; import com.alipay.sofa.serverless.common.api.AutowiredFromBiz; +import com.alipay.sofa.serverless.common.api.SpringBeanFinder; import com.alipay.sofa.serverless.common.api.SpringServiceFinder; import com.alipay.sofa.serverless.common.service.ArkAutowiredBeanPostProcessor; import org.junit.Assert; @@ -37,7 +38,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.util.ReflectionUtils; -import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.List; @@ -53,7 +53,7 @@ * @date: 2023/9/26 9:40 下午 */ @RunWith(MockitoJUnitRunner.class) -public class SpringServiceFinderTest { +public class SpringServiceAndBeanFinderTest { @Mock private Biz masterBiz; @@ -120,12 +120,12 @@ public void testSpringServiceFinder() { // test to invoke crossing classloader - URL url = SpringServiceFinderTest.class.getClassLoader().getResource(""); + URL url = SpringServiceAndBeanFinderTest.class.getClassLoader().getResource(""); URLClassLoader loader = new URLClassLoader(new URL[] { url }, null); Object newModuleBean = null; try { Class aClass = loader - .loadClass("com.alipay.sofa.serverless.common.SpringServiceFinderTest$ModuleBean"); + .loadClass("com.alipay.sofa.serverless.common.SpringServiceAndBeanFinderTest$ModuleBean"); newModuleBean = aClass.newInstance(); } catch (Exception e) { System.out.println(e); @@ -172,6 +172,14 @@ public void testArkAutowired() { testBean)); } + @Test + public void testGetBaseBean() { + Object baseBean = SpringBeanFinder.getBaseBean("baseBean"); + BaseBean baseBean1 = SpringBeanFinder.getBaseBean(BaseBean.class); + Assert.assertNotNull(baseBean); + Assert.assertNotNull(baseBean1); + } + public ConfigurableApplicationContext buildApplicationContext(String appName) { Properties properties = new Properties(); properties.setProperty("spring.application.name", appName);