作用:启用某种功能特性的注解
@Enable*注解的种类举例:
(1)@EnableConfigurationProperties:用来启用将配置文件属性注入到bean中这一特性,和@ConfigurationProperties注解一起使用。
(2)@EnableAsync启用异步特性,与@Async(相当于对方法或类进行一个标记,具体开启异步任务由TaskExecutor来进行)一起使用
@Async作用
具体作用
Enable*原理一
原理二
import java.util.concurrent.TimeUnit;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
public class Jeep implements Runnable {
@Override
@Async
public void run() {
for(int i=0;i<=10;i++)
{
System.out.println("========="+i);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
@ComponentScan
@EnableAsync
public class App
{
public static void main( String[] args )
{
ConfigurableApplicationContext context= SpringApplication.run(App.class, args);
//System.out.println(context.getBeansOfType(EncodingConvert.class));
((Runnable) context.getBean("jeep")).run();
System.out.println("------------");
context.close();
}
}
@Enable的原理:@Enable注解可以发挥作用于@Import有关,@Import作用是可以向Spring容器中导入普通类(不用加@Component)和配置类(不用加@Configuration)。此注解常用来进行配置类的集中管理。
@Import注解导入了ImportSelector接口的实现类,ImportSelector的selectImports方法会将返回的字符串数组中的类装配到Spring容器中。
package com.edu1.spring.springboot;
//注意:此类上没有添加任何注解
public class User {
@Override
public String toString() {
return "User [getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()=" + super.toString()
+ "]";
}
}
package com.edu1.spring.springboot;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// TODO Auto-generated method stub
return new String[]{"com.edu1.spring.springboot.User"};//User类的全路径名,也可以写为User.class.getName()
}
}
@ComponentScan
@Import(MyImportSelector.class)
public class App
{
public static void main( String[] args )
{
ConfigurableApplicationContext context= SpringApplication.run(App.class, args);
//System.out.println(context.getBeansOfType(EncodingConvert.class));
// ((Runnable) context.getBean("jeep")).run();
//context.getBean(Runnable.class).run();
System.out.println( context.getBean(User.class));
context.close();
}
}
还可以利用ImportSelector的selectImports()方法的importingClassMetadata参数获得相应的注解(前提是该注解使用@Import注解引入了ImportSelector的实现类)信息,具体例子如下。
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;
//自己创建EnableLog注解,引入ImportSelector的实现类MyImportSelector
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MyImportSelector.class)
public @interface EnableLog {
String name();
}
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// TODO Auto-generated method stub
System.out.println(importingClassMetadata.getAnnotationAttributes(EnableLog.class.getCanonicalName()));//在实现类中获取注解信息
return new String[]{};
}
}
@ComponentScan
//@Import(MyImportSelector.class)
@EnableLog(name = "my Spring Boot")//注解信息
public class App
{
public static void main( String[] args )
{
ConfigurableApplicationContext context= SpringApplication.run(App.class, args);
//System.out.println(context.getBeansOfType(EncodingConvert.class));
// ((Runnable) context.getBean("jeep")).run();
//context.getBean(Runnable.class).run();
// System.out.println( context.getBean(User.class));
context.close();
}
}
运行结果:
注意:也可以实现ImportBeanDefinitionRegistrar接口的 default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)方法来达到相同的效果,两者的主要不同是后者用BeanDefinitionRegistry 对象来向Spring容器中注入相应实例。
```go
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 {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder bdb=BeanDefinitionBuilder.rootBeanDefinition(User.class);
BeanDefinition beanDefinition=bdb.getBeanDefinition();
registry.registerBeanDefinition("user", beanDefinition);
}
}
@ComponentScan
@Import(MyImportBeanDefinitionRegistrar.class)
@EnableLog(name = "my Spring Boot")
public class App
{
public static void main( String[] args )
{
ConfigurableApplicationContext context= SpringApplication.run(App.class, args);
//System.out.println(context.getBeansOfType(EncodingConvert.class));
//((Runnable) context.getBean("jeep")).run();
//context.getBean(Runnable.class).run();
System.out.println( context.getBean(User.class));
context.close();
}
}