1、@Scope设置组件作用域
@Configuration public class MainConfigA { @Bean("person") @Scope("singleton") public Person person(){ return new Person("张三丰",25); } }
public class JuitTest { @Test public void test(){ ApplicationContext context = new AnnotationConfigApplicationContext(MainConfigA.class); Person person = (Person)context.getBean("person"); Person person1 = (Person)context.getBean("person"); System.out.print(person == person1);//true } }
@Scope的值:
singleton:单例,默认值,每次都返回同一个对象,该对象是在容器启动的时候创建的,在使用的时候直接从容器中获取
prototype:多实例,每次都新创建一个对象,对象不会在容器启动时创建,而是在获取对象时创建,每次获取都创建一个新对象
request:一个请求范围内只创建一个对象
session:一次会话范围内只创建一个对象
2、@Lazy注解实现组件Bean的懒加载
单实例的Bean对象默认在容器启动的时候创建,可以设置懒加载使Bean的创建时机延后至第一次获取的时候创建和初始化,懒加载仅作用于单实例(singleton)的Bean
@Configuration @ComponentScan(value="com.bdm",useDefaultFilters = false,includeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM,classes = {BdmTypeFilter.class})}) public class MainConfig { @Bean @Lazy public Person person() { return new Person("lisi", 12); } }
3、@Conditional:按照条件动态注册Bean
public class JunitTest{ ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class); @Test public void test(){ Map<String,Person> persons = context.getBeansOfType(Person.class); System.out.print(persons); ConfigurableEnvironment environment = context.getEnvironment();//获取运行环境 String osName = environment.getProperty("os.name");//获取操作系统名称 } }
从这个测试类获取Bean的方式可以看出Spring容器是将Bean的对象放在了Map中,id为key、bean为value,另外通过ApplicationContenxt的对象可以获取当前的运行环境信息
使用@Conditional注解需自定义Condition:实现Condition接口
public class MyCondition implements Condition { // context:判断条件使用的上下文 // metaData:使用该注解的类的注解信息 public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // 运行时的信息以及环境变量、虚拟机的变量 Environment environment = context.getEnvironment(); String property = environment.getProperty("os.name"); if(property.toLowerCase().contains("Windows")) return true; // // 创建和装配Bean的工厂 // ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); // // 类加载器 // ClassLoader classLoader = context.getClassLoader(); // // 所有的bean定义都在该类中注册 也可以使用该对象注册Bean // BeanDefinitionRegistry registry = context.getRegistry(); return false; } }
容器Bean中使用@Conditional注解:使person类仅会在windows系统中才会创建
@Configuration public class MainConfig { @Bean @Conditional({MyCondition.class}) public Person person(){ return new Person("张三",12); } @Bean public Person person1(){ return new Person("李四",13); } }
@Conditional注解可以标注在类上也可以标注在方法上,作用的范围不同,标注在类上时影响整个容器Bean
@Conditional的值是一个Condition类型的数组,Condition是一个接口,有一个matches方法,该方法中有两个参数:
ConditionContext:通过此类型的参数可以获取运行环境、Bean工厂等信息
AnnotatedTypeMetadata:通过此类型的变量可获取到使用@Conditional注解的类的注解信息