Spring Boot @Enable*注解的工作原理

作用:启用某种功能特性的注解

@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();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值