微服务笔记
支持http请求
加上@RestController和@RequestMappint注释即可
@RestController :是@controller和@ResponseBody 的结合,@controller标注为spring的bean, @ResponseBody返回格式设置成json
支持rpc请求
打开开关配置
jlpay.framework.rpc.client.enabled :true
jlpay.framework.rpc.server.enabled :true
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package com.jlpay.commons.rpc.thrift.server.configuration; import com.jlpay.commons.command.CommandService; import com.jlpay.commons.rpc.thrift.server.Dispatcher; import com.jlpay.commons.rpc.thrift.server.HealthListener; import com.jlpay.commons.rpc.thrift.server.RpcAdapterImpl; import com.jlpay.commons.rpc.thrift.server.RpcStopReceiveServiceImpl; import com.jlpay.commons.rpc.thrift.server.ThriftRpcHealth; import com.jlpay.commons.rpc.thrift.server.ThriftRpcService; import com.jlpay.commons.tools.configuration.StatefulUtilsAutoConfiguration; import com.jlpay.commons.tools.log.SensitiveLogService; import java.io.Serializable; import java.util.Map; import org.I0Itec.zkclient.ZkClient; import org.I0Itec.zkclient.serialize.SerializableSerializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.scheduling.annotation.EnableScheduling; @Configuration @EnableScheduling @ConditionalOnProperty( prefix = "jlpay.framework.rpc.server", name = {"enabled"}, havingValue = "true" ) @EnableConfigurationProperties({RpcServerAutoConfiguration.RpcServerProp.class}) @Import({StatefulUtilsAutoConfiguration.class}) public class RpcServerAutoConfiguration { private static final Logger logger = LoggerFactory.getLogger(RpcServerAutoConfiguration.class); private static final int MAX_SESSION_TIMEOUT = 3000; public RpcServerAutoConfiguration() { } @Bean @ConditionalOnMissingBean public RpcServerProperties rpcServerProperties() { return new RpcServerProperties(); } @Bean @ConditionalOnMissingBean public ZkClient zkClient(RpcServerProperties prop) { logger.info("rpc server config: initialize zk client"); SerializableSerializer serializer = new SerializableSerializer(); int sessionTimeout = prop.getZkSessionTimeout(); if (sessionTimeout > 3000) { sessionTimeout = 3000; } ZkClient zkClient = new ZkClient(prop.getZkServers(), sessionTimeout, prop.getZkConnectionTimeout(), serializer); logger.info("rpc server config: initialize zk client successfully"); return zkClient; } @Bean @ConditionalOnMissingBean public Dispatcher dispatcher(RpcServerProperties prop, ObjectProvider<Map<String, CommandService>> commandServiceProvider, SensitiveLogService sensitiveLogService) { return new Dispatcher(prop, (Map)commandServiceProvider.getIfAvailable(), sensitiveLogService); } @Bean @ConditionalOnMissingBean public RpcAdapterImpl rpcAdapterImpl(Dispatcher dispatcher) { RpcAdapterImpl rpcAdapter = new RpcAdapterImpl(); rpcAdapter.setDispatcher(dispatcher); return rpcAdapter; } @Bean( initMethod = "start", destroyMethod = "stop" ) @ConditionalOnMissingBean public ThriftRpcService thriftRpcService(RpcAdapterImpl rpcAdapterImpl, ZkClient zkClient, RpcServerProperties serverProp) { logger.info("BASE(rpc): rpc server enabled"); return new ThriftRpcService(rpcAdapterImpl, zkClient, serverProp); } @Bean @ConditionalOnBean({ThriftRpcService.class}) @ConditionalOnProperty( prefix = "jlpay.framework.rpc.server.health", name = {"enabled"}, havingValue = "true", matchIfMissing = true ) public ThriftRpcHealth thriftRpcHealth(ThriftRpcService thriftRpcService) { return new ThriftRpcHealth(thriftRpcService); } @Bean @ConditionalOnBean({ZkClient.class, RpcServerProperties.class}) @ConditionalOnProperty( prefix = "jlpay.framework.rpc.server.elegant-shutdown", name = {"enabled"}, havingValue = "true" ) public RpcStopReceiveServiceImpl rpcStopReceiveService(ZkClient zkClient, RpcServerProperties prop) { logger.info("BASE(rpc server): elegant shutdown enabled."); return new RpcStopReceiveServiceImpl(zkClient, prop.getNodePath(), prop.getThriftPort()); } @Bean @ConditionalOnBean({ZkClient.class, ThriftRpcService.class, RpcServerProperties.class}) @ConditionalOnProperty( prefix = "jlpay.framework.rpc.server.offline-reconnect", name = {"enabled"}, havingValue = "true" ) public HealthListener offlineReconnect(ZkClient zkClient, ThriftRpcService thriftRpcService, RpcServerProperties prop) { logger.info("BASE(rpc server): offline reconnect enabled."); return new HealthListener(zkClient, prop.getNodePath(), prop.getThriftPort(), thriftRpcService); } public static class EnableEntity implements Serializable { private Boolean enabled; public EnableEntity() { } public Boolean getEnabled() { return this.enabled; } public void setEnabled(Boolean enabled) { this.enabled = enabled; } } @ConfigurationProperties("jlpay.framework.rpc.server") public static class RpcServerProp implements Serializable { private Boolean enabled; private RpcServerAutoConfiguration.EnableEntity health; private RpcServerAutoConfiguration.EnableEntity elegantShutdown; private RpcServerAutoConfiguration.EnableEntity offlineReconnect; public RpcServerProp() { } public Boolean getEnabled() { return this.enabled; } public void setEnabled(Boolean enabled) { this.enabled = enabled; } public RpcServerAutoConfiguration.EnableEntity getHealth() { return this.health; } public void setHealth(RpcServerAutoConfiguration.EnableEntity health) { this.health = health; } public RpcServerAutoConfiguration.EnableEntity getElegantShutdown() { return this.elegantShutdown; } public void setElegantShutdown(RpcServerAutoConfiguration.EnableEntity elegantShutdown) { this.elegantShutdown = elegantShutdown; } public RpcServerAutoConfiguration.EnableEntity getOfflineReconnect() { return this.offlineReconnect; } public void setOfflineReconnect(RpcServerAutoConfiguration.EnableEntity offlineReconnect) { this.offlineReconnect = offlineReconnect; } } }
@Configuration: 定义配置类 替代配置文件,里面定义的bean会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext扫描,用于初始化成bean容器
@EnableScheduling:在配置类上使用,开启计划任务的支持(类上)
@ConditionalOnProperty: 用于控制该配置是否生效
@EnableConfigurationProperties:是配置了@ConfigurationProperties注解的类生效
@Import : 导入类
@Bean:使用注解的方式产生一个spring管理的bean
@ConditionalOnMissingBean:当此bean被注册后,同个类型的bean唯一存在,如果有多个会报错
数据库读写分离
package com.jlpay.agent.merch.config; import com.alibaba.druid.pool.DruidDataSource; import com.jlpay.agent.merch.config.constrant.DataSourceConstants; import com.jlpay.agent.merch.config.security.PasswordResolver; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ResourceLoader; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import tk.mybatis.mapper.autoconfigure.SpringBootVFS; import tk.mybatis.spring.annotation.MapperScan; /** * 写数据源配置 * * @author :heyaolei * @date :2022/8/25 */ @Configuration @MapperScan(basePackages = "com.jlpay.agent.merch.mapper.write", sqlSessionFactoryRef = DataSourceConstants.SQL_SESSION_FACTORY_WRITE) @EnableConfigurationProperties(MybatisConfigProperties.class) public class WriteDataSourceConfig { private final ResourceLoader resourceLoader; private final MybatisConfigProperties mybatisConfigProperties; public WriteDataSourceConfig(ResourceLoader resourceLoader, MybatisConfigProperties mybatisConfigProperties) { this.resourceLoader = resourceLoader; this.mybatisConfigProperties = mybatisConfigProperties; } /** * 写数据源 配置 */ @Bean @ConfigurationProperties("spring.datasource.write") public DataSourceProperties writeDataSourceProperties() { return new DataSourceProperties(); } /** * 写数据源 */ @Bean(initMethod = "init") @ConfigurationProperties("spring.datasource.write.config") public DruidDataSource writeDruidDataSource() { DataSourceProperties dsp = writeDataSourceProperties(); dsp.setPassword(PasswordResolver.decrypt(dsp.getPassword())); return dsp.initializeDataSourceBuilder().type(DruidDataSource.class).build(); } @Bean(name = DataSourceConstants.SQL_SESSION_FACTORY_WRITE) public SqlSessionFactory writeSqlSessionFactory() throws Exception { SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); factory.setDataSource(writeDruidDataSource()); factory.setVfs(SpringBootVFS.class); factory.setConfigLocation(resourceLoader.getResource(mybatisConfigProperties.getConfigLocation())); factory.setTypeAliasesPackage(mybatisConfigProperties.getTypeAliasesPackage()); factory.setMapperLocations(mybatisConfigProperties.resolveMapperLocations()); return factory.getObject(); } @Bean(name = DataSourceConstants.TX_MANAGER_NAME_WRITE) public PlatformTransactionManager readTransactionManager() { return new DataSourceTransactionManager(writeDruidDataSource()); } }
@ConfiguratonProperties:读取配置文件的注解
ResourceLoader:资源定位器,