4. Spring - IOC - 组件的作用域、懒加载、条件判断

系列篇幅

作用域

参数字符方式说明
SCOPE_SINGLETONsingleton单实例的(默认值)
ioc容器启动会调用方法创建对象放到ioc容器中
以后每次获取就是直接从容器(map.get())中拿
SCOPE_PROTOTYPEprototype多实例的
ioc容器启动并不会去调用方法创建对象放在容器中
每次获取的时候才会调用方法创建对象
SCOPE_REQUESTrequest同一次请求创建一个实例
SCOPE_SESSIONsession同一个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
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页