Spring Boot(九) @Enable*註解的工作原理

1. @EnableConfigurationProperties

    0.是用來啓用一個特性,這個特性就是,可以把配置文件的屬性注入到bean裏面去,一般是要和@ConfigurationProperties一起使用
    1.Demo
        1.在啓動類里加上 @EnableConfigurationProperties 註解(@SpringBootConfiguration 裏有這個註解)
@EnableConfigurationProperties
@ComponentScan
public class App {
    public static void main(String[] args) {
        ConfigurableApplicationContext context=SpringApplication.run(App.class, args);
        System.out.println(context.getBean(TomcatProperties.class));
        context.close();
    }
}
        2.創建一個TomcatProperties.java
@Component
@ConfigurationProperties("tomcat")
public class TomcatProperties {
    private String host;
    private int port;
    //get,set方法
}

2. 在SpringBoot中使用異步---- @EnableAsync、@Async

    0. @EnableAsync 起步啓動,一般是和@Async一起使用
        1.Demo
            1.啓動類
@EnableAsync
@ComponentScan
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();
    }
}
            2.Jeep.java
@Component
public class Jeep implements Runnable{
    @Async
    public void run() {
        try {
            for (int i = 0; i <3; i++) {
                System.out.println("-------------"+i);
                TimeUnit.SECONDS.sleep(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
           }
    }
}


3. @Import

0.用來導入一個或多個類(會被Spring容器託管),或者是配置類(配置類裏面的bean都會被Spring容器託管)
    1.一個bean
        @Import(User.class)
    2.多個bean(可以是數組)
        @Import({User.class,Role.class})
    3.bean的配置文件
        0.創建一個bean的配置文件 MyConfiguration.java
public class MyConfiguration {
    @Bean
    public Runnable getRunnable(){
        return ()->{};
    }
    @Bean
    public Runnable getRunnable2(){
        return ()->{};
    }
}
        1.應用
@Import(MyConfiguration.class)
				public class App2 {
					    public static void main(String[] args) {
        ConfigurableApplicationContext context=SpringApplication.run(App2.class, args);
        context.close();
    }
}
1.ImportSelector 接口----(一、將想要託管的bean動態地放入spring容器)
    0.使用這種方法,通過在 @Import中 輸入不同的類,可以動態地返回一些需要使用的類(放入Spring容器託管起來),
      selectImports方法的返回值,必須是一個class(全稱),該class會被Spring託管起來
    1.Demo
        1. 創建 MyImportSelector.java ,實現 ImportSelector
public class MyImportSelector implements ImportSelector {
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{User.class.getName(),Role.class.getName(),MyConfiguration.class.getName()};
    } 
}

        2.應用

@Import(MyConfiguration.class)
public class App2 {
    public static void main(String[] args) {
        ConfigurableApplicationContext context=SpringApplication.run(App2.class, args);
        context.close();
    }
}

2.ImportSelector 接口----(二、獲取註解裏的屬性,可以動態地註冊bean到spring容器裏)
    1.Demo

       1.創建 EnableLog.java 註解 ,使用4個註解 

         @Target(ElementType.TYPE),@Retention(RetentionPolicy.RUNTIME), @Documented,@Import 

            0. @Import 裏放入ImportSelector接口 的實現類
            1.代碼
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyImportSelector.class)
public @interface EnableLog {
    String name();
}
            2.獲取 ImportSelector接口 的實現類 裏的屬性 (使用importingClassMetadata 參數裏的 getAllAnnotationAttributes方法)
public class MyImportSelector implements ImportSelector {
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        System.out.println(importingClassMetadata.getAllAnnotationAttributes(EnableLog.class.getName()));
        /*
        * 這裏可以獲得註解的詳細信息,然後根據信息動態的返回需要被spring容器管理的bean
        */
        return new String[]{User.class.getName(),Role.class.getName(),MyConfiguration.class.getName()};
    } 
}
            3.應用
@EnableLog(name = "spring boot")
public class App2 {
    public static void main(String[] args) {
        ConfigurableApplicationContext context=SpringApplication.run(App2.class, args);
        context.close();
    }
}

3.ImportSelector 接口----(三、可以 用 ImportBeanDefintionRegistrar 接口 來替換ImportSelector) 

    0. registerBeanDefinitions方法參數中有一個BeanDefinitionRegistry,它可以用來往spring容器裏注入bean如此,我們就可以在 registerBeanDefinition方法裏動態地注入bean
    1.Demo
        1.創建 MyImportBeanDefinitionRegistrar.java 實現 ImportBeanDefinitionRegistrar ,來註冊bean
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        BeanDefinitionBuilder bdb=BeanDefinitionBuilder.rootBeanDefinition(User.class);
        registry.registerBeanDefinition("user", bdb.getBeanDefinition());
    }
}

        2.其他的和 ImportSelector一樣Spring Boot @Enable*註解的工作原理

4.ImportBeanDefintionRegistrar 的例子

0.實現:將指定的包裏的類打印出來

1.創建 EchoBeanPostProcessor.java

public class EchoBeanPostProcessor implements BeanPostProcessor {
	private List<String> packages;
	//get、set方法
	
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		for (String pack : packages) {
			if(bean.getClass().getName().startsWith(pack)){
				System.out.println("Echo bean:"+bean.getClass().getName());
			}
		}
		return bean;
	}
}	 

2.創建 EchoImportBeanDefinitionRegistrar 實現 ImportBeanDefinitionRegistrar

public class EchoImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		//獲得 EnableEcho 註解的屬性信息
		Map<String,Object> attr=importingClassMetadata.getAnnotationAttributes(EnableEcho.class.getName());
		String[] packArr=(String[])attr.get("packages");
		List<String> packages=Arrays.asList(packArr);
		System.out.println("packages:"+packages);
		//將 EchoBeanPostProcessor 註冊到Spring容器
		BeanDefinitionBuilder bdb=BeanDefinitionBuilder.rootBeanDefinition(EchoBeanPostProcessor.class);
		bdb.addPropertyValue("packages", packages);
		registry.registerBeanDefinition(EchoBeanPostProcessor.class.getName(),bdb.getBeanDefinition() );
	}
}	

3.創建 EnableEcho.java

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EchoImportBeanDefinitionRegistrar.class)
public @interface EnableEcho {
	String[] packages();
}	

4.創建bean ,並注入到spring容器裏

1.com.edu.spring.springboot.SpringBoot09.bean.Cat

@Component
public class Cat {
	
}			

2.com.edu.spring.springboot.SpringBoot09.vo.Dog

@Component
public class Dog {

}

5.應用

@EnableEcho(packages = { "com.edu.spring.springboot.SpringBoot09.vo" ,"com.edu.spring.springboot.SpringBoot09.bean"})
public class App2 {
	public static void main(String[] args) {
		ConfigurableApplicationContext context=SpringApplication.run(App2.class, args);
		context.close();
	}
}


發佈了40 篇原創文章 · 獲贊 2 · 訪問量 9811
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章