首页 文章 精选 留言 我的

精选列表

搜索[spring-boot],共500篇文章
优秀的个人博客,低调大师

spring-boot学习

Controller的使用 注: 通常程序开发后端需要提供的是rest接口,返回一些json格式给前端,尽量不要使用模板的方式,使用模板会在性能上带来很大的损耗. 参数的获取 知识点整理 @Restcontroller和@controller的区别 如果使用@Restcontroller注解,就不能返回jsp,html页面,视图解析器无法解析jsp,html页面 @Controller注解,若返回json等内容到页面,则需要加@Response注解,而且需要页面返回 url映射可以是以集合的形式获取 例:@RequestMapping(value ={"/hello/","/hi"}) 获取一个id值 :@RequestMapping(value ={"/hello/{id}",method=RequestMethod.GET}) @PathVariable("id") 获取操作 导航栏: /hello/12也可以 12/hello @RequestParam("id") 获取操作 导航栏

优秀的个人博客,低调大师

spring-boot整合protobuf

简介:protobuf是Google的语言中立,平台中立,可扩展的机制,用于序列化结构化数据 - 想想XML,但更小,更快,更简单。您可以定义数据的结构化结构,然后使用特殊生成的源代码轻松地将结构化数据写入和读取各种数据流,并使用各种语言。1.在项目中导入依赖 <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.8.0</version> </dependency> 2.创建ReturnVO. proto文件 syntax = "proto3";

优秀的个人博客,低调大师

学习 spring-boot (一)

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。 spring Boot特点 1. 创建独立的Spring应用程序 2. 嵌入的Tomcat,无需部署WAR文件 3. 简化Maven配置 4. 自动配置Spring 。。。。。。 maven项目创建 1、访问http://start.spring.io/ 2、选择构建工具Maven Project、Spring Boot版本1.3.6以及一些工程基本信息,点击“Switch to the full version.”java版本选择1.7,可参考下图所示: 3、点击Generate Project下载项目压缩包 4、解压后,使用eclipse,Import -> Existing Maven Projects -> Next ->选择解压后的文件夹-> Finsh,OK done! 项目结构介绍 如上图所示,Spring Boot的基础结构共三个文件: src/main/java 程序开发以及主程序入口 src/main/resources 配置文件 src/test/java 测试程序 另外,spingboot建议的目录结果如下:root package结构:com.example.myproject com +- example +- myproject +- Application.java | +- domain | +- Customer.java | +- CustomerRepository.java | +- service | +- CustomerService.java | +- controller | +- CustomerController.java | 1、Application.java 建议放到根目录下面,主要用于做一些框架配置 2、domain目录主要用于实体(Entity)与数据访问层(Repository) 3、service 层主要是业务类代码 4、controller 负责页面访问控制 采用默认配置可以省去很多配置,当然也可以根据自己的喜欢来进行更改最后,启动Application main方法,至此一个java项目搭建好了! 引入web模块 1、pom.xml中添加支持web的模块: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> pom.xml文件中默认有两个模块: spring-boot-starter:核心模块,包括自动配置支持、日志和YAML; spring-boot-starter-test:测试模块,包括JUnit、Hamcrest、Mockito。 2、编写controller内容: @RestController public class HelloWorldController { @RequestMapping("/hello") public String index() { return "Hello World"; } } @RestController的意思就是controller里面的方法都以json格式输出,不用再写什么jackjson配置的了! 3、启动主程序,打开浏览器访问http://localhost:8080/hello,就可以看到效果了,有木有很简单! 如何做单元测试 打开的src/test/下的测试入口,编写简单的http请求来测试;使用mockmvc进行,利用MockMvcResultHandlers.print()打印出执行结果。 @RunWith(SpringRunner.class) @SpringBootTest public class HelloTests { private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build(); } @Test public void getHello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("Hello World"))); } } 开发环境的调试 热启动在正常开发项目中已经很常见了吧,虽然平时开发web项目过程中,改动项目启重启总是报错;但springBoot对调试支持很好,修改之后可以实时生效,需要添加以下的配置: <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> </configuration> </plugin> </plugins> </build> 该模块在完整的打包环境下运行的时候会被禁用。如果你使用java -jar启动应用或者用一个特定的classloader启动,它会认为这是一个“生产环境”。 总结 使用spring boot可以非常方便、快速搭建项目,使我们不用关心框架之间的兼容性,适用版本等各种问题,我们想使用任何东西,仅仅添加一个配置就可以,所以使用sping boot非常适合构建微服务。 学习文章来自 : springboot(一)入门篇 一边学习一边记录。看了就忘了,就还是自己敲敲代码,记录学习的过程。

优秀的个人博客,低调大师

spring-boot整合redis和lettuce

1.在项目pom中引人 <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <!--redis数据库--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 在application.properties配置 #redis数据库配置 #连接池最大连接数(使用负值表示没有限制) spring.redis.lettuce.pool.max-active=-1 #连接池中的最大空闲连接 spring.redis.lettuce.pool.max-idle=100 #连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.lettuce.pool.max-wait=-1ms #连接池中的最小空闲连接 spring.redis.lettuce.pool.min-idle=0 #redis数据库链接配置 spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password= spring.redis.database=0 3.使用StringRedisTemplate操作redis @Service public class RedisService { @Autowired private StringRedisTemplate stringRedisTemplate; /** * 执行set操作 * * @param key * @return */ public void set(final String key, final String value) { stringRedisTemplate.opsForValue().set(key, value); } /** * 执行get操作 * @param key * @return */ public String get(final String key) { return stringRedisTemplate.opsForValue().get(key); } /** * 执行delete操作 * * @param key * @return */ public boolean del(final String key) { return stringRedisTemplate.delete(key); } /** * 执行set操作并且设置生存时间,单位为:秒 * * @param key * @param value //TimeUnit.SECONDS 秒 * //TimeUnit.MINUTES 分 * @return */ public void set(final String key, final String value, final Integer seconds) { stringRedisTemplate.opsForValue().set(key, value, seconds, TimeUnit.SECONDS); } /** * 执行hset操作 * * @param key * @param * @return */ public void hset(final String key, final String mapkey, final String mapvalue) { stringRedisTemplate.opsForHash().put(key, mapkey, mapvalue); } /** * 执行hgetAll操作 * * @param key * @param * @return */ public Map<String, String> hgetAll(final String key) { return (Map)stringRedisTemplate.opsForHash().entries(key); } /** * 执行hdel操作 * * @param key * @param * @return */ public long hdel(final String key, final String[] strings) { return stringRedisTemplate.opsForHash().delete(key, strings); } /** * 执行hkeys操作 * * @param * @param key * @return */ public Set<String> hkeys(final String key) { return (Set) stringRedisTemplate.opsForHash().keys(key); } /** * 执行hvalues操作 * * @param * @param key * @return */ public List<String> hvalues(final String key) { return (List) stringRedisTemplate.opsForHash().values(key); } /** * 执行hget操作 * * @param * @param key * @return */ public String hget(final String key, final String mapkey) { return (String)stringRedisTemplate.opsForHash().get(key, mapkey); } /** * 执行hmset操作 * * @param * @param key * @return */ public void hmset(final String key, final Map<String, String> mapvalue) { stringRedisTemplate.opsForHash().putAll(key, mapvalue); } /** * 执行lpush操作 * @param * @param key * @return */ public long lpush(final String key,final String value) { return stringRedisTemplate.opsForList().leftPush(key,value); } /** * 执行lpop操作 * @param * @param key * @return */ public String lpop(final String key) { return stringRedisTemplate.opsForList().leftPop(key); } /** * 执行rpop操作 * @param * @param key * @return */ public String rpop(final String key) { return stringRedisTemplate.opsForList().rightPop(key); } /** * 执行list操作 * 在列表中的尾部添加一个个值,返回列表的长度 * * @param key * @return */ public Long rpush(final String key, final String value) { return stringRedisTemplate.opsForList().rightPush(key,value); } /** * 执行list操作 * 在列表中的尾部添加多个值,返回列表的长度 * * @param key * @return */ public Long rpush(final String key, final String[] value) { return stringRedisTemplate.opsForList().rightPushAll(key,value); } /** * 执行list操作 * 获取List列表 * * @param key * @return */ public List<String> lrange(final String key, final long start, final long end) { return stringRedisTemplate.opsForList().range(key,start,end); } /** * 执行list操作 * 通过索引获取列表中的元素 * * @param key * @return */ public String lindex(final String key, final long index) { return stringRedisTemplate.opsForList().index(key,index); } /** * 执行list操作 * 获取列表长度,key为空时返回0 * * @param key * @return */ public Long llen(final String key) { return stringRedisTemplate.opsForList().size(key); } public boolean expire(final String key, final Integer seconds) { return stringRedisTemplate.expire(key,seconds,TimeUnit.SECONDS); } } 4.如果对lettuce有更好的使用方式,请评论区沟通。

优秀的个人博客,低调大师

spring-boot项目整合Disruptor的初步使用

1.在项目的pom文件中配置 <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>r09</version> </dependency> 2.创建BaseQueueHelper /** * lmax.disruptor 高效队列处理模板. 支持初始队列,即在init()前进行发布。 * * 调用init()时才真正启动线程开始处理 系统退出自动清理资源. */ public abstract class BaseQueueHelper<D, E extends ValueWrapper<D>, H extends WorkHandler<E>> { /** * 记录所有的队列,系统退出时统一清理资源 */ private static List<BaseQueueHelper> queueHelperList = new ArrayList<BaseQueueHelper>(); /** * Disruptor 对象 */ private Disruptor<E> disruptor; /** * RingBuffer */ private RingBuffer<E> ringBuffer; /** * initQueue */ private List<D> initQueue = new ArrayList<D>(); /** * 队列大小 * * @return 队列长度,必须是2的幂 */ protected abstract int getQueueSize(); /** * 事件工厂 * * @return EventFactory */ protected abstract EventFactory<E> eventFactory(); /** * 事件消费者 * * @return WorkHandler[] */ protected abstract WorkHandler[] getHandler(); /** * 初始化 */ public void init() { ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("DisruptorThreadPool").build(); disruptor = new Disruptor<E>(eventFactory(), getQueueSize(), namedThreadFactory, ProducerType.SINGLE, getStrategy()); disruptor.setDefaultExceptionHandler(new MyHandlerException()); disruptor.handleEventsWithWorkerPool(getHandler()); ringBuffer = disruptor.start(); //初始化数据发布 for (D data : initQueue) { ringBuffer.publishEvent(new EventTranslatorOneArg<E, D>() { @Override public void translateTo(E event, long sequence, D data) { event.setValue(data); } }, data); } //加入资源清理钩子 synchronized (queueHelperList) { if (queueHelperList.isEmpty()) { Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { for (BaseQueueHelper baseQueueHelper : queueHelperList) { baseQueueHelper.shutdown(); } } }); } queueHelperList.add(this); } } /** * 如果要改变线程执行优先级,override此策略. YieldingWaitStrategy会提高响应并在闲时占用70%以上CPU, * 慎用SleepingWaitStrategy会降低响应更减少CPU占用,用于日志等场景. * * @return WaitStrategy */ protected abstract WaitStrategy getStrategy(); /** * 插入队列消息,支持在对象init前插入队列,则在队列建立时立即发布到队列处理. */ public synchronized void publishEvent(D data) { if (ringBuffer == null) { initQueue.add(data); return; } ringBuffer.publishEvent(new EventTranslatorOneArg<E, D>() { @Override public void translateTo(E event, long sequence, D data) { event.setValue(data); } }, data); } /** * 关闭队列 */ public void shutdown() { disruptor.shutdown(); } } 3.创建MyHandlerException public class MyHandlerException implements ExceptionHandler { private Logger logger = LoggerFactory.getLogger(MyHandlerException.class); /* * (non-Javadoc) 运行过程中发生时的异常 * * @see * com.lmax.disruptor.ExceptionHandler#handleEventException(java.lang.Throwable * , long, java.lang.Object) */ @Override public void handleEventException(Throwable ex, long sequence, Object event) { ex.printStackTrace(); logger.error("process data error sequence ==[{}] event==[{}] ,ex ==[{}]", sequence, event.toString(), ex.getMessage()); } /* * (non-Javadoc) 启动时的异常 * * @see * com.lmax.disruptor.ExceptionHandler#handleOnStartException(java.lang. * Throwable) */ @Override public void handleOnStartException(Throwable ex) { logger.error("start disruptor error ==[{}]!", ex.getMessage()); } /* * (non-Javadoc) 关闭时的异常 * * @see * com.lmax.disruptor.ExceptionHandler#handleOnShutdownException(java.lang * .Throwable) */ @Override public void handleOnShutdownException(Throwable ex) { logger.error("shutdown disruptor error ==[{}]!", ex.getMessage()); } } 4.创建ValueWrapper public abstract class ValueWrapper<T> { private T value; public ValueWrapper() {} public ValueWrapper(T value) { this.value = value; } public T getValue() { return value; } public void setValue(T value) { this.value = value; } } 5.创建EventFactory public class EventFactory implements com.lmax.disruptor.EventFactory<SeriesDataEvent> { @Override public SeriesDataEvent newInstance() { return new SeriesDataEvent(); } } 创建DisruptorConfig @Configuration @ComponentScan(value = {"com.demo.disruptor"}) public class DisruptorConfig { /** * smsParamEventHandler1 * * @return SeriesDataEventHandler */ @Bean public SeriesDataEventHandler smsParamEventHandler1() { return new SeriesDataEventHandler(); } /** * smsParamEventHandler2 * * @return SeriesDataEventHandler */ @Bean public SeriesDataEventHandler smsParamEventHandler2() { return new SeriesDataEventHandler(); } /** * smsParamEventHandler3 * * @return SeriesDataEventHandler */ @Bean public SeriesDataEventHandler smsParamEventHandler3() { return new SeriesDataEventHandler(); } /** * smsParamEventHandler4 * * @return SeriesDataEventHandler */ @Bean public SeriesDataEventHandler smsParamEventHandler4() { return new SeriesDataEventHandler(); } /** * smsParamEventHandler5 * * @return SeriesDataEventHandler */ @Bean public SeriesDataEventHandler smsParamEventHandler5() { return new SeriesDataEventHandler(); } /** * smsParamEventHandler5 * * @return SeriesDataEventHandler */ @Bean public SeriesDataEventHandler smsParamEventHandler6() { return new SeriesDataEventHandler(); } } 7.创建SeriesData public class SeriesData { private String deviceInfoStr; public SeriesData() { } public SeriesData(String deviceInfoStr) { this.deviceInfoStr = deviceInfoStr; } public String getDeviceInfoStr() { return deviceInfoStr; } public void setDeviceInfoStr(String deviceInfoStr) { this.deviceInfoStr = deviceInfoStr; } @Override public String toString() { return "SeriesData{" + "deviceInfoStr='" + deviceInfoStr + '\'' + '}'; } } 8.创建SeriesDataEvent public class SeriesDataEvent extends ValueWrapper<SeriesData> { } 9.创建SeriesDataEventQueueHelper @Component public class SeriesDataEventQueueHelper extends BaseQueueHelper<SeriesData, SeriesDataEvent, SeriesDataEventHandler> implements InitializingBean { private static final int QUEUE_SIZE = 1024; @Autowired private List<SeriesDataEventHandler> seriesDataEventHandler; @Override protected int getQueueSize() { return QUEUE_SIZE; } @Override protected com.lmax.disruptor.EventFactory eventFactory() { return new EventFactory(); } @Override protected WorkHandler[] getHandler() { int size = seriesDataEventHandler.size(); SeriesDataEventHandler[] paramEventHandlers = (SeriesDataEventHandler[]) seriesDataEventHandler.toArray(new SeriesDataEventHandler[size]); return paramEventHandlers; } @Override protected WaitStrategy getStrategy() { return new BlockingWaitStrategy(); //return new YieldingWaitStrategy(); } @Override public void afterPropertiesSet() throws Exception { this.init(); } } 10.创建SeriesDataEventHandler public class SeriesDataEventHandler implements WorkHandler<SeriesDataEvent> { private Logger logger = LoggerFactory.getLogger(SeriesDataEventHandler.class); @Autowired private SocketService socketService; @Override public void onEvent(SeriesDataEvent event) { if (event.getValue() == null || StringUtils.isEmpty(event.getValue().getDeviceInfoStr())) { logger.warn("receiver series data is empty!"); } logger.error("hello word!"); } } 11.使用操作 @Autowired private SeriesDataEventQueueHelper seriesDataEventQueueHelper; @Test public void demo(){ seriesDataEventQueueHelper.publishEvent(new SeriesData("hello word")); } 12.后面推出Disruptor的各种操作

优秀的个人博客,低调大师

spring-boot项目启动卡住问题排查记录

问题背景 一个spring boot开发的项目,spring boot版本是1.5.7,携带的spring版本是4.1.3。开发反馈,突然在本地启动不起来了,表象特征就是在本地IDEA上运行时,进程卡住也不退出,应用启动时加载相关组件的日志也不输出。症状如下图: 问题分析 因为没有有用的日志信息,所以不能从日志这个层面上排查问题。但是像这种没有输出日志的话,一般情况下,肯定是程序内部启动流程卡在什么地方了,只能通过打印下当前线程堆栈信息了解下。一般情况下,在服务器环境,我们会使用java工具包中的jstack 工具来查看:如jstack pid(应用java进程)。 但是,在IDEA本地开发的话,IDEA内置了一个工具,可以直接查看当前应用的线程上线文信息,如: 注意下面那个箭头指向的像照相机一样的图标,故图思意,就是打印当前线程快照的的意思。点击后,就出现了右边那些线程上下文信息了,可以看到有很多的线程,我们主要关注下main线程,线程状态确实是waiting的,接着点击箭头所指向的main线程,可以看到如下内容: "main@1" prio=5 tid=0x1 nid=NA waiting java.lang.Thread.State: WAITING at sun.misc.Unsafe.park(Unsafe.java:-1) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836) at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304) at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231) at org.springframework.boot.autoconfigure.BackgroundPreinitializer.onApplicationEvent(BackgroundPreinitializer.java:63) at org.springframework.boot.autoconfigure.BackgroundPreinitializer.onApplicationEvent(BackgroundPreinitializer.java:45) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:158) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127) at org.springframework.boot.context.event.EventPublishingRunListener.finished(EventPublishingRunListener.java:115) at org.springframework.boot.SpringApplicationRunListeners.callFinishedListener(SpringApplicationRunListeners.java:79) at org.springframework.boot.SpringApplicationRunListeners.finished(SpringApplicationRunListeners.java:72) at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:745) at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:134) - locked <0xea6> (a java.util.concurrent.atomic.AtomicBoolean) at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:175) at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:98) at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:64) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127) at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:74) at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54) at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:325) at org.springframework.boot.SpringApplication.run(SpringApplication.java:296) at cn.keking.project.customerManagement.KekingCustomerManagement.main(KekingCustomerManagement.java:36) 可以看到是通过CountDownLatch.await()阻塞了线程,接着看下面那行,所在代码块如下: private static final CountDownLatch preinitializationComplete = new CountDownLatch(1); @Override public void onApplicationEvent(SpringApplicationEvent event) { if (event instanceof ApplicationEnvironmentPreparedEvent) { if (preinitializationStarted.compareAndSet(false, true)) { performPreinitialization(); } } if (event instanceof ApplicationReadyEvent || event instanceof ApplicationFailedEvent) { try { preinitializationComplete.await(); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); } } } 这是spring boot中的一个安全初始化资源的一个类,代码所示为监听SpringApplicationEvent事件,可以肯定的是,它的逻辑执行到了preinitializationComplete.await();这里,导致了线程阻塞了。正常情况下,spring会触发ApplicationEnvironmentPreparedEvent事件完成资源的初始化,这里先不深究Spring为什么这么做,主要通过程序逻辑看下为什么卡这里了,在preinitializationComplete.await();所在行打个断点,看下event对象里的信息,如下: 原来event是一个Spring上下文初始化失败的异常事件对象,对象里包含了具体的异常信息,如箭头所指,关键异常信息如: NoSuchMethodError:"org.springframework.util.ObjectUtils.unwrapOptional(Ljava/lang/Object;)Ljava/lang/Object;" 假设问题 通过上面的分析,基本定位到Spring boot应用启动卡住这个表象背后的真实原因了,而且也定位到了异常信息。 出现NoSuchMethodError异常,是因为调用方法的时候,找不到方法了。一般出现在两个有关联的jar包,但是版本对不上了,也就是常说的jar版本依赖冲突。查看了下,ObjectUtils是spring-core包里的一个类,当前的4.1.3版本确实没有这个unwrapOptional方法,spring-core-5.x的版本才新增了这个方法。因为之前的依赖是没有问题,为什么现在spring上下文会调用5.x的版本的方法呢? 所以先假设近期有开发在pom.xml里添加了新的的依赖,导致了这个问题。 小心求证 有了找问题的方向就好办了,因为代码都是git管理维护的,所以查看下pom.xml文件近期的提交记录即可,查看后,确实发现了近期对pom.xml有改动,添加了一个依赖: <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.6.RELEASE</version> </dependency> 这里还涉及到一点Maven依赖优先级的问题,在pom.xml里直接这样添加的依赖优先于其他jar中pom.xml依赖的,也就是说,即使spring boot1.5.7自带了Spring-context.4.1.3,但是这样指定后,应用最后依赖的还是5.1.6的版本。具体的Maven依赖关系,可以参考我的博文《关于Maven的使用,这些你都了解了么?》。结合之前的分析,八九不离十了就是因为加了这个依赖导致的问题,spring-context.5.1.6配合spring-core.4.1.3肯定得出问题啊。直接移除这个依赖,然后启动系统一切正常,日志打印了Spring加载上线文的信息。 问题总结 定位这个问题的关键在于要了解java中线程堆栈的知识,在没有足够异常日志情况下通过线程快照排查问题。在定位到问题后,如NoSuchMethodError这样的异常,需要平时的经验积累来假设问题的真实原因,然后在追本溯源验明问题所在根本原因。找问题本质一定要这种循序渐进的思路。举例,出现这种问题,如果你直接去搜索引擎搜:“Spring boot应用启动卡住了”,是搜不出来什么东西的,但是当你发现了是由于jar冲突。去搜索引擎搜索: “NoSuchMethodError:"org.springframework.util.ObjectUtils.unwrapOptional(Ljava/lang/Object;)Ljava/lang/Object;"”。就会有很多的内容,很容易解决问题。 作者简介: 陈凯玲,2016年5月加入凯京科技。现任凯京科技研发中心架构组经理,救火队队长。独立博客KL博客(http://www.kailing.pub)博主。

优秀的个人博客,低调大师

Spring-Boot使用profile来配置不同环境的配置文件

在springboot的开发中,有时候我们会有不同的配置,例如日志打印,数据库连接等,开发,测试,生产每个环境可能配置都不一致,还好,springboot支持通过不同的profile来配置不同环境的配置,下面就大致介绍一下yml配置文件跟properties配置文件怎么使用profile配置不同环境的配置文件... 先介绍一下开发环境: jdk版本是1.8 springboot的版本是1.4.1 开发工具为 intellij idea 我们先来介绍,使用一个yml文件,通过不同的profile来配置属性文件: 1.首先,我们先创建一个名为 application.yml的属性文件,如下: 2.然后打开文件,输入一下内容: #查看springboot开启了哪些配置 debug:false spring: profiles: active:dev --- #开发环境配置 spring: profiles:dev server: port:8080 --- #测试环境配置 spring: profiles:test server: port:8081 --- #生产环境配置 spring: profiles:pro server: port:8082 非常简单的配置,application.yml文件分为四部分,使用一组(---)来作为分隔符,第一部分,为通用配置部分,表示三个环境都通用的属性,spring.profiles.active稍后解释. 后面三段分别为,开发,测试,生产,都用spring.profiles指定了一个值(开发为dev,测试为test,生产为pro),这个值表示该段配置应该用在哪个profile里面, PS:一定要注意!!一定要注意!!一定要注意!!所有属性后面跟的value要跟 ":" 隔开一个空格,否则,配置无效!!!配置无效!!!配置无效!!!我当初就掉进来了,在此告知各位,别跟我一样掉进来!!! 如果,我们是本地启动,在通用配置里面,可以设置调用哪个环境的profile,也就是第一段的spring.profiles.active=XXX; 上面的XXX是每个环境的 spring.profiles对应的value,通过这个,可以控制本地启动调用哪个环境的配置文件,例如: spring: profiles: active: dev 加载的,就是开发环境的属性,如果dev换成test,则会加载测试环境的属性,生产也是如此, PS:如果spring.profiles.active没有指定值,那么只会使用没有指定spring.profiles文件的值,也就是只会加载通用的配置 如果是部署到服务器的话,我们正常打成jar包,发布是时候,采用: --spring.profiles.active=test或者pro 来控制加载哪个环境的配置,完整命令如下: java -jar xxxxx.jar --spring.profiles.active=test 表示加载测试环境的配置 java -jar xxxxx.jar --spring.profiles.active=pro 表示加载生产环境的配置 上面介绍完了,我们本地启动一下,先将spring.profiles.active的值设置为dev,看看日志打印结果: 通过日志分析,可以看到,打印了profiles的值为dev,下面看看打印的端口号 发现,端口号是8080说明加载了dev的配置; 下面我们来试试把active的值换成test,重启看看: active变成了test, 端口变为了8081,说明,加载的是test的配置, 接下来,就是使用多个yml配置文件进行配置属性文件: 如果是使用多个yml来配置属性,我们则可以这么使用,通过与配置文件相同的明明规范,创建application-{profile}.yml文件,将于环境无关的属性,放置到application.yml文件里面,可以通过这种形式来配置多个环境的属性文件,在application.yml文件里面指定spring.profiles.active=profiles的值,来加载不同环境的配置,如果不指定,则默认只使用application.yml属性文件,不会加载其他的profiles的配置 使用properties配置多个环境配置文件 如果使用application.properties进行多个环境的配置,原理跟使用多个yml配置文件一致,也是通过application-{profile}.properties来控制加载哪个环境的配置,将于环境无关的属性,放置到application.properties文件里面,通过spring.profiles.active=profiles的值,加载不同环境的配置,如果不指定,则默认加载application.properties的配置,不会加载带有profile的配置

优秀的个人博客,低调大师

bee-spring-boot V1.9.5.boot2.4.2,整合 Bee 和 Spring-boot

bee-spring-bootV1.9.5.boot2.4.2(立夏版) Bee1.9.5 整合Spring-boot2.4.2 并且提供bee-spring-boot-starter. maven依赖: <dependency> <groupId>org.teasoft</groupId> <artifactId>bee-spring-boot</artifactId> <version>1.9.5.boot2.4.2</version> </dependency> 直接使用相应starter: <parent> <groupId>org.teasoft</groupId> <artifactId>bee-spring-boot-starter</artifactId> <version>1.9.5.boot2.4.2</version> </parent> 相应demo: https://gitee.com/automvc/bee-starter-demo Bee是一个简单,易用,功能强大,开发速度快,编码少的 JAVA ORM 框架。连接,事务都可以由Bee框架负责管理.Bee 简化了与DB交互的编码工作量. Bee简单易用:单表操作、多表关联操作,可以不用写sql,极少语句就可以完成SQL操作;概念简单,10分钟即可入门。 Bee功能强大:复杂查询也支持向对象方式,分页查询性能更高,一级缓存即可支持个性化优化;具有分布式特性。高级要求,还可以方便自定义SQL语句。 Spring Boot是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置, 从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot可以帮助我们进行快速应用开发。 Bee整合Spring Boot,让你瞬间拥有两样快速开发利器! 码云上的项目首页: https://gitee.com/automvc/bee-springboot https://gitee.com/automvc/bee github: https://github.com/automvc/bee 相关框架设计信息也可关注微信公众号:软件设计活跃区 也可以加入Bee的技术QQ群:992650213

优秀的个人博客,低调大师

ORM 框架 Bee V1.9.0-5.1 发布,支持 Spring-boot,无 Javabean 插入

Bee V1.9.0-5.1(劳动节版) 新增功能: SuidRich新增方法:public boolean exist(T entity); //判断记录是否存在 MapSuid,无需Javabean操作数据库在查询、删除功能基础上,再增加插入功能。 调整bee.properties,HoneyConfig配置信息. 整合Spring boot,提供bee-spring-boot-starter. 支持利用Javabean生成表. 修复缺陷:jdk 11下,LoggerFactory在配置log4j2时,报错. Bee是一个Java ORM框架。重点是简单,同时功能还很强大! 一个兼具Hibernate和Mybatis优点的ORM框架,同时又避免了两者的缺陷; 此外还有许多自己的优点,如开发速度快,编写代码少,文件小,具有分布式特性。 Bee 是一个简单,易用,功能强大,开发速度快,编码少的 JAVA ORM 框架。 如果说Mybatis在Hibernate之后不是重复造轮子,那Bee在Hibernate和Mybatis之后也不会是重复造轮子! 工欲善其事必先利其器!——《论语·卫灵公》 磨刀不误砍柴工! Bee连磨刀的时间都帮你省了。

优秀的个人博客,低调大师

spring-boot整合hazelcast实现高频交易撮合引擎缓存部分入门级

简介:官网:https://hazelcast.com/一.可用性Hazelcast的分布式架构为连续群集正常运行时间提供冗余,并始终提供可用数据,以满足最苛刻的应用需求。容量随着需求弹性增长,而不会影响性能或可用性。二.速度Hazelcast In-Memory解决方案可以更快地补充数据库和数量级。时间就是金钱; 为您的新应用提供推动业务发展所需的微秒响应时间。将数据保留保留在数据库中,并利用Hazelcast以数字速度进行数据处理。三.用户体验在数字时代,用户不会等待。无论是复杂的电子商务交易还是机器学习驱动的客户自助服务门户,速度都是一切。Hazelcast客户实际上利用我们的速度在其微小的处理窗口中创造更多时间,以便在更多更深层次的服务中分层,创造卓越的商业价值,同时提供业界最佳的用户体验。四.风险缓解有足够的速度和规模,

优秀的个人博客,低调大师

bee-spring-boot 1.9.8(双11版)正式发布,轻松整合 Bee 和 Spring-boot

bee-spring-bootV1.9.8(双11版) Bee1.9.8 整合Spring-boot1.5.16.RELEASE 并且提供bee-spring-boot-starter. maven依赖: <dependency> <groupId>org.teasoft</groupId> <artifactId>bee-spring-boot</artifactId> <version>1.9.8</version> </dependency> 直接使用相应starter: <parent> <groupId>org.teasoft</groupId> <artifactId>bee-spring-boot-starter</artifactId> <version>1.9.8</version> </parent> 相应demo: https://gitee.com/automvc/bee-starter-demo Bee,互联网新时代的Java ORM框架,更快、更简单、更自动,开发速度快,运行快,更智能!Bee 简化了与DB交互的编码工作量. Bee简单易用:单表操作、多表关联操作,可以不用写sql,极少语句就可以完成SQL操作;概念简单,10分钟即可入门。 Bee功能强大:复杂查询也支持向对象方式,分页查询性能更高,一级缓存即可支持个性化优化;具有分布式特性。高级要求,还可以方便自定义SQL语句。 Spring Boot是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置, 从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot可以帮助我们进行快速应用开发。 Bee整合Spring Boot,让你瞬间拥有两样快速开发利器! 码云上的项目首页: https://gitee.com/automvc/bee-springboot https://gitee.com/automvc/bee github: https://github.com/automvc/bee 下载代码包含有Bee Api: 相关框架设计信息也可关注微信公众号:软件设计活跃区

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册