1.@EnableAsync 和 @Async一起使用做异步
首先创建一个类我叫他Jeep
package com.gcx.spring.z_springboot_Enablexxx;
import java.util.concurrent.TimeUnit;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
public class Jeep implements Runnable{
public void run() {
for(int i=0;i<10;i++) {
try {
System.out.println("=================:"+i);
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
然后我们在Maven默认的App.class中调用
package com.gcx.spring.z_springboot_Enablexxx;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* Hello world!
*EnableAsync 和@Async一起使用
*@Import 导入一个活着的多个配置类 会被spring容器所托管 ,如果导入配置类,配置类所有bean都会被spring容器托管
*/
@SpringBootApplication
public class App {
public static void main( String[] args ){
ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
context.getBean(Runnable.class).run();
System.out.println("===end=====");
context.close();
}
}
现在的情况是没有异步的情况,只能等待run方法执行之后再打印 end
接下来我们使用异步情况
在App.class加上 @EnableAsync注解。在Jeep.class上的run方法,加上@Async注解,打印结果如下
发现结果的确是异步执行的
2.我们来看看Enable注解内部的原理,发现里面都有@Import注解,它其实就是导入一个类,举例说明
创建一个User.class,Role.class
package com.gcx.spring.z_springboot_Enablexxx;
public class Role {
}
package com.gcx.spring.z_springboot_Enablexxx;
public class User {
}
这两个类现在没有加上@Componment注解
我们在App.class调用的话 会显示异常,告诉你Spring容器中并没有这个bean
System.out.println(context.getBean(User.class));
System.out.println(context.getBean(Role.class));
这时候我们在App.class上加入@Import注解
@Import({User.class,Role.class})
运行App.class会发现打印输出bean已经被spring容器装载
@Import既可以装载一个或者多个类交给spriing容器处理,也可以装载配置类MyConfig
package com.gcx.spring.z_springboot_Enablexxx;
import org.springframework.context.annotation.Bean;
public class MyConfig {
@Bean
public Runnable createRunnble1() {
return () -> {};
}
@Bean
public Runnable createRunnble2() {
return () -> {};
}
}
它还提供ImportSelector类静态注入Spring容器,我们创建一个MyImportSelector类来实现这个接口
package com.gcx.spring.z_springboot_Enablexxx;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/**
* 返回值是一个class 该class必须是全称 这样会被spring容器托管
* @author Administrator
*
*/
public class MyImportSelector implements ImportSelector{
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//可以获取到注解信息,然后根据注解信息动态的返回被spring容器托管的bean
System.out.println(importingClassMetadata.getAnnotationAttributes(EnableLog.class.getName()));
return new String[]{User.class.getName(),Role.class.getName(),MyConfig.class.getName()};
}
}
我们创建一个注解类
package com.gcx.spring.z_springboot_Enablexxx;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyImportSelector.class)
public @interface EnableLog {
String name();
}
接着我们在 App.class上添加@EnableLog(name=“today is a good day")
结果发现bean被全部注入到Spring容器,还可以打印注解信息
有静态的就有动态的注入
我们创建一个新类MyImportBeanDefinitionRegistrar实现ImportBeanDefinitionRegistrar
package com.gcx.spring.z_springboot_Enablexxx;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder beanDefinitionBuilder=BeanDefinitionBuilder.rootBeanDefinition(User.class);
BeanDefinition beanDefinition=beanDefinitionBuilder.getBeanDefinition();
registry.registerBeanDefinition("User", beanDefinition);
}
}
修改@EnableLog注解上@Import导入的类换成新创建的MyImportBeanDefinitionRegistrar
结果控制台同样输出bean被装载
静态的是有返回值的,动态的是没返回值