Springboot Enable开头注解解释说明

来源:互联网 发布:double保留两位小数 js 编辑:程序博客网 时间:2024/06/05 02:22


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;@Componentpublic 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 blocke.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容器托管 */@SpringBootApplicationpublic 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 {@Beanpublic Runnable createRunnble1() {return () -> {};}@Beanpublic 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{@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {//可以获取到注解信息,然后根据注解信息动态的返回被spring容器托管的beanSystem.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 {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {BeanDefinitionBuilder  beanDefinitionBuilder=BeanDefinitionBuilder.rootBeanDefinition(User.class);BeanDefinition beanDefinition=beanDefinitionBuilder.getBeanDefinition();registry.registerBeanDefinition("User", beanDefinition);}}
修改@EnableLog注解上@Import导入的类换成新创建的MyImportBeanDefinitionRegistrar

结果控制台同样输出bean被装载

静态的是有返回值的,动态的是没返回值

原创粉丝点击