Bean的作用域
作用域 singleton
单例(默认值), 在每个SpringIOC容器中,一个bean定义对应一个对象实例
prototype
一个bean定义对应多个对象实例
request
在一次HTTP请求中,一个bean定义对应一-个实例,即每次HTTP请求将会有各自的bean实例,它们依据某个bean定义创建而成。该作用域仅在基于Web的Spring ApplicationContext的情况下有效。
session
在一个HTTP Session 中,一个bean定义对应一个实例。该作用域仅在基于Web 的SpringApplicationContext的情况下有效
global session
在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于Web的Spring ApplicationContext的情况下有效
注解形式
配置文件形式
1 2 3 4 5 6 7 8 <bean id ="student" class =" com.ehshyee.entity.Student" > value :简单类型 <property name ="stuNo" value ="1" > </property > <property name ="stuName" value ="张三" > </property > <property name ="stuAge" value ="23" > </ property> ref:其他类型 <property name ="address" ref ="myaddress" > </property > </bean >
分别对其获取两个学生 查看是否为同一个
1 2 3 Student stul = (Student) context.getBean(S:"student" ) ;Student stu2 = (Student) context.getBean(S:"student" ) ;System.out.println(stul =stu2) ;
均返回true
在xml中scope默认是singleton
可改为prototype
。
1 <bean id ="student" class =" top.ehshyee.entity.Student" scope ="prototype" >
改后返回false
注解中添加
对于实例产生的时机
一些测试
1 2 3 4 5 6 7 8 9 10 public Student () { System.out.println("student无参构造" ) ; } public Student (int stuNo, String stuName, int stuAge) { super (); this .stuNo = stuNo; this .stuName = stuName; this .stuAge = stuAge; }
singleton | prototype
执行时机(产生bean的时机) :
(default )singleton:容器在初始化时,就会创建对象(唯一的一个);以后再getBean时,不再产生新的bean.singleton也支持延迟加载(懒加载) :在第一次使用时产生。
prototype:容器在初始化时,不创建对象;只是在每次使用时(每次从容器获取对象时,context.getBean(Xxxx)),再创建对象,并且,每次getBean()都会创建一个新的对象。
延迟加载(注解形式)
条件注解 –>SpringBoot 可以让某一个Bean在某些条件下加入Ioc容器,其他情况下不加IoC容器。
a.准备bean
1 2 3 4 5 6 7 public interface Car {} public class EnegerCar implements Car {} public class OilCar implements Car {}
b.增加条件Bean:给每个Bean设置条件,必须实现Condition接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class OilCarCondition implements Condition { @Override public boolean matches (ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { Environment environment=conditionContext.getEnvironment(); String carType=environment.getProperty("car.type" ); return carType.contains("oil" ); } } public class EnergyCarCondition implements Condition { @Override public boolean matches (ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { Environment environment = conditionContext.getEnvironment(); String carType = environment.getProperty("car.type" ); return carType.contains("energy" ); } }
c.根据条件加入IOC容器
1 2 3 4 5 6 7 8 @Bean @Conditional (OilCarCondition.class)public Car oilCar () {return new oilCar ()} @Bean @Conditional (EnergyCarCondition.class)public Car energyCar () {return new EnergyCar ()}
测试
在VM option中添加参数为oil-Dcar.type=oil
1 2 3 4 5 6 7 public static void testAnnotation { ApplicationContext context = new AnnotationConfigApplicationContext (MyConfig.class); String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String name : beanDefinitionNames) { System.out.println(name) ; }}
给IoC加入Bean的方法 注解:
三层组件: 扫描器+三层注解
非三层组件@Confiquration:
@Bean+返回值
@import
FactoryBean(工厂 Bean)
@import使用: ①直接编写到@Import中
1 2 3 @Confiquration @Import ( {Apple.class, Banana.class} )
②自定义ImportSelector接口的实现类,通过selectimports方法实现,方法的返回值就是要纳入IoC容器的Bean),并告知系统自己编写的实现类。
1 2 3 4 5 6 public class MyImportSelector implements ImportSelector { @Override public String[] selectImports (AnnotationMetadata importingClassMetadata) { return new String []{ "top.eshyee.entity.Apple" , "top.eshyee.entity.Banana" } }
1 @Import(Orage.class,MyImportSelector.class)
③编写ImportBeanDefinitionRegistrar接口的实现类,重写方法
1 2 3 4 5 6 7 8 public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions (AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { BeanDefinition beanDefinition new RootBeanDefinition (Orange.class) ; registry.registerBeanDefinition("myorange" ,beanDefinition); } }
1 @Import(MyImportBeanDefinitionRegistrar)
FactoryBean(工厂 Bean) 写注册类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class MyEactoryBean implements FactoryBean { @Override public Object getobject () throws Exception { return new Apple ; } @Override public Class<?> getobjectType() { return Apple.class ; } @Override public boolean isSingleton () { return true ; } }
bean中实现
1 2 3 4 @Bean public FactoryBean<Apple> myFactoryBean () { return new MyFactoryBean () ; }
拿myFactoryBean中的值
1 2 3 4 object obj (context. getBean( "myFactoryBean" ) ); System.out.println(obj) ; object obj (context. getBean( "&myFactoryBean" ) ); System.out.println(obj) ;
&
:不加&获取的是最内部真实的Apple;