`
y806839048
  • 浏览: 1121029 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

spring4的@configure

阅读更多

Spring4的@configure 

1,生成自定义的bean,纳入spring管理

2,覆盖默认的同名bean

3,对于集成抽象类或实现接口的,这个实现类就是代替默认抽象类或接口

 

下面以异步线程为例:

本文记录@Async的基本使用以及通过实现ThreadFactory来实现对线程的命名。

 

 

 

@Async的基本使用

 

 

 

业务场景需要进行批量更新,已有数据id主键、更新的状态。单条更新性能太慢,所以使用in进行批量更新。但是会导致锁表使得其他业务无法访问该表,in的量级太低又导致性能太慢。

 

龙道友提出了一个解决方案,把要处理的数据分成几个list之后使用多线程进行数据更新。提到多线程可直接使用@Async注解来进行异步操作。

 

好的,接下来上面的问题我们不予解答,来说下@Async的简单使用

 

@Async在SpringBoot中的使用较为简单,所在位置如下:

 

 

一.启动类加入注解@EnableAsync

 

第一步就是在启动类中加入@EnableAsync注解   启动类代码如下:

 

@SpringBootApplication

@EnableAsync//可以写在具体配置类上

public class EurekaApplication {

 

    public static void main(String[] args) {

        SpringApplication.run(EurekaApplication.class, args);

    }

}

 

二.编写MyAsyncConfigurer类

 

MyAsyncConfigurer类实现了AsyncConfigurer接口,重写AsyncConfigurer接口的两个重要方法:

 

1.getAsyncExecutor:自定义线程池,若不重写会使用默认的线程池。

 

2.getAsyncUncaughtExceptionHandler:捕捉IllegalArgumentException异常.

 

一方法很好理解。二方法中提到的IllegalArgumentException异常在之后会说明。代码如下:

 

/**

 * @author hsw

 * @Date 20:12 2018/8/23

 */

@Slf4j

@Component

public class MyAsyncConfigurer implements AsyncConfigurer {

 

    @Override

    public Executor getAsyncExecutor() {

        //定义一个最大为10个线程数量的线程池

        ExecutorService service = Executors.newFixedThreadPool(10);

        return service;

    }

 

    @Override

    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {

        return new MyAsyncExceptionHandler();

    }

 

    class MyAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {

 

        @Override

        public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {

            log.info("Exception message - " + throwable.getMessage());

            log.info("Method name - " + method.getName());

            for (Object param : objects) {

                log.info("Parameter value - " + param);

            }

        }

    }

 

}</code>

 

三.三种测试方法

 

1.无参无返回值方法

2.有参无返回值方法

3.有参有返回值方法

 

具体代码如下:

 

/**

 * @author hsw

 * @Date 20:07 2018/8/23

 */

@Slf4j

@Component

public class AsyncExceptionDemo {

 

    @Async

    public void simple() {

        log.info("this is a void method");

    }

 

    @Async

    public void inputDemo (String s) {

        log.info("this is a input method,{}",s);

        throw new IllegalArgumentException("inputError");

    }

 

    @Async

    public Future hardDemo (String s) {

        log.info("this is a hard method,{}",s);

        Future future;

        try {

            Thread.sleep(3000);

            throw new IllegalArgumentException();

        }catch (InterruptedException e){

            future = new AsyncResult("InterruptedException error");

        }catch (IllegalArgumentException e){

            future = new AsyncResult("i am throw IllegalArgumentException error");

        }

        return future;

    }

}

 

在第二种方法中,抛出了一种名为IllegalArgumentException的异常,在上述第二步中,我们已经通过重写getAsyncUncaughtExceptionHandler方法,完成了对产生该异常时的处理。在处理方法中我们简单列出了异常的各个信息。ok,现在该做的准备工作都已完成,加个测试方法看看结果如何

 

/**

 * @author hsw

 * @Date 20:16 2018/8/23

 */

@RunWith(SpringRunner.class)

@SpringBootTest

@Slf4j

public class AsyncExceptionDemoTest {

 

    @Autowired

    private AsyncExceptionDemo asyncExceptionDemo;

 

    @Test

    public void simple() {

        for (int i=0;i<3;i++){

            try {

                asyncExceptionDemo.simple();

                asyncExceptionDemo.inputDemo("input");

                Future future = asyncExceptionDemo.hardDemo("hard");

                log.info(future.get());

            } catch (InterruptedException e) {

                e.printStackTrace();

            } catch (ExecutionException e) {

                e.printStackTrace();

            }

        }

    }

}

 

测试结果如下:

 

2018-08-25 16:25:03.856  INFO 4396 --- [           main] c.hsw.test.async.AsyncExceptionDemoTest  : Started AsyncExceptionDemoTest in 3.315 seconds (JVM running for 4.184)

2018-08-25 16:25:03.947  INFO 4396 --- [pool-1-thread-1] com.hsw.test.async.AsyncExceptionDemo    : this is a void method

2018-08-25 16:25:03.947  INFO 4396 --- [pool-1-thread-3] com.hsw.test.async.AsyncExceptionDemo    : this is a hard method,hard

2018-08-25 16:25:03.947  INFO 4396 --- [pool-1-thread-2] com.hsw.test.async.AsyncExceptionDemo    : this is a input method,input

2018-08-25 16:25:03.947  INFO 4396 --- [pool-1-thread-2] com.hsw.test.async.MyAsyncConfigurer     : Exception message - inputError

2018-08-25 16:25:03.947  INFO 4396 --- [pool-1-thread-2] com.hsw.test.async.MyAsyncConfigurer     : Method name - inputDemo

2018-08-25 16:25:03.947  INFO 4396 --- [pool-1-thread-2] com.hsw.test.async.MyAsyncConfigurer     : Parameter value - input

2018-08-25 16:25:06.947  INFO 4396 --- [           main] c.hsw.test.async.AsyncExceptionDemoTest  : i am throw IllegalArgumentException error

2018-08-25 16:25:06.948  INFO 4396 --- [pool-1-thread-4] com.hsw.test.async.AsyncExceptionDemo    : this is a void method

2018-08-25 16:25:06.948  INFO 4396 --- [pool-1-thread-6] com.hsw.test.async.AsyncExceptionDemo    : this is a hard method,hard

2018-08-25 16:25:06.948  INFO 4396 --- [pool-1-thread-5] com.hsw.test.async.AsyncExceptionDemo    : this is a input method,input

2018-08-25 16:25:06.948  INFO 4396 --- [pool-1-thread-5] com.hsw.test.async.MyAsyncConfigurer     : Exception message - inputError

2018-08-25 16:25:06.948  INFO 4396 --- [pool-1-thread-5] com.hsw.test.async.MyAsyncConfigurer     : Method name - inputDemo

2018-08-25 16:25:06.948  INFO 4396 --- [pool-1-thread-5] com.hsw.test.async.MyAsyncConfigurer     : Parameter value - input

2018-08-25 16:25:09.949  INFO 4396 --- [           main] c.hsw.test.async.AsyncExceptionDemoTest  : i am throw IllegalArgumentException error

2018-08-25 16:25:09.950  INFO 4396 --- [pool-1-thread-7] com.hsw.test.async.AsyncExceptionDemo    : this is a void method

2018-08-25 16:25:09.950  INFO 4396 --- [pool-1-thread-8] com.hsw.test.async.AsyncExceptionDemo    : this is a input method,input

2018-08-25 16:25:09.950  INFO 4396 --- [pool-1-thread-8] com.hsw.test.async.MyAsyncConfigurer     : Exception message - inputError

2018-08-25 16:25:09.950  INFO 4396 --- [pool-1-thread-9] com.hsw.test.async.AsyncExceptionDemo    : this is a hard method,hard

2018-08-25 16:25:09.950  INFO 4396 --- [pool-1-thread-8] com.hsw.test.async.MyAsyncConfigurer     : Method name - inputDemo

2018-08-25 16:25:09.950  INFO 4396 --- [pool-1-thread-8] com.hsw.test.async.MyAsyncConfigurer     : Parameter value - input

2018-08-25 16:25:12.950  INFO 4396 --- [           main] c.hsw.test.async.AsyncExceptionDemoTest  : i am throw IllegalArgumentException error

2018-08-25 16:25:12.953  INFO 4396 --- [       Thread-2] o.s.w.c.s.GenericWebApplicationContext   : Closing org.springframework.web.context.support.GenericWebApplicationContext@71075444: startup date [Sat Aug 25 16:25:01 CST 2018]; root of context hierarchy

 

测试成功。

 

到此为止,关于@Async注解的基本使用内容结束。但是在测试过程中,我注意到线程名的命名为默认的pool-1-thread-X,虽然可以分辨出不同的线程在进行作业,但依然很不方便,为什么默认会以这个命名方式进行命名呢?

 

线程池的命名

 

 

点进Executors.newFixedThreadPool,发现在初始化线程池的时候有另一种方法

 

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory)

 

那么这个ThreadFactory为何方神圣?继续ctrl往里点,在类中发现这么一个实现类。

 

 

 

破案了破案了。原来是在这里对线程池进行了命名。那我们只需自己实现ThreadFactory接口,对命名方法进行重写即可,完成代码如下:

 

static class MyNamedThreadFactory implements ThreadFactory {

    private static final AtomicInteger poolNumber = new AtomicInteger(1);

    private final ThreadGroup group;

    private final AtomicInteger threadNumber = new AtomicInteger(1);

    private final String namePrefix;

 

    MyNamedThreadFactory(String name) {

 

        SecurityManager s = System.getSecurityManager();

        group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();

        if (null == name || name.isEmpty()) {

            name = "pool";

        }

 

        namePrefix = name + "-" + poolNumber.getAndIncrement() + "-thread-";

    }

 

    public Thread newThread(Runnable r) {

        Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);

        if (t.isDaemon())

            t.setDaemon(false);

        if (t.getPriority() != Thread.NORM_PRIORITY)

            t.setPriority(Thread.NORM_PRIORITY);

        return t;

    }

}

 

然后在创建线程池的时候加上新写的类即可对线程名进行自定义。

 

@Override

public Executor getAsyncExecutor() {

    ExecutorService service = Executors.newFixedThreadPool(10,new MyNamedThreadFactory("HSW"));

    return service;

}

 

看看重命名后的执行结果。

 

2018-08-25 16:42:44.068  INFO 46028 --- [           main] c.hsw.test.async.AsyncExceptionDemoTest  : Started AsyncExceptionDemoTest in 3.038 seconds (JVM running for 3.83)

2018-08-25 16:42:44.155  INFO 46028 --- [ HSW-1-thread-3] com.hsw.test.async.AsyncExceptionDemo    : this is a hard method,hard

2018-08-25 16:42:44.155  INFO 46028 --- [ HSW-1-thread-2] com.hsw.test.async.AsyncExceptionDemo    : this is a input method,input

2018-08-25 16:42:44.155  INFO 46028 --- [ HSW-1-thread-1] com.hsw.test.async.AsyncExceptionDemo    : this is a void method

2018-08-25 16:42:44.155  INFO 46028 --- [ HSW-1-thread-2] com.hsw.test.async.MyAsyncConfigurer     : Exception message - inputError

2018-08-25 16:42:44.155  INFO 46028 --- [ HSW-1-thread-2] com.hsw.test.async.MyAsyncConfigurer     : Method name - inputDemo

2018-08-25 16:42:44.155  INFO 46028 --- [ HSW-1-thread-2] com.hsw.test.async.MyAsyncConfigurer     : Parameter value - input

2018-08-25 16:42:47.155  INFO 46028 --- [           main] c.hsw.test.async.AsyncExceptionDemoTest  : i am throw IllegalArgumentException error

2018-08-25 16:42:47.156  INFO 46028 --- [ HSW-1-thread-4] com.hsw.test.async.AsyncExceptionDemo    : this is a void method

2018-08-25 16:42:47.156  INFO 46028 --- [ HSW-1-thread-5] com.hsw.test.async.AsyncExceptionDemo    : this is a input method,input

2018-08-25 16:42:47.156  INFO 46028 --- [ HSW-1-thread-6] com.hsw.test.async.AsyncExceptionDemo    : this is a hard method,hard

2018-08-25 16:42:47.156  INFO 46028 --- [ HSW-1-thread-5] com.hsw.test.async.MyAsyncConfigurer     : Exception message - inputError

2018-08-25 16:42:47.156  INFO 46028 --- [ HSW-1-thread-5] com.hsw.test.async.MyAsyncConfigurer     : Method name - inputDemo

2018-08-25 16:42:47.156  INFO 46028 --- [ HSW-1-thread-5] com.hsw.test.async.MyAsyncConfigurer     : Parameter value - input

2018-08-25 16:42:50.156  INFO 46028 --- [           main] c.hsw.test.async.AsyncExceptionDemoTest  : i am throw IllegalArgumentException error

2018-08-25 16:42:50.157  INFO 46028 --- [ HSW-1-thread-7] com.hsw.test.async.AsyncExceptionDemo    : this is a void method

2018-08-25 16:42:50.157  INFO 46028 --- [ HSW-1-thread-8] com.hsw.test.async.AsyncExceptionDemo    : this is a input method,input

2018-08-25 16:42:50.157  INFO 46028 --- [ HSW-1-thread-9] com.hsw.test.async.AsyncExceptionDemo    : this is a hard method,hard

2018-08-25 16:42:50.157  INFO 46028 --- [ HSW-1-thread-8] com.hsw.test.async.MyAsyncConfigurer     : Exception message - inputError

2018-08-25 16:42:50.157  INFO 46028 --- [ HSW-1-thread-8] com.hsw.test.async.MyAsyncConfigurer     : Method name - inputDemo

2018-08-25 16:42:50.157  INFO 46028 --- [ HSW-1-thread-8] com.hsw.test.async.MyAsyncConfigurer     : Parameter value - input

2018-08-25 16:42:53.157  INFO 46028 --- [           main] c.hsw.test.async.AsyncExceptionDemoTest  : i am throw IllegalArgumentException error

2018-08-25 16:42:53.161  INFO 46028 --- [       Thread-2] o.s.w.c.s.GenericWebApplicationContext   : Closing org.springframework.web.context.support.GenericWebApplicationContext@71075444: startup date [Sat Aug 25 16:42:41 CST 2018]; root of context hierarchy

NICE!

 

分享到:
评论

相关推荐

    Spring4整合Jersey2.9

    在本文中,我们将深入探讨如何将Spring4框架与Jersey2.9进行集成,以便创建一个功能丰富的RESTful Web服务。这个入门案例采用Maven作为项目构建工具,使得整个过程更加简便。 首先,理解Spring4和Jersey2.9的核心...

    彻底根治Spring @ResponseBody JavaScript HTML特殊字符

    4. **其他解决方案**: - 如果你使用的是Thymeleaf等模板引擎,它们通常会自动转义输出内容,防止XSS攻击。 - 如果你希望在前端处理转义,可以在JavaScript中使用`encodeURI()`或`encodeURIComponent()`函数,但这...

    Spring-Boot1.52 SpringSecurity4 Spring Data Jpa 整合例子

    ### Spring Boot 1.5.2、Spring Security 4 与 Spring Data JPA 整合实践 #### 一、项目背景及目标 本项目旨在通过一个具体的案例来演示如何将 Spring Boot 1.5.2、Spring Security 4 以及 Spring Data JPA 进行...

    spring4安全框架 maven

    Spring4安全框架是基于Spring Framework 4.x版本的Spring Security模块,它是一个强大的安全管理组件,用于保护基于Java的Web应用程序。Maven是一个流行的项目管理和综合工具,它通过管理项目的依赖关系,帮助开发者...

    log4j与spring的详细配置。

    PropertyConfigurator.configure("classpath:log4j.properties"); ``` 3. **在代码中使用**:Spring自动注入`Logger`实例,可以直接在代码中调用方法记录日志: ```java @Autowired private Logger logger; ...

    spring-boot-02-configure.rar

    Spring Boot学习笔记-------(三)spring boot配置的配套代码,博客地址:https://blog.csdn.net/huaya1127/article/details/104152567

    Spring版本Log4J的Demo

    在Spring应用中,我们可以通过`PropertyConfigurator.configure()`方法加载Log4J配置,或者在Spring的`context.xml`中使用`ContextLoaderListener`来自动加载。例如: ```xml &lt;listener-class&gt;org.spring...

    Beginning Spring Boot 2 Applications and Microservices with the Spring Framework

    usually multiple ways to configure the application. Although it is a good thing to have multiple options, it can be overwhelming to the beginners. Spring Boot addresses this “Spring applications need...

    Spring boot 和Spring Security4最新整合实例.docx

    Spring Boot 与 Spring Security 4 最新整合实例 Spring Boot 和 Spring Security 4 最新整合实例是一篇详细的教程,旨在指导用户如何使用 Spring Boot 和 Spring Security 4 实现用户身份认证、登录退出、用户...

    Spring Boot和Spring Security4最新整合实例

    Spring Boot 和 Spring Security 整合实例详解 Spring Boot 是一个快速开发框架,它简化了 Spring 应用的初始搭建以及开发过程。而 Spring Security 是一个强大的安全框架,用于处理身份认证(Authentication)和...

    Spring Boot集成Spring Security的Demo

    Spring Boot集成Spring Security是开发基于Java的Web应用时常见的安全框架选择。Spring Security提供了一整套强大且灵活的安全控制机制,使得开发者可以轻松地实现身份验证、授权以及各种安全功能。下面将详细介绍...

    spring security 4 小例子带自定义过滤器

    在Spring Security 4中,我们可以通过自定义过滤器来扩展其功能,以满足特定的安全需求。在这个小例子中,我们将探讨如何创建并集成自定义过滤器,以及它在Spring Security中的工作原理。 首先,我们需要理解Spring...

    spring cloud2.0 eureka server spring security配置

    4. **安全认证的进一步定制**: - 如果需要更复杂的认证策略,比如OAuth2或其他JWT令牌验证,可以通过自定义`Filter`或使用Spring Security提供的扩展点来实现。 - 可以添加额外的过滤器,例如: ```java @...

    spring security 完整项目实例

    Spring Security 是一个强大的安全框架,用于为Java应用提供身份验证和授权服务。在这个完整的项目实例中,我们将深入探讨Spring Security的核心概念以及如何将其应用于实际的Web应用程序开发。 首先,我们从用户、...

    Spring_boot和Spring_Security4整合

    总之,Spring Boot和Spring Security 4的整合为开发者提供了一个高效且灵活的安全框架,帮助我们快速构建安全可控的应用程序。通过深入学习和实践,开发者可以熟练掌握这一重要技能,提升自己的专业能力。

    狂神spring-security静态资源.zip

    4. **Web安全配置** Spring Security的配置通常在Java配置类中完成,通过`WebSecurityConfigurerAdapter`的子类实现。例如,配置认证和授权规则,以及自定义登录页面: ```java @Configuration @...

    Pro Spring Boot 2第2版-2009-EPUB版

    Configure and use Spring Boot Use non-functional requirements with Spring Boot Actuator Carry out web development with Spring Boot Persistence with JDBC, JPA and NoSQL Databases Messaging with JMS, ...

    spring security4登陆例子

    ### Spring Security 4 登录示例详解 #### 一、概览 在现代Web应用开发中,安全性至关重要。Spring Security 是一款广泛使用的安全框架,它为基于Spring的应用提供了全面的安全解决方案,包括认证、授权等核心功能...

    SpringSecurity笔记,编程不良人笔记

    4. **SpringSecurity认证流程** - 用户提交登录请求,请求被SpringSecurity的过滤器拦截。 - 认证过滤器(如`UsernamePasswordAuthenticationFilter`)提取用户名和密码,并调用`UserDetailsService`进行验证。 -...

    spring-boot-reference.pdf

    4. Working with Spring Boot 5. Learning about Spring Boot Features 6. Moving to Production 7. Advanced Topics II. Getting Started 8. Introducing Spring Boot 9. System Requirements 9.1. Servlet ...

Global site tag (gtag.js) - Google Analytics