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:一次会话范围内只创建一个对象
@Scope注解也可以在组件的类名上标注:
@Component
@Scope("prototype")
public class Person {
public Person() {
System.out.println("Person Constructor");
}
}
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 persons = context.getBeansOfType(Person.class);
System.out.print(persons);
ConfigurableEnvironment environment = context.getEnvironment();//获取运行环境
String osName = environment.getProperty("os.name");//获取操作系统名称
}
}
从这个测试类获取Bean的方式可以看出Spring容器是将Bean的对象放在了Map中,而且同一个类型的bean可能会有多个(id不同),id为key、bean为value,另外通过ApplicationContenxt的对象可以获取当前的运行环境信息,在调用context.getBeansOfType(Person.class)方法时会创建所有类型为Person的对象
使用@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注解的方法上,作用的范围不同,标注在类上时影响整个容器Bean
@Conditional的值是一个Condition类型的数组,Condition是一个接口,有一个matches方法,该方法中有两个参数:
ConditionContext:通过此类型的参数可以获取运行环境、Bean工厂等信息
AnnotatedTypeMetadata:通过此类型的变量可获取到使用@Conditional注解的类的注解信息