Spring注解(@Scope @Lazy @Condition

2019-03-21  本文已影响0人  Godlike_4029

@Scope注解指定注入容器的bean是单实例还是多实例的,默认情况下是单实例

@Configuration
public class MainConfig2 {
    @Scope("prototype")
    @Bean("person")
    public Person person(){

        return new Person("zhangsan",22);
    }
}

ConfigurableBeanFactory#SCOPE_PROTOTYPE
@see ConfigurableBeanFactory#SCOPE_SINGLETON
@see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST request
@see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION sesssion@return
@Scope:调整作用域
prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。
每次获取的时候才会调用方法创建对象;
singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。
以后每次获取就是直接从容器(map.get())中拿,
request:同一次请求创建一个实例
session:同一个session创建一个实例
对比Spring xml 配置

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

@Scope("prototype") 指定多实例测试代码

   @Test
    public void test2(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);

//        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
//        for (String beanDefinitionName : beanDefinitionNames) {
//            System.out.println(beanDefinitionName);
//        }

        System.out.println("ioc容器创建完成");
        Object person = applicationContext.getBean("person");
        System.out.println(person);
        Object person1 = applicationContext.getBean("person");
        System.out.println(person1);

        System.out.println(person==person1);

    }

测试结果如下(每次获取bean,都会创建一个新的对象)

ioc容器创建完成
Person constructor....
Person [name=zhangsan, age=22, nickName=null]
Person constructor....
Person [name=zhangsan, age=22, nickName=null]
false

Process finished with exit code 0

懒加载:@Lazy
单实例bean:默认在容器启动的时候创建对象;
懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;

@Configuration
public class MainConfig2 {

    @Scope("singleton")
    @Lazy
    //@Scope("prototype")
    @Bean("person")
    public Person person(){
        return new Person("zhangsan",22);
    }
}

@Conditional({Condition}) : 按照一定的条件进行判断,满足条件给容器中注册bean,Spring 底层大量使用的一个注解 可以标在类上,方法上

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    Class<? extends Condition>[] value();
}

向容器中注入 bean

@Configuration
public class MainConfig2 {

    @Scope("singleton")
    @Lazy
    //@Scope("prototype")
    @Bean("person")
    public Person person(){

        return new Person("zhangsan",22);
    }

    @Bean("linux")
    public Person person01(){
        return new Person("Tom",10);
    }

    @Bean("windows")
    public Person person02(){
        return new Person("Jack",30);
    }

}

案例:如果当前系统的是Linux就注入 bean(linux),是windows就注入 bean(windows)

public class LinuxCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        // TODO是否linux系统

        //1、能获取到ioc使用的beanfactory
        ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
        //2、获取类加载器
        ClassLoader classLoader = conditionContext.getClassLoader();
        //3、获取当前环境信息
        Environment environment = conditionContext.getEnvironment();
        //4、获取到bean定义的注册类
        BeanDefinitionRegistry registry = conditionContext.getRegistry();

        String property = environment.getProperty("os.name");

        //可以判断容器中的bean注册情况,也可以给容器中注册bean
        boolean definition = registry.containsBeanDefinition("person");
        if(property.contains("linux")){
            return true;
        }

        return false;
    }
}
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("Windows")){
            return true;
        }
        return false;
    }

}
@Configuration
public class MainConfig2 {

    @Scope("singleton")
    @Lazy
    //@Scope("prototype")
    @Bean("person")
    public Person person(){

        return new Person("zhangsan",22);
    }

    @Conditional(LinuxCondition.class)
    @Bean("linux")
    public Person person01(){
        return new Person("linus",10);
    }

    @Conditional(WindowsCondition.class)
    @Bean("windows")
    public Person person02(){
        return new Person("bill",30);
    }

}
@Test
    public void test3(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);

        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();

        //获取系统当前环境
        Environment environment = applicationContext.getEnvironment();
        String property = environment.getProperty("os.name");
        System.out.println(property);

        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }

        Map<String, Person> beansOfType = applicationContext.getBeansOfType(Person.class);
        System.out.println(beansOfType);

    }
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
person
windows
Person constructor....
{person=Person [name=zhangsan, age=22, nickName=null], windows=Person [name=bill, age=30, nickName=null]}

Process finished with exit code 0

可以看到 由于是Windows环境,bean(Linux) 并没有注入到容器中

//类中组件统一设置。满足当前条件,这个类中配置的所有bean注册才能生效;
@Conditional({WindowsCondition.class})
@Configuration
public class MainConfig2 {

    @Scope("singleton")
    @Lazy
    //@Scope("prototype")
    @Bean("person")
    public Person person(){

        return new Person("zhangsan",22);
    }
  ........
}
上一篇下一篇

猜你喜欢

热点阅读