preface

The last article covered the source code for @import, as well as some functional uses for the annotation. So this is some application of the actual situation. It’s easy to define @enablexxx and add @import to Import the configuration. Let’s implement a custom @enablexxx annotation. The main thing is to do an asynchronous task, which is the same as @enableAsync, but it’s a lot worse than that.

The body of the

Note that, as in the previous article, create this annotation in the directory above the startup class. For example, the startup class is under A.B.C.D. Then the annotation is under A.B.C. c.

  1. Create a base annotation marked on the method to indicate that the method will execute asynchronously

    @Target({ElementType.TYPE,ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface TestAsync {
    }

Copy the code
  1. Creating AOP Advice (implementing the MethodInterceptor interface)

    public class AsyncInterceptor implements MethodInterceptor {
        @Override
        public Object invoke(MethodInvocation methodInvocation) throws Throwable {
            new Thread(() -> {
                try {
                    System.out.println("AsyncInterceptor run before ... " + Thread.currentThread().getName());
                    methodInvocation.proceed();
                    System.out.println("AsyncInterceptor run after ..." + Thread.currentThread().getName());
                } catch (Throwable throwable) {
                    throwable.printStackTrace();
                }
            }).start();
            return null; }}Copy the code
  1. Creating a configuration class

    @Configuration
    public class AsyncConfig {
        @Bean
        public DefaultPointcutAdvisor defaultPointcutAdvisor1(a){
            AsyncInterceptor asyncInterceptor=new AsyncInterceptor();
            // 1. Annotation mode
            AnnotationMatchingPointcut pointcut=new AnnotationMatchingPointcut(null,TestAsync.class);
            / / 2.
            // JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
            // pointcut.setPatterns("");
            DefaultPointcutAdvisor advisor=new DefaultPointcutAdvisor();
            advisor.setPointcut(pointcut);
            advisor.setAdvice(asyncInterceptor);
            returnadvisor; }}Copy the code

Note here is the first way Pointcut, the first parameter is null, or cannot achieve function, need to pay attention to AnnotationMatchingPointcut constructor of different functions. Also, try to use annotations when defining pointcuts so they are more granular and easier to modify.

  1. Create a custom annotation @enableTestAsync

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(AsyncConfig.class)
    public @interface EnableTestAsync {
    }

Copy the code

Here for simple and quick, I was using a configuration class, usually is to use ImportSelector or ImportBeanDefinitionRegistrar implementation class, because @ EnableXXX annotation will also include a attribute values, and the two interface implementation class is to be able to get information to the annotation.

  1. Using annotations

5.1 Add the @enableTestAsync annotation on the startup class for it to take effect. 5.2 Creating interfaces and Implementation classes

    public interface TestAsyncService {
        void testAsync(a);
        void testAsyncA(a);
    }

    @Service
    public class TestAsyncServiceImpl implements TestAsyncService {
        @Override
        public void testAsync(a) {
            System.out.println("TestAsyncServiceImpl. TestAsync () the run... ");
        }
    
        @Override
        @TestAsync
        public void testAsyncA(a) {
            System.out.println("TestAsyncServiceImpl. TestAsyncA () the run... "); }}Copy the code

5.3 call


    @SpringBootApplication
    @EnableTestAsync
    public class SpringBootTwoApplication {
        public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(SpringbootTwoApplication.class, args); TestAsyncService bean = run.getBean(TestAsyncService.class); bean.testAsync(); bean.testAsyncA(); }}Copy the code

Running result:

TestAsyncServiceImpl. TestAsync () the run... AsyncInterceptor run before ... Thread - 2 TestAsyncServiceImpl. TestAsyncA () the run... AsyncInterceptor run after ... Thread-2Copy the code

This is a simple custom @enablexxx annotation, of course, there are a lot of problems.