做外贸用什么社交网站百度seo关键词排名

当前位置: 首页 > news >正文

做外贸用什么社交网站,百度seo关键词排名,需要推广的app在哪里找,运城建设厅官方网站一、Async 注解介绍#xff1a; Async 注解用于声明一个方法是异步的。当在方法上加上这个注解时#xff0c;Spring 将会在一个新的线程中执行该方法#xff0c;而不会阻塞原始线程。这对于需要进行一些异步操作的场景非常有用#xff0c;比如在后台执行一些耗时的任务而不…一、Async 注解介绍 Async 注解用于声明一个方法是异步的。当在方法上加上这个注解时Spring 将会在一个新的线程中执行该方法而不会阻塞原始线程。这对于需要进行一些异步操作的场景非常有用比如在后台执行一些耗时的任务而不影响前台响应。 示例 Service public class MyService {Asyncpublic void asyncMethod() {// 异步执行的代码} }在上面的例子中asyncMethod 方法使用 Async 注解标记表示该方法将在一个独立的线程中执行。 二、Async 底层分析 1、整体思维导图 2、注解底层实现分析 Async的实现大概分为以下几个步骤 // 1、目标代理类 ProxyFactory proxyFactory new ProxyFactory(); proxyFactory.setTarget(DemoImpl bean); // 2、代理接口 proxyFactory.addInterface(DemoService); // 3、设置切点 AsyncAnnotationAdvisor.pointcut Async注解 // 4、环绕通知处理 AsyncAnnotationAdvisor.advice AnnotationAsyncExecutionInterceptor拦截器 // 5、切面 切点通知 proxyFactory.addAdvisor(AsyncAnnotationAdvisor); // 6、生成代理 UserService userService proxyFactory.getProxy(getProxyClassLoader()); 其中设置切点是在AsyncAnnotationAdvisor类里面 环绕通知处理是在AnnotationAsyncExecutionInterceptor这个拦截器去做的我们主要就分析一下这个拦截器相关的代码可以看到直接调用了super(defaultExecutor, exceptionHandler)是在它的父类实现的。 我们看看它的父类 这个类有四个方法invoke()、getExecutorQualifier()、getDefaultExecutor()、getOrder()我们主要关注Invoke()方法和getDefaultExecutor()方法。 Invoke()方法如下 它的作用就是会找出标注了Async注解的方法然后生成一个Callable对象并提交给线程池的一个线程来执行从而实现了该方法的异步执行。 通过AOPUtils.getTargetClass(invocation.getThis()) 获取目标对象的类使用 ClassUtils.getMostSpecificMethod() 方法获取指定目标类和方法通过 BridgeMethodResolver.findBridgedMethod() 方法处理桥接方法确保获取到用户声明的方法。(桥接方法用来解决运行时泛型被擦除问题)determineAsyncExecutor() 方法根据用户声明的方法确定异步执行器。 定义一个 Callable 类型的任务使用 Lambda 表达式创建了一个匿名函数作为任务内容通过 invocation.proceed() 执行目标方法并处理可能的异常情况。 this.doSubmit(task, executor, invocation.getMethod().getReturnType())将任务提交给异步执行器进行处理并返回执行结果。 getDefaultExecutor()方法如下 首先尝试获取 TaskExecutor 实现类的 bean 对象如果能找到且只有一个则返回该对象如果找不到或者找到了多个则会进入 catch 语句块分支获取 beanName 为 taskExecutor 的 bean对象如果获取不到则会创建一个 SimpleAsyncTaskExecutor 线程池对象。 换句话说如果直接使用 Async 注解Spring 就会直接使用 SimpleAsyncTaskExecutor 线程池。那直接使用 SimpleAsyncTaskExecutor 线程池会出现什么问题呢现在我们进入第三个主题。 三、Async 存在的问题或注意事项 1、线程池问题 上面说到如果直接使用 Async 注解Spring 就会直接使用 SimpleAsyncTaskExecutor 线程池。 1让我们看看这个线程池到底是怎么执行的。 可以看到它是直接 new 一个线程然后直接开启线程。 他既没有重用线程也没有设置最大线程数所以在并发量大的时候会产生严重的性能问题所以一般在生产环境特别是 toc 的项目不建议直接使用 Async 注解应该使用自定义线程池搭配 Async 注解一起使用 2那如何配置Async的自定义线程池呢 在Spring中我们可以通过实现 AsyncConfigurer 接口或者直接继承 AsyncConfigurerSupport 类来自定义 Async 异步线程池 线程池可以直接使用 JDK 提供的 ThreadPoolExecutor 或者 Spring 本身也提供的 TaskExecutor 的实现类Spring的实现类有以下五种其中使用最多的就是 ThreadPoolTaskExecutor。 SimpleAsyncTaskExecutor不是真的线程池这个类不重用线程每次调用都会创建一个新的线程。SyncTaskExecutor这个类没有实现异步调用只是一个同步操作。只适用于不需要多线程的地ConcurrentTaskExecutorExecutor的适配类不推荐使用。如果ThreadPoolTaskExecutor不满足要求时才用考虑使用这个类ThreadPoolTaskScheduler可以使用cron表达式ThreadPoolTaskExecutor最常使用推荐。其实质是对java.util.concurrent.ThreadPoolExecutor的包装 接下来我们就以 ThreadPoolTaskExecutor 为例来自定义一个线程池 2、与 Transactional 联用问题 当然使用Async还有一些别的注意事项比如与Transcational联用时它们在同一个方法上同时使用时可能导致异步失效。这是因为 Async 通常会使用一个新的线程而新线程无法继承原始线程的事务上下文。 解决办法是将 Async 注解放在另外的类或者方法上确保异步方法被另外的代理类包装。这样异步方法就能够在独立的线程中执行同时也能够继承事务上下文。 Service public class MyService {Asyncpublic void asyncMethodWithTransaction() {transactionalMethod();}Transactionalpublic void transactionalMethod() {// 事务性操作的代码} } 3、循环依赖问题 现在有两个类ServiceA 和 ServiceB 如下 Service public class ServiceA {private final ServiceB serviceB;Autowiredpublic ServiceA(ServiceB serviceB) {this.serviceB serviceB;}Asyncpublic void asyncMethod() {// 异步方法逻辑} } Service public class ServiceB {private final ServiceA serviceA;Autowiredpublic ServiceB(ServiceA serviceA) {this.serviceA serviceA;} } 其中serviceA、serviceB对象之间相互依赖serviceA和serviceB总有一个会先实例化而serviceA或serviceB里面使用了Async注解会导致循环依赖异常 org.springframework.beans.factory.BeanCurrentlyInCreationException 在springboot中以上报错被捕捉抛出的异常是 The dependencies of some of the beans in the application context form a cycle 原因 我们知道spring三级缓存一定程度上解决了循环依赖问题。A对象在实例化之后属性赋值【opulateBean(beanName, mbd, instanceWrapper)】执行之前将ObjectFactory添加至三级缓存中从而使得在B对象实例化后的属性赋值过程中能从三级缓存拿到ObjectFactory调用getObject()方法拿到A的引用B由此能顺利完成初始化并加入到IOC容器。此时A对象完成属性赋值之后将会执行初始化【initializeBean(beanName, exposedObject, mbd)方法】重点是Async注解的处理正是在这地方完成的其对应的后置处理器AsyncAnnotationBeanPostProcessor在postProcessAfterInitialization方法中将返回代理对象此代理对象与B中持有的A对象引用不同导致了以上报错。 解决办法 在A类上加Lazy保证A对象实例化晚于B对象不使用Async注解通过自定义异步工具类发起异步线程线程池不要让Async的Bean参与循环依赖 Async循环依赖问题参考博客https://cloud.tencent.com/developer/article/1497689 ps以下是我整理的java面试资料感兴趣的可以看看。最后创作不易觉得写得不错的可以点点关注 链接https://www.yuque.com/u39298356/uu4hxh?# 《Java知识宝典》