Spring再次学习(2)

2019-08-16 11:55:13来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

Spring再次学习(2)

时隔一年多,在掌握了Spring、SpringBoot、SpringCloud之后

我再次回头,重新学习Spring框架

 

Spring中的Bean默认是单实例的:

package org.dreamtech.config;

import org.dreamtech.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类
 */
@Configuration
public class MainConfig {

    @Bean("person")
    public Person person() {
        return new Person("李四", 20);
    }

}
package org.dreamtech.test;

import org.dreamtech.config.MainConfig;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class IOCTest {
    @Test
    public void test() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        Object bean1 = applicationContext.getBean("person");
        Object bean2 = applicationContext.getBean("person");
        System.out.println(bean1.equals(bean2));
        System.out.println(bean1 == bean2);
    }
}

 

这里打印的是:

true
true

 

可以使用注解设置多实例:

    @Bean("person")
    @Scope(scopeName = "prototype")
    public Person person() {
        return new Person("李四", 20);
    }

测试后打印:

false
false

 

单实例下Bean在IOC容器启动时候就创建了,只创建一次

多实例下Bean在使用到的时候才会创建,每次获取都会创建

 

由于单实例在容器启动就创建了,而有时候我们需要在第一次获取时再创建Bean:

使用懒加载(延迟加载)

    @Bean("person")
    @Lazy
    public Person person() {
        System.out.println("创建Bean");
        return new Person("李四", 20);
    }
package org.dreamtech.test;

import org.dreamtech.config.MainConfig;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class IOCTest {
    @Test
    public void test() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        System.out.println("容器创建完成");
        System.out.println("准备获取Bean");
        Object bean = applicationContext.getBean("person");
        System.out.println(bean);
    }
}

 

打印如下:

容器创建完成
准备获取Bean
创建Bean
Person{name='李四', age=20}

 

按照条件给Spring中注册Bean:

满足条件才会注册Bean,不满足则不注册,而这也在SpringBoot底层应用到

package org.dreamtech.config;

import org.dreamtech.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类
 */
@Configuration
public class MainConfig {

    @Bean("zhangsan")
    public Person person1() {
        return new Person("张三", 17);
    }

    @Bean("lisi")
    public Person person2() {
        return new Person("李四", 20);
    }

    @Bean("wangwu")
    public Person person3(){
        return new Person("王五",18);
    }

}
package org.dreamtech.test;

import org.dreamtech.bean.Person;
import org.dreamtech.config.MainConfig;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.Map;

public class IOCTest {
    @Test
    public void test() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        Map<String,Person> beanNamesForType = applicationContext.getBeansOfType(Person.class);
        System.out.println(beanNamesForType);
    }
}

打印

{zhangsan=Person{name='张三', age=17}, lisi=Person{name='李四', age=20}, wangwu=Person{name='王五', age=18}}

 

现在想要做到,Windows系统创建张三,Linux系统创建李四

从Spring环境中获取操作系统版本:

    @Test
    public void test() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        String OsName = environment.getProperty("os.name");
        System.out.println(OsName);
        Map<String,Person> beanNamesForType = applicationContext.getBeansOfType(Person.class);
        System.out.println(beanNamesForType);
    }

 

打印

Windows 10
{zhangsan=Person{name='张三', age=17}, lisi=Person{name='李四', age=20}, wangwu=Person{name='王五', age=18}}

 

如何根据条件创建呢?使用Conditional注解

public @interface Conditional {
    Class<? extends Condition>[] value();
}

 

发现注解需要创建一个实现Condition接口的类

package org.dreamtech.condition;

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

/**
 * 判断是否是Linux系统
 */
public class LinuxCondition implements Condition {
    /**
     * 匹配
     * @param conditionContext 判断条件能使用的上下文环境
     * @param annotatedTypeMetadata 标注Conditional注解的方法的其他注解
     * @return boolean
     */
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        Environment environment = conditionContext.getEnvironment();
        String OSName = environment.getProperty("os.name");
        return OSName.contains("Linux");
    }
}
package org.dreamtech.condition;

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

/**
 * 判断是否是Windows系统
 */
public class WindowsCondition implements Condition {
    /**
     * 匹配
     * @param conditionContext 判断条件能使用的上下文环境
     * @param annotatedTypeMetadata 标注Conditional注解的方法的其他注解
     * @return boolean
     */
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        Environment environment = conditionContext.getEnvironment();
        String OSName = environment.getProperty("os.name");
        return OSName.contains("Windows");
    }
}
package org.dreamtech.config;

import org.dreamtech.bean.Person;
import org.dreamtech.condition.LinuxCondition;
import org.dreamtech.condition.WindowsCondition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类
 */
@Configuration
public class MainConfig {

    @Conditional({WindowsCondition.class})
    @Bean("zhangsan")
    public Person person1() {
        return new Person("张三", 17);
    }

    @Conditional({LinuxCondition.class})
    @Bean("lisi")
    public Person person2() {
        return new Person("李四", 20);
    }

    @Bean("wangwu")
    public Person person3() {
        return new Person("王五", 18);
    }

}
package org.dreamtech.test;

import org.dreamtech.bean.Person;
import org.dreamtech.config.MainConfig;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.Map;

public class IOCTest {
    @Test
    public void test() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        Map<String,Person> beanNamesForType = applicationContext.getBeansOfType(Person.class);
        System.out.println(beanNamesForType);
    }
}

打印:由于我的操作系统是Windows而不是Linux,所以打印张三不打印李四

{zhangsan=Person{name='张三', age=17}, wangwu=Person{name='王五', age=18}}

 

这里只是简单地使用了一个方法,实际上还可以做很多的操作:

        conditionContext.getEnvironment();
        conditionContext.getBeanFactory();
        conditionContext. getClassLoader();
        conditionContext.getResourceLoader();
        conditionContext.getRegistry();

 

Conditional注解不只是可以用在方法上,也可以用在类上

@Configuration
@Conditional({LinuxCondition.class})
public class MainConfig {

.......................

}

 

这种情况直接打印为空,因为没有一个Bean符合条件

 


原文链接:https://www.cnblogs.com/xuyiqing/p/11289661.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Java equal() 和 == 详细分析

下一篇:Java开发笔记(一百三十三)Swing的菜单