Spring註解學習之:@Configuration,@Bean,@ComponentScan

以前學習Spring時,使用IOC,需要利用到xml配置文件進行組建的註冊和設定等等。同樣也可以使用註解的方式進行操作,下面是個人在學習註解開發過程中做的一些總結;

1、@Configuration:告訴Spring,當前class類是一個配置類,等同於以前的xml文件;在@Configuration裏面,其實也是一個@Component;要想被@Configuration註解,當前類不可以是final類型,不可以是匿名類;

2、@Bean:註冊一個組件;相當於以前在xml文件中的<bean/>標籤;

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {

可以看到@Bean可以再METHOD(方法),ANNOCITION_TYPE上進行註解,@Bean有如下幾個屬性可以進行設置:

參數 默認值 概念

value

默認爲方法名 bean別名,和name相互依賴關聯的,value,name如果都使用的話值必須要一致
name 默認方法名 相當於xml配置中<bean/>標籤的id

autowire

Autowire.NO,默認不開啓自動裝配  

initMethod

-- 初始化方法

destroyMethod

-- 註銷方法

3、@ComponentScan:指定包掃描策略,相當於xml配置文件中的<context:component-scan/>標籤,其中可以進行一些屬性設定,常用的屬性有以下幾種:

參數 默認值或者類型 概念

value

string 指定需要掃描的包路徑
excludeFilters Filter [] 按照一定策略,排除需要掃描的包

includeFilters

Filter [] 按照一定策略,只需要掃描指定的包,需要和useDefaultFilters=false搭配使用,要不然沒效果

useDefaultFilters

true 默認寶掃描策略

其中excludeFilter和includeFilter在使用是,需要使用到@Filter註解來指定策略,如下例子:

1、指定只掃描包含@Controller註解的bean
includeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
        },useDefaultFilters = false


2、指定只掃描不包含@Controller註解的bean
excludeFilters= {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
}

上面Filter的type可以有以下集中掃描策略:

FilterType.ANNOTATION 按照註解規則,過濾被指定註解標記的類
FilterType.ASSIGNABLE_TYPE 按照給定的類型
FilterType.ASPECTJ ASPECTJ表達式
FilterType.REGEX 正則表達式
FilterType.CUSTOM 自定義規則

 

當然,@ComponentScan可以寫多個,同樣也可是使用@ComponentScans包含多個@ComponentScan;

@ComponentScans(value = {
        @ComponentScan(value = "com.snail.tool.annocation",
                excludeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
                }
        ),
        @ComponentScan(value = "com.snail.tool.annocation",
                includeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
        }
        ,useDefaultFilters = false
        )      
})

做個測試,首先測試一下@Configuration和@Bean;定義一個bean類Student,在定義一個MyConfig的配置類,往容器中注入一個名爲stu的Student類型的bean,編寫測試類,看是否可以拿到;

1、student類
@Data
@ToString
public class Student {

    private int age;
    private String name;

    public Student() {
    }

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
}
----------------------------------------------------------------
2、Myconfig配置類
/**
 * @Configuration 作用是:告訴spring,當前class文件爲一個配置類文件
 */
@Configuration
public class MyConfig {

    /**
     * @Bean 作用是:向容器中註冊一個bean對象,改對象的類型爲返回值類型,id爲方法名。
     * 相當於配置文件中的bean標籤
     */
    @Bean()
    public Student student(){
        return new Student(20,"idea");
    }
}
------------------------------------------------------------------
3、測試類
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootAnnocationApplicationTests {


    @Test
    public void contextLoads() {
        ApplicationContext alicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        Object student = alicationContext.getBean("stu");
        System.out.println(student);
    }
}

結果:
Student(age=20, name=idea)

測試二,測試excludeFilter:新建controller,service,dao,分別使用@Controller,@service,@Repository註解,首先掃描不包括controller的所有bean;

1、Myconfig類
@Configuration
@ComponentScan(value = "com.snail.tool.annocation",
        excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
        }
)
public class MyConfig {

}

------------------------------------------------------
2、測試類
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootAnnocationApplicationTests {

    @Test
    public void contextLoads1(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }
    }

}

結果:

可以看到,沒有controllrt。但是爲什麼會有myconfig?因爲@Configuration底層是使用@Component註解的;

測試三,測試includeFilter:掃描只包括controller的所有bean;

1、Myconfig類
@Configuration
@ComponentScan(value = "com.snail.tool.annocation",
        includeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
        },useDefaultFilters = false
)
public class MyConfig {

}

------------------------------------------------------
2、測試類
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootAnnocationApplicationTests {

    @Test
    public void contextLoads1(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }
    }

}

結果:

上面便是自己總結的一部分只是內容,當初學的時候也是整個人都傻傻的,學就完事了。如有不對,還請指出,謝謝;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章