二、Spring註解開發,次日

次日:Spring annotation開發

目錄:一、TypeFilter指定過濾規則 二、Scope設置組件做用域 三、懶加載Lazy 四、Conditional按條件註冊beanjava

1、TypeFilter指定過濾規則

最經常使用的兩個
FilterType.Annotation	按照註解
FilterType.ASSIGNABLE_TYPE  按照給定的類型
自定義規則
FilterType.Custom  自定義規則--實現TypeFilter接口[TypeFilter和FilterType有區別的]

一、FilterType.ASSIGNABLE_TYPE

package com.lee.config;

import com.lee.bean.Person;
import com.lee.service.BookService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;

//@ComponentScan("com.lee")//自動掃描 value指定要掃描的包
@Configuration//告訴Spring這是一個配置類
//@ComponentScan(value="com.lee",excludeFilters = {
//        @ComponentScan.Filter(type=FilterType.ANNOTATION,value = Controller.class)
//})
@ComponentScan(value = "com.lee",useDefaultFilters=false,includeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,value = Controller.class),
        @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,value= BookService.class)
})
//FilterType.ANNOTATION 按照註解
//FilterType.ASSIGNABLE_TYPE 按照給定的類型
//FilterType.CUSTOM 按照自定義
public class MainConfig {

    //Bean 給容器註冊一個bean,類型爲返回值的類型,id默認使用方法名做爲id
    //@Bean("名字")能夠給bean修更名稱
    @Bean
    public Person person(){
        return new Person(2,"lee2","male2");
    }


}

結果linux

mainConfig
bookController
bookService
person

二、FilterType.Custom

#metadataReader the metadata reader for the target class
#metadataReaderFactory  a factory for obtaining metadata readers for other classes (such as superclasses and interfaces)

MyTypeFilter.classspring

package com.lee.config;


import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;

public class MyTypeFilter implements TypeFilter {


    /**
     *
     * @param metadataReader 讀取到當前正在掃描類的信息
     * @param metadataReaderFactory  一個工廠,能夠獲取到任何類的信息
     */
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        System.out.println("======>"+classMetadata.getClassName());
        if(classMetadata.getClassName().contains("ao")){
            System.out.println("---->"+classMetadata.getClassName());
            return true;
        }

        return false;
    }
}

MainConfig.classide

package com.lee.config;

import com.lee.bean.Person;
import com.lee.service.BookService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;

//@ComponentScan("com.lee")//自動掃描 value指定要掃描的包
@Configuration//告訴Spring這是一個配置類
//@ComponentScan(value="com.lee",excludeFilters = {
//        @ComponentScan.Filter(type=FilterType.ANNOTATION,value = Controller.class)
//})
@ComponentScan(value = "com.lee",useDefaultFilters=false,includeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,value = Controller.class),
        @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,value= BookService.class),
        @ComponentScan.Filter(type=FilterType.CUSTOM,value = MyTypeFilter.class)
})
//FilterType.ANNOTATION 按照註解
//FilterType.ASSIGNABLE_TYPE 按照給定的類型
//FilterType.CUSTOM 按照自定義
public class MainConfig {

    //Bean 給容器註冊一個bean,類型爲返回值的類型,id默認使用方法名做爲id
    //@Bean("名字")能夠給bean修更名稱
    @Bean
    public Person person(){
        return new Person(2,"lee2","male2");
    }


}

結果:prototype

mainConfig
bookController
bookDao
bookService
person

2、Scope設置組件做用域

spring默認Bean都是單實例的ssr

一、單例-SINGLETON

MainConfig2.classcode

package com.lee.config;

import com.lee.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@ComponentScan(value = "com.lee")//包掃描
@Configuration//這是個配置類
public class MainConfig2 {

    @Bean
    public Person person(){
        return new Person(1,"張三","male");
    }
}

MainTest.classxml

package com.lee;

import com.lee.bean.Person;
import com.lee.config.MainConfig;
import com.lee.config.MainConfig2;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {


    @Test
    public void test01(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig2.class);
        Person person1 = (Person) context.getBean("person");
        Person person2 = (Person) context.getBean("person");
        System.out.println("person1 == person2 : "+(person1==person2));
    }

}

結果:對象

person1 == person2 : true

二、原型-PROTOTYPE

MainConfig2.class接口

package com.lee.config;

import com.lee.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@ComponentScan(value = "com.lee")//包掃描
@Configuration//這是個配置類
public class MainConfig2 {

    @Scope(value = "prototype")
    @Bean
    public Person person(){
        return new Person(1,"張三","male");
    }
}

結果:

person1 == person2 : false

3、懶加載

單實例bean:默認在容器啓動的時候建立對象

懶加載:容器啓動不建立對象,等第一次調用的時候才建立對象

一、默認

MainConfig2.class

package com.lee.config;

import com.lee.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@ComponentScan(value = "com.lee")//包掃描
@Configuration//這是個配置類
public class MainConfig2 {

    @Scope(value = "prototype")
    @Bean
    public Person person(){
        return new Person(1,"張三","male");
    }
}

二、懶加載 lazy

MainConfig2.class

package com.lee.config;

import com.lee.bean.Person;
import org.springframework.context.annotation.*;

@ComponentScan(value = "com.lee")//包掃描
@Configuration//這是個配置類
public class MainConfig2 {

    @Lazy//懶加載
    @Scope(value = "prototype")
    @Bean
    public Person person(){
        return new Person(1,"張三","male");
    }
}

3、Conditional按條件註冊bean

按照必定的條件進行判斷,知足條件給容器中註冊bean

WindowsCondition.class

package com.lee.conditions;


import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class WindowsCondition implements Condition {


    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment environment = context.getEnvironment();
        String property = environment.getProperty("os.name");
        if(property.contains("Window")){
            return true;
        }
        return false;
    }
}

LinuxCondition.class

package com.lee.conditions;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class LinuxCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment environment = context.getEnvironment();
        String property = environment.getProperty("os.name");
        if(property.contains("linux")){
            return true;
        }
        return false;
    }
}

MainConfig2.class

package com.lee.config;

import com.lee.bean.Person;
import com.lee.conditions.LinuxCondition;
import com.lee.conditions.WindowsCondition;
import org.springframework.context.annotation.*;

@ComponentScan(value = "com.lee")//包掃描
@Configuration//這是個配置類
public class MainConfig2 {

//    @Lazy//懶加載
//    @Scope(value = "prototype")
    @Bean
    public Person person(){
        return new Person(1,"張三","male");
    }


    @Conditional({WindowsCondition.class})
    @Bean("bill")
    public Person person01(){
        return new Person(2,"bill Gates","male");
    }

    @Conditional(LinuxCondition.class)
    @Bean("linus")
    public Person person02(){
        return new Person(3,"linus","male");
    }
}

MainTest.class

public class MainTest {

    @Test
    public void test02(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig2.class);
        ConfigurableEnvironment environment = context.getEnvironment();
        String property = environment.getProperty("os.name");
        System.out.println("===>"+property);
        String[] beanNamesForType = context.getBeanNamesForType(Person.class);
        for(String bean : beanNamesForType){
            System.out.println(bean);
        }
    }
}

結果:

===>Windows 10
person
bill

在Run/Debug Configurations中加入環境變量

-Dos.name=linux

結果:

===>Linux
person
linus

@Conditional不只能夠標註在方法method上,也能夠標註在類class上,這個類中全部bean註冊才能被生效

相關文章
相關標籤/搜索