您的位置:首页 > 编程语言 > Java开发

Springboot Enable开头注解解释说明

2017-12-24 10:12 561 查看
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被装载

静态的是有返回值的,动态的是没返回值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: