-
解决办法 报错原因:因为 @Mapper 是属于 mybatis,不需要在 spring 配置中设置扫描地址,通过 mapper.xml 里面的 namespace 属性对应相关的 mapper 类,spring 将动态的生成 Bean 后注入到 ServiceImpl 中。 看了很多同学们的在设置改掉 springbean 自动装配的办法,但是仍报错。可以选择在 mapper interface 上面,添加 @Repository 注解: 效果 @Mapper 与 @Repository 的相同点: 两个注解都可在 dao/mapper 层使用(用来标记持久层),生成相应代理对象 bean 注入到 spring 容器中。 @Mapper 与 @Repository 的不同点: @Mapper 是 mybatis 的注解,可以单独使用,也允许存在在多个 mapper 文件,它不需要在 Spring 中配置扫描地址,通过 xml 里面的 namespace 里面的接口地址,生成 Bean 后注入到 Service 层中。 @Repository 是 spring 提供的注解,能够将该类注册成 Bean。被依赖注入,但是使用该注解后,在启动类上要加 @MapperScan 来表名 Mapper 类的位置,否则扫描不到。但在 idea 中,使用 @Repository 可以消除在业务层中注入 mapper 对象时的错误。 ———————————————— 原文作者:lanruo127 转自链接:https://learnku.com/articles/71027 版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请保留以上作者信息和原文链接。
-
1. Nacos 升级到 2021.1 后,本地未启动 Nacos,则无法启动 SpringBoot。 背景 本来是用的 SpringBoot 2.1.0,和 Nacos 版本忘记了。 后来升级 SpringBoot 2.5.4,然后 Spring Cloud 那一些也需要升级,随后升级到了 Nacos 版本 2021.1。 升级完之后,将 bootstrap.yml 的 spring.cloud 那些注释掉,启动还是会报错,Nacos 连接失败。 未升级前只要将 spring.cloud nacos 那些注释掉,顶多启动的时候控制台报些错,但不会导致启动不了。 解决 在 bootstrap.yml 中,不需要将那些注释掉了,只需要加两个 enabled 的参数设置为 false 就可以了。 spring: application: name: keepAccount cloud: nacos: discovery: enabled: false server-addr: 127.0.0.1:8848 config: enabled: false server-addr: 127.0.0.1:8848 file-extension: yml 这样子,在启动就不会报错了。 2. 启动报错:When allowCredentials is true, allowedOrigins cannot contain the special value 之前的 CrossConfig 需要改一下,将 allowedOrigins("*") 改为 allowedOriginPatterns("*")。 @Configuration public class CrossConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // .allowedOrigins("*") .allowedOriginPatterns("*") .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS") .allowCredentials(true) .maxAge(3600) .allowedHeaders("*"); } } 3. SpringCloud 版本升级后 bootstrap.yml 配置不生效 背景 和问题 1 有关联,因为 SpringBoot 升级,SpringCloud 也需要升级,当升级后重启 SpringBoot,发现 bootstrap.yml 中配置的应用端口号没生效,变成了默认的 8080. 问题原因 从 Spring Boot 2.4 版本开始,配置文件加载方式进行了重构。 另外也有配置的默认值变化,原来默认启用 true 现在变更为 false 如下: version:2.4 之前 package org.springframework.cloud.bootstrap; public class BootstrapApplicationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered { public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { ConfigurableEnvironment environment = event.getEnvironment(); if ((Boolean)environment.getProperty("spring.cloud.bootstrap.enabled", Boolean.class, true)) { } } } version:2.4.2 package org.springframework.cloud.util; public abstract class PropertyUtils { public static boolean bootstrapEnabled(Environment environment) { return (Boolean)environment.getProperty("spring.cloud.bootstrap.enabled", Boolean.class, false) || MARKER_CLASS_EXISTS; } } 解决办法 pom 文件中引入如下配置 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency> 指定运行参数 spring.cloud.bootstrap.enabled 值为 true spring: cloud: bootstrap: enabled: true 原文作者:邢闯洋转自链接:https://learnku.com/articles/72031
-
打开 /etc/profile 文件 vim /etc/profile 在文件末尾添加以下内容 export JAVA_HOME=/usr/local/jdk/jdk8 export PATH=${JAVA_HOME}/bin:$PATH 执行下面这条命令source /etc/profile 命令行输入java,看到如下界面,则证明设置成功
-
java 的transient关键字的作用是需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。用法@transient 就是在给某个javabean上需要添加个属性,但是这个属性你又不希望给存到数据库中去,仅仅是做个临时变量,用一下。不修改已经存在数据库的数据的数据结构。那么这个注解就可以一用。只要在你准备添加的临时属性上添加这个注解,然后getter和setter自动完成一下,就可以啦。@Document(collection = "streams") public class Stream implements Serializable,Cloneable { private static final long serialVersionUID = 1L; @Transient private boolean alarmsettingsActive = false; xxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx }12345678上面的是个人理解,下面呢就是详细说说。transient的作用 我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个类实现了Serilizable接口,这个类的所有属性和方法都会自动序列化。 然而在实际开发过程中,我们常常会遇到这样的问题,这个类的有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。 总之,java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。transient使用小结1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。作者:fireflies爱人如己原文:cid:link_2
-
1、配置pom文件 <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.9</version> </dependency> 2、配置模板 3、编码 4、效果 response.reset(); try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { ExcelWriter build = EasyExcel.write(out).withTemplate(classPathResource.getFile()).build(); WriteSheet writeSheet = EasyExcel.writerSheet().build(); //配置使用上一个行的样式 WriteSheet writeSheet1 = EasyExcel.writerSheet().registerWriteHandler(new MyHandler()).build(); FillConfig fillConfig1 = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build(); //有集合需要写,则forceNewRow(true) FillConfig fillConfig2 = FillConfig.builder().forceNewRow(Boolean.TRUE).build(); Map map = JSONObject.parseObject(JSONObject.toJSONString(byId), Map.class); build.fill(map, fillConfig1, writeSheet1); for (int i = 0; i < byId.getSugarCookingProcessEntities().size(); i++) { byId.getSugarCookingProcessEntities().get(i).setId(i + 1L); } List list = JSONObject.parseObject(JSONObject.toJSONString(byId.getSugarCookingProcessEntities()), List.class); build.fill(new FillWrapper("sugarCookingProcessEntities", list), fillConfig2, writeSheet1); build.fill(new FillWrapper("sugarCookingFeedingEntities", JSONObject.parseObject(JSONObject.toJSONString(byId.getSugarCookingFeedingEntities()), List.class)), fillConfig2, writeSheet1); IOUtils.write(out.toByteArray(), response.getOutputStream()); } catch (Exception e) { log.error("导出数据" + byId.getOrderId() + "失败", e); } ———————————————— 原文链接:https://blog.csdn.net/Z_linht/article/details/118698643
-
public class FileUtil { public static InputStream getResourcesFileInputStream(String fileName) { return Thread.currentThread().getContextClassLoader().getResourceAsStream("" + fileName); } public static String getPath() { return FileUtil.class.getResource("/").getPath(); } public static File createNewFile(String pathName) { File file = new File(getPath() + pathName); if (file.exists()) { file.delete(); } else { if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } } return file; } public static File readFile(String pathName) { return new File(getPath() + pathName); } } 我查询并需导出的数据,并且里面的字段和excel需要导出的字段对应 -------------------------------------------------华丽的分割线------------------------------------------------------------- 大神能看到这里,感激不经,废话不多,请过目 这里是报错行: ExcelWriter excelWriter = EasyExcel.write(bos).withTemplate(templateFileName).build(); 1 2 com.alibaba.excel.exception.ExcelGenerateException: Create workbook failure at com.alibaba.excel.context.WriteContextImpl.<init>(WriteContextImpl.java:87) at com.alibaba.excel.write.ExcelBuilderImpl.<init>(ExcelBuilderImpl.java:35) at com.alibaba.excel.ExcelWriter.<init>(ExcelWriter.java:47) at com.alibaba.excel.write.builder.ExcelWriterBuilder.build(ExcelWriterBuilder.java:130) at cn.gaialab.gaiamind.microservice.brp.service.ecxport.impl.PlanVisitDataServiceImpl.exportRoutePlanningStore(PlanVisitDataServiceImpl.java:121) at cn.gaialab.gaiamind.microservice.brp.web.ecxport.ExportCustomerInfoController.exportRoutePlanningStore1(ExportCustomerInfoController.java:41) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) 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:634) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1579) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748) Caused by: org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException: The supplied data appears to be in the OLE2 Format. You are calling the part of POI that deals with OOXML (Office Open XML) Documents. You need to call a different part of POI to process this data (eg HSSF instead of XSSF) at org.apache.poi.openxml4j.opc.internal.ZipHelper.verifyZipHeader(ZipHelper.java:147) at org.apache.poi.openxml4j.opc.internal.ZipHelper.openZipStream(ZipHelper.java:175) at org.apache.poi.openxml4j.opc.ZipPackage.<init>(ZipPackage.java:104) at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:307) at org.apache.poi.ooxml.util.PackageHelper.open(PackageHelper.java:37) at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:303) at com.alibaba.excel.util.WorkBookUtil.createWorkBook(WorkBookUtil.java:32) at com.alibaba.excel.context.WriteContextImpl.<init>(WriteContextImpl.java:85) ... 55 common frames omitted 2020-03-24 15:00:49.261 INFO 11336 --- [tbeatExecutor-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_SERVICE-BRP/${eureka.instance.hostname}:service-brp:7081 - Re-registering apps/SERVICE-BRP 2020-03-24 15:00:49.261 INFO 11336 --- [tbeatExecutor-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_SERVICE-BRP/${eureka.instance.hostname}:service-brp:7081: registering service... 2020-03-24 15:00:49.266 INFO 11336 --- [tbeatExecutor-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_SERVICE-BRP/${eureka.instance.hostname}:service-brp:7081 - registration status: 204 2020-03-24 15:02:23.933 INFO 11336 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration 感言 感谢大家的帮助,问题已经解决,并且重新写了一篇,希望能给看到这的朋友,送上一点绵薄之力。 ———————————————— 原文链接:https://blog.csdn.net/weixin_42153503/article/details/104994360
-
当我们在service方法里面进行方法的自调用时,会发生事务失效的情况,这个时候可以通过AopContext.currentProxy()来获取当前类的代理类。 AopContext.currentProxy()是通过ThreadLocal来实现的。 /** * Class containing static methods used to obtain information about the current AOP invocation. * * <p>The {@code currentProxy()} method is usable if the AOP framework is configured to * expose the current proxy (not the default). It returns the AOP proxy in use. Target objects * or advice can use this to make advised calls, in the same way as {@code getEJBObject()} * can be used in EJBs. They can also use it to find advice configuration. * * <p>Spring's AOP framework does not expose proxies by default, as there is a performance cost * in doing so. * * <p>The functionality in this class might be used by a target object that needed access * to resources on the invocation. However, this approach should not be used when there is * a reasonable alternative, as it makes application code dependent on usage under AOP and * the Spring AOP framework in particular. * * @author Rod Johnson * @author Juergen Hoeller * @since 13.03.2003 */ public abstract class AopContext { /** * ThreadLocal holder for AOP proxy associated with this thread. * Will contain {@code null} unless the "exposeProxy" property on * the controlling proxy configuration has been set to "true". * @see ProxyConfig#setExposeProxy */ private static final ThreadLocal<Object> currentProxy = new NamedThreadLocal<>("Current AOP proxy"); /** * Try to return the current AOP proxy. This method is usable only if the * calling method has been invoked via AOP, and the AOP framework has been set * to expose proxies. Otherwise, this method will throw an IllegalStateException. * @return Object the current AOP proxy (never returns {@code null}) * @throws IllegalStateException if the proxy cannot be found, because the * method was invoked outside an AOP invocation context, or because the * AOP framework has not been configured to expose the proxy */ public static Object currentProxy() throws IllegalStateException { Object proxy = currentProxy.get(); if (proxy == null) { throw new IllegalStateException( "Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available."); } return proxy; } /** * Make the given proxy available via the {@code currentProxy()} method. * <p>Note that the caller should be careful to keep the old value as appropriate. * @param proxy the proxy to expose (or {@code null} to reset it) * @return the old proxy, which may be {@code null} if none was bound * @see #currentProxy() */ @Nullable static Object setCurrentProxy(@Nullable Object proxy) { Object old = currentProxy.get(); if (proxy != null) { currentProxy.set(proxy); } else { currentProxy.remove(); } return old; } } ———————————————— 原文链接:https://blog.csdn.net/weixin_41751625/article/details/117038828
-
常规使用SpringAOP功能,都是对一个Service中的B方法进行切入记录日志,这些时候AOP是能起作用的。但是假如B方法被Service中的A方法调用,在B方法上的切入便会失效,导致无法记录日志。 要弄清楚切入失败的原因,就要先了解切入的原理。为什么能够切入目标对象,原理就是创建了代理类,在代理类中调用目标方法的前后进行切入。比如说目标对象是service,代理对象是$proxy0,这时候切入对B方法的调用就是$proxy0.B(),执行流程就是先执行切面中的逻辑比如记录日志,然后再invoke调用service的B方法,所以可以切入;但是执行A方法$proxy0.A()只能对A方法起作用,A里面再使用this调用B的时候使用的是service的原目标对象s.(),而不是$proxy0.B(),所以对B的切入无效,因为压根就没有用代理对象去调用,自然不能使用代理对象提供的切面增强功能。 解决方案就是把service目标对象的A方法中对B方法的调用(this.B())改成使用代理对象对B的调用,那么怎么获取代理对象呢?AopContext.currentProxy()使用了保存了代理对象因此在A方法中使用【((Service) AopContext.currentProxy()).B()】就能解决切入失效的问题。 另外,如果使用【AopContext.currentProxy()】方法获取当前代理对象需要在类上添加【@EnableAspectJAutoProxy(exposeProxy=true)】注解 exposeProxy:在AopContext中暴露代理对象。指示代理应由 AOP 框架公开为ThreadLocal以通过AopContext类进行检索。 默认关闭,即不保证可访问的AopContext。 ———————————————— 原文链接:https://blog.csdn.net/qq_16159433/article/details/120952972
-
1.查看表是否被锁:(1)直接在mysql命令行执行:show engine innodb status\G。(2)查看造成死锁的sql语句,分析索引情况,然后优化sql。(3)然后show processlist,查看造成死锁占用时间长的sql语句。(4)show status like ‘%lock%。2.查看表被锁状态和结束死锁步骤:(1)查看表被锁状态:show OPEN TABLES where In_use > 0; 这个语句记录当前锁表状态 。(2)查询进程:show processlist查询表被锁进程;查询到相应进程killid。(3)分析锁表的SQL:分析相应SQL,给表加索引,常用字段加索引,表关联字段加索引。(4)查看正在锁的事物:SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS。(5)查看等待锁的事物:SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS。扩展资料MySQL锁定状态查看命令:Checking table:正在检查数据表(这是自动的)。Closing tables:正在将表中修改的数据刷新到磁盘中,同时正在关闭已经用完的表。这是一个很快的操作,如果不是这样的话,就应该确认磁盘空间是否已经满了或者磁盘是否正处于重负中。Connect Out:复制从服务器正在连接主服务器。Copying to tmp table on disk:由于临时结果集大于tmp_table_size,正在将临时表从内存存储转为磁盘存储以此节省内存。Creating tmp table:正在创建临时表以存放部分查询结果。deleting from main table:服务器正在执行多表删除中的第一部分,刚删除第一个表。deleting from reference tables:服务器正在执行多表删除中的第二部分,正在删除其他表的记录。Flushing tables:正在执行FLUSH TABLES,等待其他线程关闭数据表。Killed:发送了一个kill请求给某线程,那么这个线程将会检查kill标志位,同时会放弃下一个kill请求。MySQL会在每次的主循环中检查kill标志位,不过有些情况下该线程可能会过一小段才能死掉。如果该线程程被其他线程锁住了,那么kill请求会在锁释放时马上生效。Locked:被其他查询锁住了。Sending data:正在处理SELECT查询的记录,同时正在把结果发送给客户端。Sorting for group:正在为GROUP BY做排序。Sorting for order:正在为ORDER BY做排序。Opening tables:这个过程应该会很快,除非受到其他因素的干扰。例如,在执ALTER TABLE或LOCK TABLE语句行完以前,数据表无法被其他线程打开。正尝试打开一个表。Removing duplicates:正在执行一个SELECT DISTINCT方式的查询,但是MySQL无法在前一个阶段优化掉那些重复的记录。因此,MySQL需要再次去掉重复的记录,然后再把结果发送给客户端。Reopen table:获得了对一个表的锁,但是必须在表结构修改之后才能获得这个锁。已经释放锁,关闭数据表,正尝试重新打开数据表。Repair by sorting:修复指令正在排序以创建索引。Repair with keycache:修复指令正在利用索引缓存一个一个地创建新索引。它会比Repair by sorting慢些。Searching rows for update:正在讲符合条件的记录找出来以备更新。它必须在UPDATE要修改相关的记录之前就完成了。Sleeping:正在等待客户端发送新请求。System lock:正在等待取得一个外部的系统锁。如果当前没有运行多个mysqld服务器同时请求同一个表,那么可以通过增加--skip-external-locking参数来禁止外部系统锁。Upgrading lock:INSERT DELAYED正在尝试取得一个锁表以插入新记录。Updating:正在搜索匹配的记录,并且修改它们。User Lock:正在等待GET_LOCK()。Waiting for tables:该线程得到通知,数据表结构已经被修改了,需要重新打开数据表以取得新的结构。然后,为了能的重新打开数据表,必须等到所有其他线程关闭这个表。waiting for handler insert:INSERT DELAYED已经处理完了所有待处理的插入操作,正在等待新的请求。原文链接:https://m.php.cn/article/487451.html
-
今天在做公司项目时,有一个发邮件的需求。所以写了一个发送邮件的方法后来发现发邮件很慢,导致接口响应也很慢。于是我便想到要使用异步调用去处理这个方法。于是我把注解@Async 加到了自己service类下的一个发邮件的一个方法,后来发现并没有生效。 调用处代码: 我在以下两个方法上都试过加上@Async注解 可是都并没有生效 发送邮件代码: 我思考了一下可能应该是因为aop代理的缘故,被调用方法 和 调用处的代码都处在同一个类,所以只是相当于本类调用,并没有使用代理类 从而@Async并没有产生效果。 于是我查询了一下资料,证实了我的想法,于是我把@Async 注解放到了工具类 MailService 下 修改了注解的添加位置后,接口调用明显速度加快了,成功! 总结: 失效原因 1.@SpringBootApplication启动类当中没有添加@EnableAsync注解。 2.异步方法使用注解@Async的返回值只能为void或者Future。 3.没有走Spring的代理类。因为@Transactional和@Async注解的实现都是基于Spring的AOP,而AOP的实现是基于动态代理模式实现的。那么注解失效的原因就很明显了,有可能因为调用方法的是对象本身而不是代理对象,因为没有经过Spring容器管理。 解决方法: 这里具体说一下第三种情况的解决方法。 1.注解的方法必须是public方法。 2.方法一定要从另一个类中调用,也就是从类的外部调用,类的内部调用是无效的。 3.如果需要从类的内部调用,需要先获取其代理类。 扩展阅读: https://blog.csdn.net/YoungLee16/article/details/88398045 https://blog.csdn.net/QYHuiiQ/article/details/85014983 ———————————————— 原文链接:https://blog.csdn.net/weixin_37760377/article/details/103627676
-
什么是“异步调用”?“异步调用”对应的是“同步调用”,同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执行;异步调用指程序在顺序执行时,不等待异步调用的语句返回结果就执行后面的程序。同步调用下面通过一个简单示例来直观的理解什么是同步调用:定义Task类,创建三个处理函数分别模拟三个执行任务的操作,操作消耗时间随机取(10秒内)@Component public class Task { public static Random random =new Random(); public void doTaskOne() throws Exception { System.out.println("开始做任务一"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务一,耗时:" + (end - start) + "毫秒"); } public void doTaskTwo() throws Exception { System.out.println("开始做任务二"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务二,耗时:" + (end - start) + "毫秒"); } public void doTaskThree() throws Exception { System.out.println("开始做任务三"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务三,耗时:" + (end - start) + "毫秒"); } }在单元测试用例中,注入Task对象,并在测试用例中执行doTaskOne、doTaskTwo、doTaskThree三个函数。@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public class ApplicationTests { @Autowired private Task task; @Test public void test() throws Exception { task.doTaskOne(); task.doTaskTwo(); task.doTaskThree(); } }执行单元测试,可以看到类似如下输出:开始做任务一 完成任务一,耗时:4256毫秒 开始做任务二 完成任务二,耗时:4957毫秒 开始做任务三 完成任务三,耗时:7173毫秒任务一、任务二、任务三顺序的执行完了,换言之doTaskOne、doTaskTwo、doTaskThree三个函数顺序的执行完成。异步调用上述的同步调用虽然顺利的执行完了三个任务,但是可以看到执行时间比较长,若这三个任务本身之间不存在依赖关系,可以并发执行的话,同步调用在执行效率方面就比较差,可以考虑通过异步调用的方式来并发执行。在Spring Boot中,我们只需要通过使用@Async注解就能简单的将原来的同步函数变为异步函数,Task类改在为如下模式:@Component public class Task { @Async public void doTaskOne() throws Exception { // 同上内容,省略 } @Async public void doTaskTwo() throws Exception { // 同上内容,省略 } @Async public void doTaskThree() throws Exception { // 同上内容,省略 } }为了让@Async注解能够生效,还需要在Spring Boot的主程序中配置@EnableAsync,如下所示:@SpringBootApplication @EnableAsync public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }此时可以反复执行单元测试,您可能会遇到各种不同的结果,比如:没有任何任务相关的输出有部分任务相关的输出乱序的任务相关的输出原因是目前doTaskOne、doTaskTwo、doTaskThree三个函数的时候已经是异步执行了。主程序在异步调用之后,主程序并不会理会这三个函数是否执行完成了,由于没有其他需要执行的内容,所以程序就自动结束了,导致了不完整或是没有输出任务相关内容的情况。注: @Async所修饰的函数不要定义为static类型,这样异步调用不会生效异步回调为了让doTaskOne、doTaskTwo、doTaskThree能正常结束,假设我们需要统计一下三个任务并发执行共耗时多少,这就需要等到上述三个函数都完成调动之后记录时间,并计算结果。那么我们如何判断上述三个异步调用是否已经执行完成呢?我们需要使用Future<T>来返回异步调用的结果,就像如下方式改造doTaskOne函数:@Async public Future<String> doTaskOne() throws Exception { System.out.println("开始做任务一"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务一,耗时:" + (end - start) + "毫秒"); return new AsyncResult<>("任务一完成"); }按照如上方式改造一下其他两个异步函数之后,下面我们改造一下测试用例,让测试在等待完成三个异步调用之后来做一些其他事情。@Test public void test() throws Exception { long start = System.currentTimeMillis(); Future<String> task1 = task.doTaskOne(); Future<String> task2 = task.doTaskTwo(); Future<String> task3 = task.doTaskThree(); while(true) { if(task1.isDone() && task2.isDone() && task3.isDone()) { // 三个任务都调用完成,退出循环等待 break; } Thread.sleep(1000); } long end = System.currentTimeMillis(); System.out.println("任务全部完成,总耗时:" + (end - start) + "毫秒"); }看看我们做了哪些改变:在测试用例一开始记录开始时间在调用三个异步函数的时候,返回Future<String>类型的结果对象在调用完三个异步函数之后,开启一个循环,根据返回的Future<String>对象来判断三个异步函数是否都结束了。若都结束,就结束循环;若没有都结束,就等1秒后再判断。跳出循环之后,根据结束时间 - 开始时间,计算出三个任务并发执行的总耗时。执行一下上述的单元测试,可以看到如下结果:开始做任务一 开始做任务二 开始做任务三 完成任务三,耗时:37毫秒 完成任务二,耗时:3661毫秒 完成任务一,耗时:7149毫秒 任务全部完成,总耗时:8025毫秒可以看到,通过异步调用,让任务一、二、三并发执行,有效的减少了程序的总运行时间。代码示例本文的相关例子可以查看下面仓库中的chapter4-1-2目录:Github:https://github.com/dyc87112/SpringBoot-LearningGitee:https://gitee.com/didispace/SpringBoot-Learning原文链接:https://blog.didispace.com/springbootasync/
-
方法一:同一个类中调用需要先获取代理对象,也就是手动获取对象12345678910111213141516171819@Service@EnableAsyncpublic class DemoService { public void add(){ DemoService bean = SpringUtil.getBean(DemoService.class); System.out.println("开始"); bean.sendToKafka(); System.out.println("结束"); } @Async public void sendToKafka() { try { Thread.sleep(10000); System.out.println("我睡醒了!!!"); } catch (InterruptedException e) { e.printStackTrace(); } }}方法二:不同的类调用,直接注入即可AsyncHandle.java (异步处理类)12345678910111213@Service@EnableAsyncpublic class AsyncHandle { @Async public void sendToKafka() { try { Thread.sleep(10000); System.out.println("我睡醒了!!!"); } catch (InterruptedException e) { e.printStackTrace(); } }}DemoService.java (业务类)1234567891011@Servicepublic class DemoService { @Autowired private AsyncHandle asyncHandle; public void add(){ System.out.println("开始"); asyncHandle.sendToKafka(); System.out.println("结束"); }}总结:1、在需要用到的@Async注解的类上加上@EnableAsync,或者直接加在springboot启动类上2、异步处理方法(也就是加了@Async注解的方法)只能返回的是void或者Future类型3、同一个类中调用异步方法需要先获取代理类,因为@Async注解是基于Spring AOP (面向切面编程)的,而AOP的实现是基于动态代理模式实现的。有可能因为调用方法的是对象本身而不是代理对象,因为没有经过Spring容器。。。。。。这点很重要,也是经常遇到的原文链接:https://www.jb51.net/article/236337.htm
-
本文主要讨论 集合Set 中存储对象的 hashCode 与 equals 方法应遵循的约束关系.新手对Set中contains()方法的疑惑 [java] 普通类会继承Object类的一切方法,但是不会重写Object类的方法 import java.util.HashSet; class Dog{ String color; public Dog(String s){ color = s; } } public class SetAndHashCode { public static void main(String[] args) { HashSet dogSet = new HashSet(); dogSet.add(new Dog('white')); dogSet.add(new Dog('white')); System.out.println('We have ' + dogSet.size() + ' white dogs!'); if(dogSet.contains(new Dog('white'))){ System.out.println('We have a white dog!'); }else{ System.out.println('No white dog!'); } } } 上述代码的输出为: [plain] We have 2 white dogs! No white dog! 程序中添加了两只白色的小狗到集合dogSet中. 且 size()方法显示有2只白色的小狗.但为什么用 contains()方法来判断时却提示没有白色的小狗呢? Set的contains(Object o) 方法详解 Java的API文档指出: 当且仅当 本set包含一个元素 e,并且满足(o==null ? e==null : o.equals(e))条件时,contains()方法才返回true. 因此 contains()方法 必定使用equals方法来检查是否相等. 需要注意的是: set 中是可以包含 null值的(常见的集合类都可以包含null值). 所以如果添加了null,然后判断是否包含null,将会返回true,代码如下所示: [java] HashSet a = new HashSet(); a.add(null); if(a.contains(null)){ System.out.println('true'); } Java的根类Object定义了 public boolean equals(Object obj) 方法.因此所有的对象,包括数组(array,[]),都实现了此方法。 在自定义类里,如果没有明确地重写(override)此方法,那么就会使用Object类的默认实现.即只有两个对象(引用)指向同一块内存地址(即同一个实际对象, x==y为true)时,才会返回true。 如果把Dog类修改为如下代码,能实现我们的目标吗? [java class Dog{ String color; public Dog(String s){ color = s; } //重写equals方法, 最佳实践就是如下这种判断顺序: public boolean equals(Object obj) { if (!(obj instanceof Dog)) return false; if (obj == this) return true; return this.color == ((Dog) obj).color; } } 英文答案是: no. 问题的关键在于 Java中hashCode与equals方法的紧密联系. hashCode() 是Object类定义的另一个基础方法. equals()与hashCode()方法之间的设计实现原则为: 如果两个对象相等(使用equals()方法),那么必须拥有相同的哈希码(使用hashCode()方法). 即使两个对象有相同的哈希值(hash code),他们不一定相等.意思就是: 多个不同的对象,可以返回同一个hash值. hashCode()的默认实现是为不同的对象返回不同的整数.有一个设计原则是,hashCode对于同一个对象,不管内部怎么改变,应该都返回相同的整数值. 在上面的例子中,因为未定义自己的hashCode()实现,因此默认实现对两个对象返回两个不同的整数,这种情况破坏了约定原则。 解决办法 [java] class Dog{ String color; public Dog(String s){ color = s; } //重写equals方法, 最佳实践就是如下这种判断顺序: public boolean equals(Object obj) { if (!(obj instanceof Dog)) return false; if (obj == this) return true; return this.color == ((Dog) obj).color; } public int hashCode(){ return color.length();//简单原则 } } 但是上面的hashCode实现,要求Dog的color是不变的.否则会出现如下的这种困惑: [java] import java.util.HashSet; import java.util.Set; public class TestContains { public static final class Person{ private String name = ''; public Person(String n) { setName(n); } public String getName() { return name; } public void setName(String name) { this.name = (name==null)? '' : name; } @Override public int hashCode() { // 请考虑是否值得这么做,因为此时name是会变的. return name.length(); // 推荐让name不可改变 } @Override public boolean equals(Object obj) { if(!(obj instanceof Person)){ return false; } if(obj == this){ return true; } return this.name.equals(((Person)obj).name); } }; public static void main(String[] args) { Set persons = new HashSet(); // Person person = new Person('tiemao'); persons.add(person); // 修改name, 则依赖hash的集合可能失去作用 person.setName('ren'); // 同一个对象,居然是false,原因是我们重写了hashCode,打破了hashCode不变的基本约定 boolean has = persons.contains(person); int size = persons.size(); System.out.println('has='+has); // has=false. System.out.println('size='+size);// size=1 } } ———————————————— 原文链接:https://blog.csdn.net/weixin_40007548/article/details/114090134
-
一、List列表与Set列表的区别List列表是有序、可以重复、线程不安全的列表,Set是无序、不能重复、线程不安全的列表。但List和Set可以通过方法来转换为线程安全的,加互斥锁。Set set=new HashSet<>();// 转换为线程安全的集合Collections.synchronizedSet(set);List lists=new ArrayList<>();Collections.synchronizedList(lists);二、List与Set的转换1) List转换为setList ids=new ArrayList<>();HashSet set=new HashSet<>(ids);2) Set转换为ListHashSet set=new HashSet<>();List ids=new ArrayList<>(set);此处都可以使用 addAll()方法来替换。需要注意的是: List转换为Set的时候,当有重复数据时,转换为出现数据丢失的情况,因为Set集合不允许有重复数据。————————————————原文链接:https://blog.csdn.net/qq_33036061/article/details/103968822
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签