4. Spring - IOC - 組件的作用域、懶加載、條件判斷

系列篇幅

作用域

參數 字符方式 說明
SCOPE_SINGLETON singleton 單實例的(默認值)
ioc容器啓動會調用方法創建對象放到ioc容器中
以後每次獲取就是直接從容器(map.get())中拿
SCOPE_PROTOTYPE prototype 多實例的
ioc容器啓動並不會去調用方法創建對象放在容器中
每次獲取的時候纔會調用方法創建對象
SCOPE_REQUEST request 同一次請求創建一個實例
SCOPE_SESSION session 同一個session創建一個實例

xml中 - 任選一

<bean id="person" class="com.atguigu.bean.Person" scope="prototype" >
  <property name="age" value="18"></property>
  <property name="name" value="zhangsan"></property>
</bean>

代碼中 - 任選一

@Configuration
public class MainConfig {
    @Bean
    @Scope("prototype")
    public Person person(){
        System.out.println("創建Person");
        return new Person("張三", 18);
    }
}

使用

public class MainTest {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
		System.out.println("ioc容器創建完成....");
		Object bean = applicationContext.getBean("person");
		Object bean2 = applicationContext.getBean("person");
		System.out.println(bean == bean2);
	}
}

輸出

ioc容器創建完成....
創建Person
創建Person
false

懶加載

懶加載只針對單實例時有效,多實例調用時才創建

@Lazy
@Bean
public Person person(){
  System.out.println("給容器中添加Person..");
  return new Person("張三", 18);
}

使用

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("ioc容器創建完成....");
Object bean = applicationContext.getBean("person");
Object bean2 = applicationContext.getBean("person");
System.out.println(bean == bean2);

輸出

ioc容器創建完成....
給容器中添加Person..
true

Conditional

@Conditional 註解按照一定的條件進行判斷,滿足條件給容器中註冊bean

根據不同系統,給予不同Person

/**
 * 判斷是否linux系統
 */
public class LinuxCondition implements Condition {

    /**
     * ConditionContext:判斷條件能使用的上下文(環境)
     * AnnotatedTypeMetadata:註釋信息
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //1、能獲取到ioc使用的beanfactory
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        //2、獲取類加載器
        ClassLoader classLoader = context.getClassLoader();
        //3、獲取當前環境信息
        Environment environment = context.getEnvironment();
        //4、獲取到bean定義的註冊類
        BeanDefinitionRegistry registry = context.getRegistry();
        String property = environment.getProperty("os.name");
        //5. 可以判斷容器中的bean註冊情況,也可以給容器中註冊bean
        boolean definition = registry.containsBeanDefinition("person");
        // 返回
        return property.contains("linux");
    }

}
/**
 * 判斷是否windows系統
 */
public class WindowsCondition implements Condition {

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

}

不同系統不同返回

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
String[] names = applicationContext.getBeanDefinitionNames();
Stream.of(names).forEach(System.out::println);

我當前是mac,返回

person2

作用於類上

作用於類上,這樣只有windows纔會加載bean

@Conditional({WindowsCondition.class})
@Configuration
public class MainConfig {
    @Bean
    public Person person(){
        System.out.println("創建Person");
        return new Person("張三", 18);
    }
}

查看

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
String[] names = applicationContext.getBeanDefinitionNames();
Stream.of(names).forEach(System.out::println);

返回:因爲我是mac沒有返回加載的person

關於測試

可以運行jar包時候,指定以下環境變量

java -jar test.jar -Dos.name=window
發佈了193 篇原創文章 · 獲贊 35 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章