Spring注解开发2--@Scope @Lazy @Conditional

目录

1.@Scope 设置组件作用域

2. @Lazy  bean的懒加载

3.@Conditional  按照条件注册bean


1.@Scope 设置组件作用域

  singleton    默认值单例,在IOC容器启动的时候就创建了,只会创建一个
  prototype   多实例,调用一次创建一次

       配置类:         

@Configuration
public class MainConfig {
  
    @Scope("prototype")
    @Bean(value = "user")
    public  User user(){
        System.out.println("加载了...."); //这个可以用来测试容器的创建时机,单例的时候,在没有调用,但是容器启动了就会打印这个结果(总共只有一次),而多例是在调用一次就打一次。
        return  new User("vison",23);
    }
}

测试类:

public class TestAnotation {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        User user1 = configApplicationContext.getBean(User.class);
        User user2 = configApplicationContext.getBean(User.class);
        System.out.println(user1==user2);  //这里是false
    }
}

如上两个测试类:当scope为prototype时候,那么产生的bean是多例的,所以测试的结果就是false;

                             当scope为singleton时候,那么产生的bean是单例的,上面的结果就应该是true。

注意点:

         单例的bean的创建在容器启动的时候就创建好了,而多例是在调用一次才创建一次。

2. @Lazy  bean的懒加载

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

配置类:

@Configuration
public class MainConfig {

    @Lazy
    @Bean(value = "user")
    public  User user(){
        System.out.println("加载了....");
        return  new User("vison",23);
    }
}

测试类:

public class TestAnotation {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class);    
    /*  User user2 = configApplicationContext.getBean(User.class);
        System.out.println(user1);*/   
    }
}

如上面的测试,使用了@Lazy注解;当加载了IOC容器,user对象并不会创建,“加载了.....”不会打印,当打开下面的注释就会打印出来;如果去掉@Lazy注解,当加载IOC容器的时候,user对象就已经创建出来了,那么“加载了.....”会即刻打印出来。这就是懒加载。

3.@Conditional  按照条件注册bean

      按照一定条件进行判断,满足条件就给IOC容器注册bean

   作用在类上表示只有满足当前条件才会让当前类实例化,类中的方法才会可以使用

先看@Conditional源码:

@Target({ElementType.TYPE, ElementType.METHOD}) //可以作用于类上或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    Class<? extends Condition>[] value();  //这个表示参数是需要继承Condition的Class类型
}

在window环境下创建bean

例子1:

1. 创建一个条件的类

public class WindowsCondition implements Condition {
    //conditionContext 判断条件能使用的上下文
    //annotatedTypeMetadata 注释信息
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        //能获取到ioc使用到的beanFactory
        ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
        //获取到类加载器
        ClassLoader classLoader = conditionContext.getClassLoader();
        //获取到当前的环境,包括JVM等
        Environment environment = conditionContext.getEnvironment();
        //获取到bean定义注册类,所有的bean注册,查询,移出都是在BeanDefinitionRegistry中
        BeanDefinitionRegistry registry = conditionContext.getRegistry();
        ResourceLoader resourceLoader = conditionContext.getResourceLoader();

        String property = environment.getProperty("os.name");
        if (property.contains("Window")){
            return true;
        }
        return false;
    }
}

2.同理可以创建一个LinuxCondition实现Condition接口的条件类

3.配置类

@Configuration
public class MainConfig {

    @Bean(value = "user01")
    public  User user01(){
        return  new User("vison01",23);
    }

    @Conditional(WindowsCondition.class)
    @Bean(value = "windowUser")
    public  User user02(){
        return  new User("vison02",23);
    }

    @Conditional(LinuxCondition.class)
    @Bean(value = "LinuxUser")
    public  User user03(){
        return  new User("vison03",23);
    }
}

4.测试类

public class TestAnotation {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        String[] beanNames = configApplicationContext.getBeanNamesForType(User.class);
        for (String bean : beanNames){
            System.out.println(bean);
        }
    }
}

如果当前环境时window的话,结果只有   user01  和 windowUser  。

例子2:

 上面例子把条件放在类上

@Conditional(WindowsCondition.class)
@Configuration
public class MainConfig {

    @Bean(value = "user01")
    public  User user01(){
        return  new User("vison01",23);
    }
    
    @Bean(value = "user02")
    public  User user02(){
        return  new User("vison02",23);
    }

    @Bean(value = "user03")
    public  User user03(){
        return  new User("vison03",23);
    }
}

       这个表示只有满足上面的条件后才会注册这个配置中所有的bean,这里只有满足windowsCondition条件(window环境下)才会创建里面的user对象。反之其他环境一个bean都会注册。

猜你喜欢

转载自blog.csdn.net/weixin_40792878/article/details/82794123