范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

GraalVM实践javaweb项目改造成SpringNative

  Spring Native使用
  代码已贡献在github,iMinusMinus/jaot的子模块javaweb,master分支为传统的ssm框架,切换到spring-native分支即可。
  spring-native项目提供了spring-native和spring-aot两个jar包,由于这些jar可能并未发布到中央仓库,需要加入spring仓库,内容如下:                           org.springframework.experimental             spring-native             ${spring-native.version}                               org.springframework.experimental             spring-aot             ${spring-native.version}             provided                                                  org.springframework.boot                 spring-boot-maven-plugin                 ${spring-boot.version}                                      ${repackage.classifier}                                                                                                             repackage                                                                                                                  org.springframework.experimental                 spring-aot-maven-plugin                 ${spring-native.version}                                      false                     true                     true                                                                                generate                                                      generate                                                                                            test-generate                                                      test-generate                                                                                                                     spring-release             Spring release             https://repo.spring.io/release                              false                                            spring-snapshots             Spring Snapshots             https://repo.spring.io/snapshot                                         spring-release             Spring release             https://repo.spring.io/release                              false                                                      native                              exec                 0.9.10                                                                                 org.junit.platform                     junit-platform-launcher                     test                                                                                                          org.graalvm.buildtools                         native-maven-plugin                         ${native-buildtools.version}                         true                                                                                       test-native                                 test                                                                      test                                                                                                                            build-native                                 package                                                                      build                                                                                                                                                        
  执行编译:mvn -Pnative -DskipTests clean package
  如果使用了logback自身的"%gray"、"%highlight"以及安装DelayingShutdownHook时,都会编译后启动报错。这是因为spring-native默认的LogbackHints只添加了部分logback的类型信息,可以使用spring-boot提供的默认配置,或者自己添加NativeHint。
  报错信息如下:%PARSER_ERROR[gray] %PARSER_ERROR[highlight] %PARSER_ERROR[magenta] %PARSER_ERROR[gray] %PARSER_ERROR[gray] %PARSER_ERROR[cyan] %PARSER_ERROR[gray] Application run failed %PARSER_ERROR[ex]java.lang.IllegalStateException: java.lang.IllegalStateException: Logback configuration error detected: ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to instantiate converter class [ch.qos.logback.core.pattern.color.GrayCompositeConverter] as a composite converter for keyword [gray] ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.core.pattern.color.GrayCompositeConverter ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to create converter for [%gray] keyword ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to instantiate converter class [ch.qos.logback.classic.pattern.color.HighlightingCompositeConverter] as a composite converter for keyword [highlight] ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.classic.pattern.color.HighlightingCompositeConverter ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to create converter for [%highlight] keyword ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to instantiate converter class [ch.qos.logback.core.pattern.color.MagentaCompositeConverter] as a composite converter for keyword [magenta] ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.core.pattern.color.MagentaCompositeConverter ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to create converter for [%magenta] keyword ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to instantiate converter class [ch.qos.logback.core.pattern.color.GrayCompositeConverter] as a composite converter for keyword [gray] ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.core.pattern.color.GrayCompositeConverter ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to create converter for [%gray] keyword ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to instantiate converter class [ch.qos.logback.core.pattern.color.GrayCompositeConverter] as a composite converter for keyword [gray] ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.core.pattern.color.GrayCompositeConverter ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to create converter for [%gray] keyword ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to instantiate converter class [ch.qos.logback.core.pattern.color.CyanCompositeConverter] as a composite converter for keyword [cyan] ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.core.pattern.color.CyanCompositeConverter ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to create converter for [%cyan] keyword ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to instantiate converter class [ch.qos.logback.core.pattern.color.GrayCompositeConverter] as a composite converter for keyword [gray] ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.core.pattern.color.GrayCompositeConverter ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to create converter for [%gray] keyword ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - Failed to instantiate converter class [ch.qos.logback.classic.pattern.ThrowableProxyConverter] for keyword [ex] ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.classic.pattern.ThrowableProxyConverter ERROR in ch.qos.logback.core.pattern.parser.Compiler@61b960ac - [ex] is not a valid conversion word ERROR in ch.qos.logback.core.pattern.parser.Compiler@7ad7aa6c - Failed to instantiate converter class [ch.qos.logback.classic.pattern.ThrowableProxyConverter] for keyword [ex] ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.classic.pattern.ThrowableProxyConverter ERROR in ch.qos.logback.core.pattern.parser.Compiler@7ad7aa6c - [ex] is not a valid conversion word ERROR in ch.qos.logback.core.joran.action.AppenderAction - Could not create an Appender of type [ch.qos.logback.classic.AsyncAppender]. ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.classic.AsyncAppender ERROR in ch.qos.logback.core.joran.spi.Interpreter@24:73 - ActionException in Action for tag [appender] ch.qos.logback.core.joran.spi.ActionException: ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.classic.AsyncAppender ERROR in ch.qos.logback.core.joran.action.ShutdownHookAction - Could not create a shutdown hook of type [ch.qos.logback.core.hook.DelayingShutdownHook]. ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.core.hook.DelayingShutdownHook ERROR in ch.qos.logback.core.joran.spi.Interpreter@49:75 - ActionException in Action for tag [shutdownHook] ch.qos.logback.core.joran.spi.ActionException: ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.core.hook.DelayingShutdownHook at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:328) at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:282) at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:240) at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:216) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131) at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:85) at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:66) at java.util.ArrayList.forEach(ArrayList.java:1511) at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:120) at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:114) at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:65) at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:339) at org.springframework.boot.SpringApplication.run(SpringApplication.java:297) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) at ml.iamwhatiam.baostock.Application.main(Application.java:12)
  可以通过在main类或配置类上添加注解解决,代码如下:@NativeHint(trigger = Level.class, types = {         @TypeHint(types = {                 GrayCompositeConverter.class,                 CyanCompositeConverter.class,                 HighlightingCompositeConverter.class,                 MagentaCompositeConverter.class,                 ThrowableProxyConverter.class         }, access = {}, methods = @MethodHint(name = "")),         @TypeHint(types = {                 AsyncAppender.class,                 DelayingShutdownHook.class         }, access = {TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.PUBLIC_METHODS}), }) @SpringBoootApplication public class Application {      public static void main(String[] args) {           SpringApplication.run(Application.class, args);       } }
  再次编译启动后,仍有报错: [36mo.s.boot.SpringApplication  [0;39m  [1;30m: [0;39m Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name "stockRepositoryImpl": Initialization of bean failed; nested exception is com.oracle.svm.core.jdk.UnsupportedFeatureError: Unsupported method java.lang.Class.isSealed() is reachable: The declaring class of this element has been substituted, but this element is not present in the substitution class at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:628) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) at ml.iamwhatiam.baostock.Application.main(Application.java:38) Caused by: com.oracle.svm.core.jdk.UnsupportedFeatureError: Unsupported method java.lang.Class.isSealed() is reachable: The declaring class of this element has been substituted, but this element is not present in the substitution class at com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:87) at java.lang.Class.isSealed(DynamicHub.java:4563) at java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282) at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:266) at org.springframework.aop.framework.AopProxyUtils.completeProxiedInterfaces(AopProxyUtils.java:146) at org.springframework.aop.framework.JdkDynamicAopProxy.(JdkDynamicAopProxy.java:111) at org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy(DefaultAopProxyFactory.java:55) at org.springframework.aop.framework.ProxyCreatorSupport.createAopProxy(ProxyCreatorSupport.java:105) at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110) at org.springframework.aop.framework.AbstractAdvisingBeanPostProcessor.postProcessAfterInitialization(AbstractAdvisingBeanPostProcessor.java:99) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:455) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1808) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ... 15 common frames omitted
  可以看到是因为触发了动态代理,由于使用的是基于JDK17的GraalVM,触发了bug。
  一般来说JDK动态代理是不存在问题的,CGLIB不被GraalVM原生支持。而熟悉spring框架的朋友都知道,接口才能使用JDK动态代理。根据bean名称我们能找到对应的类,而根据类上的Repository注解,非常熟悉spring-boot的朋友会想起有个PersistenceExceptionTranslationAutoConfiguration,它会自动给有Repository注解的bean生成代理类。
  既然罪魁祸首找到了,那么将Repository注解改成Component注解就好。但是需要注意,改了后,自然也没有SQL发生异常后的自动转换了。
  改好了再编译看下呗:org.springframework.beans.factory.BeanCreationException: Error creating bean with name "baoStockApi": Unexpected exception during bean creation; nested exception is java.lang.ExceptionInInitializerError at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:555) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) at ml.iamwhatiam.baostock.Application.main(Application.java:45) Caused by: java.lang.ExceptionInInitializerError: null at java.lang.Class.ensureInitialized(DynamicHub.java:546) at java.lang.Class.ensureInitialized(DynamicHub.java:546) at java.lang.Class.ensureInitialized(DynamicHub.java:546) at java.lang.Class.ensureInitialized(DynamicHub.java:546) at java.lang.Class.ensureInitialized(DynamicHub.java:546) at java.lang.Class.ensureInitialized(DynamicHub.java:546) at io.netty.util.internal.PlatformDependent$Mpsc.newMpscQueue(PlatformDependent.java:986) at io.netty.util.internal.PlatformDependent.newMpscQueue(PlatformDependent.java:997) at io.netty.channel.nio.NioEventLoop.newTaskQueue0(NioEventLoop.java:282) at io.netty.channel.nio.NioEventLoop.newTaskQueue(NioEventLoop.java:153) at io.netty.channel.nio.NioEventLoop.(NioEventLoop.java:141) at io.netty.channel.nio.NioEventLoopGroup.newChild(NioEventLoopGroup.java:183) at io.netty.channel.nio.NioEventLoopGroup.newChild(NioEventLoopGroup.java:38) at io.netty.util.concurrent.MultithreadEventExecutorGroup.(MultithreadEventExecutorGroup.java:84) at io.netty.util.concurrent.MultithreadEventExecutorGroup.(MultithreadEventExecutorGroup.java:60) at io.netty.channel.MultithreadEventLoopGroup.(MultithreadEventLoopGroup.java:52) at io.netty.channel.nio.NioEventLoopGroup.(NioEventLoopGroup.java:97) at io.netty.channel.nio.NioEventLoopGroup.(NioEventLoopGroup.java:92) at io.netty.channel.nio.NioEventLoopGroup.(NioEventLoopGroup.java:73) at io.netty.channel.nio.NioEventLoopGroup.(NioEventLoopGroup.java:53) at io.netty.channel.nio.NioEventLoopGroup.(NioEventLoopGroup.java:45) at ml.iamwhatiam.baostock.infrastructure.rpc.NettyClient.init(NettyClient.java:86) at ml.iamwhatiam.baostock.infrastructure.rpc.NettyClient.(NettyClient.java:73) at ml.iamwhatiam.baostock.infrastructure.AppConfig.baoStockApi(AppConfig.java:19) at org.springframework.aot.ContextBootstrapInitializer.lambda$initialize$0(ContextBootstrapInitializer.java:219) at org.springframework.aot.beans.factory.BeanDefinitionRegistrar$ThrowableSupplier.get(BeanDefinitionRegistrar.java:317) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1249) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1191) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ... 14 common frames omitted Caused by: java.lang.RuntimeException: java.lang.NoSuchFieldException: producerIndex at io.netty.util.internal.shaded.org.jctools.util.UnsafeAccess.fieldOffset(UnsafeAccess.java:111) at io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueProducerFields.(BaseMpscLinkedArrayQueue.java:55) ... 44 common frames omitted Caused by: java.lang.NoSuchFieldException: producerIndex at java.lang.Class.getDeclaredField(DynamicHub.java:2610) at io.netty.util.internal.shaded.org.jctools.util.UnsafeAccess.fieldOffset(UnsafeAccess.java:107)
  这个看起来也简单,不就是有些使用Unsafe么,反射信息加上:@NativeHint(trigger = NettyClient.class, types = {         @TypeHint(typeNames = "io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueColdProducerFields",                 fields = @FieldHint(name = "producerLimit", allowUnsafeAccess = true)),         @TypeHint(typeNames = "io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueProducerFields",                 fields = @FieldHint(name = "producerIndex", allowUnsafeAccess = true)),         @TypeHint(typeNames = "io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueConsumerFields",                 fields = @FieldHint(name = "consumerIndex", allowUnsafeAccess = true)),         @TypeHint(typeNames = "io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueConsumerIndexField",                 fields = @FieldHint(name = "consumerIndex", allowUnsafeAccess = true)),         @TypeHint(typeNames = "io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerIndexField",                 fields = @FieldHint(name = "producerIndex", allowUnsafeAccess = true)),         @TypeHint(typeNames = "io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerLimitField",                 fields = @FieldHint(name = "producerLimit", allowUnsafeAccess = true)),         @TypeHint(typeNames = {                 "io.netty.channel.DefaultChannelPipeline$HeadContext",                 "io.netty.channel.DefaultChannelPipeline$TailContext",         }, access = {TypeAccess.QUERY_DECLARED_METHODS}),         @TypeHint(types = ChannelHandlerAdapter.class,                 queriedMethods = @MethodHint(name = "exceptionCaught", parameterTypes = {ChannelHandlerContext.class, Throwable.class})),         @TypeHint(types = {                 AbstractByteBufAllocator.class,                 ChannelInboundHandlerAdapter.class,                 ChannelInitializer.class,                 ChannelOutboundHandlerAdapter.class,                 ByteToMessageDecoder.class,                 MessageToByteEncoder.class,                 ReferenceCountUtil.class         }, access = TypeAccess.QUERY_DECLARED_METHODS),         @TypeHint(types = {                 PooledByteBufAllocator.class,         })}, options = {"-Dbaostock.socket.readTimeout"})
  于是接着编译,再启动。可不同的错误再一次袭来:org.springframework.beans.factory.BeanCreationException: Error creating bean with name "sqlSessionFactory": Unexpected exception during bean creation; nested exception is java.lang.NoClassDefFoundError: Could not initialize class org.mybatis.spring.SqlSessionFactoryBean at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:555) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) at ml.iamwhatiam.baostock.Application.main(Application.java:77) Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.mybatis.spring.SqlSessionFactoryBean at org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration.sqlSessionFactory(MybatisAutoConfiguration.java:141) at org.springframework.aot.ContextBootstrapInitializer.lambda$initialize$70(ContextBootstrapInitializer.java:367) at org.springframework.aot.beans.factory.BeanDefinitionRegistrar$ThrowableFunction.apply(BeanDefinitionRegistrar.java:294) at org.springframework.aot.beans.factory.InjectedElementResolver.create(InjectedElementResolver.java:67) at org.springframework.aot.beans.factory.BeanDefinitionRegistrar$BeanInstanceContext.create(BeanDefinitionRegistrar.java:211) at org.springframework.aot.ContextBootstrapInitializer.lambda$initialize$71(ContextBootstrapInitializer.java:367) at org.springframework.aot.beans.factory.BeanDefinitionRegistrar$ThrowableFunction.apply(BeanDefinitionRegistrar.java:294) at org.springframework.aot.beans.factory.BeanDefinitionRegistrar.lambda$instanceSupplier$0(BeanDefinitionRegistrar.java:115) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1249) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1191) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ... 14 common frames omitted
  由于不关注mybatis团队的动态,我先是认为MyBatisAutoConfiguration存在问题,将@Configuration改成spring建议的@Configuration(proxyBeanMethods=false)形式。结果仍是问题频出,只得了解下spring-native的机制,想看下spring-data-jpa是如何处理。Mapper接口加入动态代理信息,Mapper方法的入参和出参加入反射信息,Mapper需要的xml作为资源信息,但还是存在诸多问题。于是到mybatis-spring上看看,发现官方团队已经在支持且有示例,于是添加依赖和仓库(由于还是snapshot版本):                               org.mybatis.spring.native             mybatis-spring-native-extensions             ${mybatis-spring-native.version}                                         sonatype-oss-snapshots             Sonatype OSS Snapshots Repository             https://oss.sonatype.org/content/repositories/snapshots          
  然后添加注解(由于xml不是mybatis-spring-native的默认文件名)@MyBatisResourcesScan(mapperLocationPatterns = "mapper/**/*Mapper.xml")
  但是,编译后错误再度出现:2022-04-04 18:02:27.159 INFO [stock,,] 15128 --- [main] ml.iamwhatiam.baostock.Application : No active profile set, falling back to 1 default profile: "default" 2022-04-04 18:02:33.010 INFO [stock,,] 15128 --- [main] ml.iamwhatiam.baostock.Application : Started Application in 5.885 seconds (JVM running for 5.887) 2022-04-04 18:02:36.307 ERROR [stock,,] 15128 --- [http-nio-8080-exec-1] m.i.b.i.web.WrapResponseBodyAdvice : uncaught exception: Invalid bound statement (not found): ml.iamwhatiam.baostock.infrastructure.dao.IndustryMapper.findAll org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): ml.iamwhatiam.baostock.infrastructure.dao.IndustryMapper.findAll at org.apache.ibatis.binding.MapperMethod$SqlCommand.(MapperMethod.java:235) at org.apache.ibatis.binding.MapperMethod.(MapperMethod.java:53) at org.apache.ibatis.binding.MapperProxy.lambda$cachedInvoker$0(MapperProxy.java:108) at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) at org.apache.ibatis.util.MapUtil.computeIfAbsent(MapUtil.java:35) at org.apache.ibatis.binding.MapperProxy.cachedInvoker(MapperProxy.java:95) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) at jdk.proxy4.$Proxy257.findAll(Unknown Source) at ml.iamwhatiam.baostock.infrastructure.dao.StockRepositoryImpl.load(StockRepositoryImpl.java:30) at ml.iamwhatiam.baostock.domain.PotentialStockServiceImpl.top(PotentialStockServiceImpl.java:16) at ml.iamwhatiam.baostock.infrastructure.web.StockController.topN(StockController.java:53) at java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:833) at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:600) at com.oracle.svm.core.windows.WindowsJavaThreads.osThreadStartRoutine(WindowsJavaThreads.java:138)
  看mapper的xml文件已经在jar包中存在,resourc-config.json也包含了文件。死马当活马医,把xml文件放到mapper接口包下,把MyBatisResourcesScan删除,再度编译。新的问题出现了,崩溃!org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name "stockRepositoryImpl": Unsatisfied dependency expressed through field "stockMapper"; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type "ml.iamwhatiam.baostock.infrastructure.dao.StockMapper" available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired} at org.springframework.aot.beans.factory.InjectedFieldResolver.resolve(InjectedFieldResolver.java:50) at org.springframework.aot.beans.factory.InjectedElementResolver.resolve(InjectedElementResolver.java:35) at org.springframework.aot.beans.factory.InjectedElementResolver.invoke(InjectedElementResolver.java:53) at ml.iamwhatiam.baostock.infrastructure.dao.ContextBootstrapInitializer.lambda$registerStockRepositoryImpl$2(ContextBootstrapInitializer.java:14) at org.springframework.aot.beans.factory.BeanDefinitionRegistrar$ThrowableFunction.apply(BeanDefinitionRegistrar.java:294) at org.springframework.aot.beans.factory.BeanDefinitionRegistrar.lambda$instanceSupplier$0(BeanDefinitionRegistrar.java:115) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1249) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1191) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) at ml.iamwhatiam.baostock.Application.main(Application.java:12)
  查看生成的ContextBootstrapInitializer类,可以发现差异,被@Autowired或@Value注解的字段可以正常被注入,使用@Resource注解的字段,被忽略掉了。
  查看spring-native源代码的InjectionPointsSupplier,可以看到该类只处理了Autowired/Value/Inject注解。找到原因就好办了,把Resource注解改成Autowired就行,或者自己定义BeanRegistrationWriterSupplier,提供自己的InjectionPointsSupplier,同时处理Resource/Autowired/Value/Inject注解。
  曙光已现,再编译启动,正常。执行请求报序列化出了问题org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class ml.iamwhatiam.baostock.infrastructure.rpc.QueryHistoryKDataPlusResponse$Quotation]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class ml.iamwhatiam.baostock.infrastructure.rpc.QueryHistoryKDataPlusResponse$Quotation and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: ml.iamwhatiam.baostock.infrastructure.web.WrapResponseBodyAdvice$Wrapper["data"]->ml.iamwhatiam.baostock.infrastructure.rpc.QueryHistoryKDataPlusResponse["data"]->java.util.ArrayList[0]) at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:462) at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:104) at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:290) at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:183) at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:135) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:833) at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:600) at com.oracle.svm.core.windows.WindowsJavaThreads.osThreadStartRoutine(WindowsJavaThreads.java:138)
  考虑到序列化,之前已经添加过SerializationHint,单测时发现没有注册JavaTimeModule会报错。然而查看HttpMessageConverter时,可以看到Jackson2ObjectMapperBuilder.build会自动注册JavaTimeModule。
  猜测可能是序列化要反射获取getter方法或字段,于是修改序列化配置代码如下:@NativeHint(trigger = ResponseBodyAdvice.class, serializables = {         @SerializationHint(types = {                 Integer.class,                 String.class,                 LocalDate.class,                 LocalDateTime.class,                 BigDecimal.class,                 StockVO.class,                 BaoStockResponse.class,                 QueryHistoryKDataPlusResponse.class,         }, typeNames = { // nested types must be specific using a $ separator                 "ml.iamwhatiam.baostock.infrastructure.web.WrapResponseBodyAdvice$Wrapper",                 "ml.iamwhatiam.baostock.infrastructure.rpc.QueryHistoryKDataPlusResponse$Quotation",                 "ml.iamwhatiam.baostock.infrastructure.rpc.QueryHistoryKDataPlusResponse$Frequency"         })}, types = {         @TypeHint(typeNames = {                 "ml.iamwhatiam.baostock.infrastructure.rpc.QueryHistoryKDataPlusResponse$Quotation",         }, access = {TypeAccess.DECLARED_METHODS, TypeAccess.PUBLIC_METHODS}) })
  ok,终于解决了。
  不过也遗留了一个问题,spring-native本身使用了bytebuddy,那么我们的事务究竟要如何配置使用呢?

理性看待创业式亏损,小康股份(601127。SH)业绩拐点临近4月29日,小康股份公布2021年度及2022Q1业绩报告,作为去年中国汽车市场重要的价值体现者,报告一经发出就引起了市场广泛关注。对于这只新能源汽车华为汽车等众多热门概念交汇的标荣耀加速清仓,超窄边框6纳米芯片66W快充,从2199跌至1289元荣耀手机创立于2013年,当时是华为推出为了对抗小米的子品牌,在大哥华为的支持下,加上自身不错的性价比,荣耀也一度成为国内第一大互联网手机品牌,很多喜欢高性价比手机的花粉,都会选择快递业复苏步伐加快网购商品迟迟不发货已经发货的快件被退回4月份以来,受吉林山西上海等多地疫情影响,快递业发展有所放缓,部分分拨中心和营业网点暂时停运,多地出现不同程度网络中断。从数据上看,影响更直观85后大数据专家扎根湖北让智医助理助力基层看好病看准病科技工作需要日积月累的学习和可持续性的创新。5月3日,科大讯飞集团大数据专家讯飞华中(武汉)有限公司医疗大数据技术总工肖桥仍在研发一线忙碌着,手握7项专利,这名34岁的青年科技工作续航超1000公里值得买的5款新能源汽车近二年在汽车市场,新能源电动车可以说是异军突起成为了众多车友追逐的目标,很多人都梦想买一辆新能源车回去尝尝鲜,可是又担心它的续航问题,买回去只能当一辆买菜的代步车,今天我就是为了这小康股份4月新能源汽车销售8552辆,同比增长187。565月5日,资本邦了解到,A股公司小康股份(601127。SH)发布4月份产销快报。报告期内,公司新能源汽车产量为7738辆,同比增长182。2销售量为8552辆,同比增长187。5汽车免费WiFi的原理是什么?汽车免费WIFI,我不知道您强调的是免费还是强调wifi这个功能。现在很多公交车上都开通了免费wifi功能,和私家车一样,主要是车上配备了具有上网功能的无线上网设备,然后装上上网卡功能机首选降至849元!8000毫安大电池充电1次能用3天的神机来了功能机首选,降至849元!8000毫安大电池,充电1次能用3天的神机来了本文原创,禁止搬运和抄袭,违者必究!导语对于购买手机的时候,除了考虑手上的预算之外,大多数的消费者会下意识考鸿海或将组装苹果汽车,瞄准高端市场,实现全自动驾驶近日,我们从相关渠道获知,苹果汽车开发案正如火如荼进行中,苹果很可能委托组装iPhone的长期合作伙伴鸿海负责汽车生产,而苹果车的发布仍将在2025年或甚至是2024年底,虽然实际宁德时代们的新生意汽车动力电池回收,为环保还是想赚钱?从2013年政策补贴,新能源汽车的生产进入快车道以来,到2020年为止,国内已经累积了20万吨废弃的动力电池。而到2030年的时候,全球动力电池的数量将累计达到1200万吨。这么多新能源汽车我想买哪吒V哪吒V典雅白续航300km400km8W起带回家每公里电费约0。06元N95级空气滤芯宽敞5人座前排双安全气囊倒车雷达倒车影像(动态辅助线)金融礼至高可享5000元金融贴息置换礼享
你是因为什么原因放弃使用华为?用着挺好为什么要放弃?老子用的好好的,没放弃!带假设的问是何意图?有点良心的中国人,都不会轻易放弃华为,他代表了中国高科技企业的精神!为什么要放弃,mate40pro坚持用到华为翻荣耀子品牌曝光!荣耀将代替华为成爸爸,最快一年成为国内第一荣耀手机脱离了华为之后,开始全面开启了市场争夺之路!荣耀手机从发布脱离华为之后的第一部手机荣耀V40开始,频繁地开启了新品发布会,荣耀数字系列的第一部手机荣耀50创造了一分钟破5亿假如你换手机,想换什么品牌的?谢谢题主。答华为!现在用的华为麦芒5,流畅好用。华为不要和我说我是狭隘的爱国,郑强老师说过一句话一个国家的品牌连自己的国人都不买,那这个品牌还怎么成长。二战以后,日本和德国的汽车产网上助听器为什么比专业验配中心便宜那么多?网上的便宜助听器都是不需要调试的模拟机,原本就是便宜的助听器,很多是电子厂生产的,模拟式助听器是线性放大,即对轻中重的声音同等放大,导致小声听不清,大声听的很难受,严重的甚至会损害现在市场上手机品牌太多,到底能入手的手机有哪几种?这篇文章近8000字,属于一篇选择手机的攻略文章,看完以后会改变你对手机的认识,但由于篇幅过长,建议收藏后找时间仔细阅读,我相信可以让你得到一些收获。华为目前比较值得入手的机型不多全球汽车芯片短缺,点燃了中国半导体的熊熊大火芯片大战,美国肯定是玩真的。那么中国应对的办法,唯一就是做出自己的高端芯片,没有第二条路可供选择。置之死地而后生,虽然悲情了一些。但无可否认,在这种绝望的情境下进行技术攻关是最容易没有孩子能拒绝这款耳机,Tribit趣倍专业儿童耳机评测如果说要给家里的小朋友买一款蓝牙耳机的话,那我一定推荐这款Tribit趣倍儿童蓝牙无线耳机,从定位上来看,这是一款专为儿童打造的儿童头戴耳机,先不说别的,耳机造型颜值就让人有佩戴的苹果笔记本数据迁移随着苹果笔记本的普及程度提高,好多人对苹果的OS系统也是越来越喜欢了,今天发现了一个在苹果电脑之间直接数据迁移的方法,真的是很高效,分享给大家,希望对更新换代苹果笔记本的朋友们有所手机病毒是怎么获取手机里个人信息的?与其说手机病毒获取个人信息,倒不如说是流氓软件强迫用户打开各种权限来获取个人信息!就像下载每个app都要访问你的通讯录,或者打开摄像头麦克风权限,访问手机相册!然后上传云端服务器!LG成功测试6G无线信号传输,是不是有点超前了?幸亏这是LG弄的。如果是华为肯定又有一堆们追着喊6G没有用了。LG手机业务都不做了,还弄6G有什么用。6G连标准都没出这是自己喊的另外微波频已经够了(再高真成微波炉了),6G顶多在神经性耳聋戴助听器会有改善吗?感音神经性耳聋主要表现就是小声听不到,大声又太吵。戴上助听器后还是感觉听不太清楚。因为感音神经性多数都是高频损失的比较严重。在戴上助听器后我们不应该着急听清楚。而是要慢慢锻炼,让声