简介
- Spring中最基础且最重要的两个包是【org.springframework.beans】和【org.springframework.context】,这两个包为控制反转和依赖注入提供了基础。
BeanFactory
- 提供了配置框架和基本的功能
ApplicationContext - 在BeanFactory的基础上提供更强的功能。
- 【ApplicationContext】是【BeanFactory】的子类
BeanFactory 和 BeanDefinitions 基础
BeanFactory
- 实例化,配置和管理众多Bean的容器。
实例化方式
String[] xmlFile = new String[]{"applicationContext.xml"};
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlFile);
ClassPathResource res = new ClassPathResource("applicationContext.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
一个最基本的BeanFactory配置由一个或多个它所管理的Bean定义组成。
BeanDefinitions
- Bean定义包括以下内容
classname bean的真正实现类
Bean行为配置元素 声明在容器中的行为方式
构造函数参数和新创建bean所需要属性
相关的其他Bean
Bean的构造方式
- 通过构造函数创建Bean
<bean id="exampleBean" class="examples.ExampleBean" />
<bean name="anotherExample" class="examples.ExampleBeanTwo" />
- 通过静态工厂方法创建Bean
<bean id="exampleBean" class="examples.ExampleBean2" factory-method="createInstance"/>
- 通过实例工厂方法创建bean
<bean id="myFactoryBean" class="..."/>
<bean id="exampleBean" factory-bean="myFactoryBean" factory-method="createInstance" />
singleton的使用与否
- Beans默认是singleton
- singleton的Bean在所有请求都只会返回这一个唯一特定的实例
- prototype则每个请求都会创建一个实例
属性,合作者,自动装配和依赖检查
依赖注入和控制反转的两种形式
- 基于setter的依赖注射,spring提倡该种形式
- 基于构造函数的依赖注射
深入Bean属性和构造函数参数
idref
<bean id="theTargetBean" class="...">
</bean>
<bean id="theClientBean" class="...">
<property name="targetName">
<value>theTargetBean</value>
</property>
</bean>
等价于
<bean id="theTargetBean" class="...">
</bean>
<bean id="theClientBean" class="...">
<property name="targetName">
<idref bean="theTargetBean"/>
</property>
</bean>
- 使用idref会使spring在部署时就验证其他的Bean是否存在,而一般只会在Spring实例化时才去验证。
- 如果被引用的bean是在同一个xml文件中而且bean的名称是bean的id,那么就可以使用local属性。这个可以让xml文件解析时就验证。
<property name="targetName">
<idref local="theTargetBean"/>
</property>
ref元素
- 允许指向的bean可以在同一个BeanFactory/ApplicationContext(无论是否是同一个XML文件)中。bean属性的值可以同目标Bean的id属性相同,也可以是name属性中任何一个值相同。
<ref name="someBean"/>
- 用local指定目标bean可以利用XML解析器的能力在同一个文件中验证XML id引用。local属性的值必须与目标bean的id属性一致。
<ref local="someBean"/>
- 用parent属性指定目标bean允许引用当前Beanfactory的服BeanFactory。parent属性的值可以同目标Bean的id属性相同,也可以是name属性中任何一个值相同。
<ref parent="someBean"/>
方法注入
Lookup方法注入
<bean id="singleShotHelper" class="..." singleton="false">
</bean>
<bean id="myBean" class="...">
<lookup-method name="createSingleShotHelper" bean="singleShotHelper">
<property>
...
</property>
</bean>
任意方法的替换
<bean id="myValueCalculator" class="...">
<replace-method name="computeValue" replacer="replacementComputeValue">
<arg-type>String</arg-type>
</replace-method>
</bean>
<bean id="replacementComputeValue" class="..."></bean>
depends-on
- 用来初始化这个元素之前强制多个beans初始化
<bean id="beanOne" class="ExampleBean" depends-on="manager">
<property name="manager">
<ref lcoal="manager" />
</property>
</bean>
Bean处理和BeanWrapper
- BeanWrapper支持设置和提取属性以及嵌套属性。
public class SysUser implements Serializable {
private String uuid; //uuid
private String userName; //用户名
public void setUuid(String uuid){
this.uuid = uuid;
}
public String getUuid(){
return this.uuid;
}
public void setUserName(String userName){
this.userName = userName;
}
public String getUserName(){
return this.userName;
}
}
SysUser user = new SysUser();
BeanWrapper wrapper = new BeanWrapperImpl(user);
wrapper.setPropertyValue("userName","Hello World");
System.out.println(user.getUserName());
System.out.println(wrapper.getPropertyValue("userName"));
PropertyDescriptor的使用
SysUser user = new SysUser();
user.setUuid("test");
PropertyDescriptor descriptor = new PropertyDescriptor("uuid",SysUser.class);
Object test = descriptor.getReadMethod().invoke(user);
descriptor.getWriteMethod().invoke(user,"2");
System.out.println(test);
System.out.println(user.getUuid());