spring 框架说明文档学习记录(3.3)
来源:互联网 发布:淘宝网店如何起步 编辑:程序博客网 时间:2024/06/06 00:40
三.三 依赖和配置详情
简单值
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <!-- results in a setDriverClassName(String) call --> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mydb"/> <property name="username" value="root"/> <property name="password" value="masterkaoli"/></bean>
java.util.properties实例(spring通过PropertyEditor机制,将value元素间的文本转换为java.util.Properties实例)
<bean id="mappings" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <!-- typed as a java.util.Properties --> <property name="properties"> <value> jdbc.driver.className=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mydb </value> </property></bean>
idref元素
idref元素,只是简单的在将其他bean的id(string类型,不是引用)传给<constructor-arg/>或<property/>元素时进行错误验证。
<bean id="theTargetBean" class="..."/><bean id="theClientBean" class="..."> <property name="targetName"> <idref bean="theTargetBean" /> </property></bean>
等同于
<bean id="theTargetBean" class="..." /><bean id="client" class="..."> <property name="targetName" value="theTargetBean" /></bean>
第一种写法要优于第二种,第一种可以在部署时验证引用的bean实际存在
idref的通常使用场景为ProxyFactoryBean定义中的AOP 拦截器。使用idref防止拦截器id的拼写错误
注意:4.0的bean xsd中,不再支持idref的local属性,使用idref的bean属性替代
对其他beans的引用
<ref bean="someBean"/>
ref中parent属性,引用父级容器中的bean
<!-- in the parent context --><bean id="accountService" class="com.foo.SimpleAccountService"><!-- insert dependencies as required as here --></bean>
<!-- in the child (descendant) context --><bean id="accountService" <!-- bean name is the same as the parent bean -->class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <ref parent="accountService"/> <!-- notice how we refer to the parent bean --> </property><!-- insert other configuration and dependencies as required here --></bean>
注意:ref元素中的local属性在beans的xsd 4.0后不再支持,使用bean属性替代
内部bean
<bean id="outer" class="..."> <!-- instead of using a reference to a target bean, simply define the target bean inline --> <property name="target"> <bean class="com.example.Person"> <!-- this is the inner bean --> <property name="name" value="Fiona Apple"/> <property name="age" value="25"/> </bean> </property></bean>内部bean,不需要定义id或name,如果定义了,容器也不会作为id使用。同时容器忽略scope标记,内部bean是匿名的并随外部bean的创建而创建。
集合
我们在<list/>,<set/>,<map/>和<props/>元素中,设置java的集合类型参数List,Set,Map和Properties
<bean id="moreComplexObject" class="example.ComplexObject"> <!-- results in a setAdminEmails(java.util.Properties) call --> <property name="adminEmails"> <props> <prop key="administrator">administrator@example.org</prop> <prop key="support">support@example.org</prop> <prop key="development">development@example.org</prop> </props> </property> <!-- results in a setSomeList(java.util.List) call --> <property name="someList"> <list> <value>a list element followed by a reference</value> <ref bean="myDataSource" /> </list> </property> <!-- results in a setSomeMap(java.util.Map) call --> <property name="someMap"> <map> <entry key="an entry" value="just some string"/> <entry key ="a ref" value-ref="myDataSource"/> </map> </property> <!-- results in a setSomeSet(java.util.Set) call --> <property name="someSet"> <set> <value>just some string</value> <ref bean="myDataSource" /> </set> </property></bean>
集合合并
<beans> <bean id="parent" abstract="true" class="example.ComplexObject"> <property name="adminEmails"> <props> <prop key="administrator">administrator@example.com</prop> <prop key="support">support@example.com</prop> </props> </property> </bean> <bean id="child" parent="parent"> <property name="adminEmails"> <!-- the merge is specified on the child collection definition --> <props merge="true"> <prop key="sales">sales@example.com</prop> <prop key="support">support@example.co.uk</prop> </props> </property> </bean><beans>
注意merge="true"的使用,child中adminEmails的值为合并后的结果
administrator=administrator@example.comsales=sales@example.comsupport=support@example.co.uk
null和空字符串
<bean class="ExampleBean"> <property name="email"> <null/> </property></bean>
<bean class="ExampleBean"> <property name="email" value=""/></bean>
使用p-命名空间简化xml
简单值
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"> <bean name="classic" class="com.example.ExampleBean"> <property name="email" value="foo@bar.com"/> </bean> <bean name="p-namespace" class="com.example.ExampleBean" p:email="foo@bar.com"/></beans>beans引用
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"> <bean name="john-classic" class="com.example.Person"> <property name="name" value="John Doe"/> <property name="spouse" ref="jane"/> </bean> <bean name="john-modern" class="com.example.Person" p:name="John Doe" p:spouse-ref="jane"/> <bean name="jane" class="com.example.Person"> <property name="name" value="Jane Doe"/> </bean></beans>
使用c-命名空间简化xml
与p-命名空间对应<property>一样,c-命名空间对应<constructor-arg/>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:c="http://www.springframework.org/schema/c"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="bar" class="x.y.Bar"/> <bean id="baz" class="x.y.Baz"/> <!-- traditional declaration --> <bean id="foo" class="x.y.Foo"> <constructor-arg ref="bar"/> <constructor-arg ref="baz"/> <constructor-arg value="foo@bar.com"/> </bean> <!-- c-namespace declaration --> <bean id="foo" class="x.y.Foo" c:bar-ref="bar" c:baz-ref="baz" c:email="foo@bar.com"/></beans>
当构造函数参数名称不可用(一般不使用debug进行编译),我们可以使用参数顺序赋值
<!-- c-namespace index declaration --><bean id="foo" class="x.y.Foo" c:_0-ref="bar" c:_1-ref="baz"/>
混合属性名称
<bean id="foo" class="foo.Bar"> <property name="fred.bob.sammy" value="123" /></bean>其中 bean foo有一个fred属性,fred有一个bob属性,bob有一个sammy属性,且sammy前各属性都不为空,否则抛出空指针异常
使用depends-on
depends-on属性,能够明确的强制一个或多个bean在当前bean之前进行初始化。
<bean id="beanOne" class="ExampleBean" depends-on="manager"/><bean id="manager" class="ManagerBean" />依赖多个bean
<bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao"> <property name="manager" ref="manager" /></bean><bean id="manager" class="ManagerBean" /><bean id="accountDao" class="x.y.jdbc.JdbcAccountDao" />懒加载bean
ApplicationContext默认立即加载bean以便提早发现问题。我们可以通过定义bean为懒加载来组织使用预加载。
<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/><bean name="not.lazy" class="com.foo.AnotherBean"/>
<beans default-lazy-init="true"><!-- no beans will be pre-instantiated... --></beans>
自动装配
自动装配功能有四个模式
no : 不使用自动装配
byName : 通过属性name绑定,spring寻找要自动装配的名称相同的bean,如果一个bean被设置为自动装配,它有一个master属性(和setMaster()方法),spring寻找一个名称为master的bean,并用它设置这个属性。
byType : 如果容器中有该类型的bean,则将该属性自动装配,如果有多个该类型属性,会报错,如果没有可匹配bean,什么都不做。
constructor : 与byType类似,在构造函数参数上使用。如果容器中没有构造函数参数类型的bean,会报致命错误。
避免bean使用自动装配
设置<bean/>的autowire-candidate属性为false
方法注入
在大部分应用场景中,容器中大部分都是单例的。当一个单例集成另一个单例或一个非单例集成另一个非单例时,我们一般将一个bean注册为另一个bean的属性。但是这会存在一个问题,假设单例A需要使用非单例B,某一个方法中调用。容器只能创建单例A一次,因此只能有一次设置其属性的机会。容器不能给单例A提供一个新的非单例B的实例。
一种解决方案是放弃部分控制反转,我们可以通过实现ApplicationContextAware创建一个与容器关联的bean A。
// a class that uses a stateful Command-style class to perform some processingpackage fiona.apple;// Spring-API importsimport org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;public class CommandManager implements ApplicationContextAware { private ApplicationContext applicationContext; public Object process(Map commandState) { // grab a new instance of the appropriate Command Command command = createCommand(); // set the state on the (hopefully brand new) Command instance command.setState(commandState); return command.execute(); } protected Command createCommand() { // notice the Spring API dependency! return this.applicationContext.getBean("command", Command.class); } public void setApplicationContext( ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; }}查找方法注入
public abstract class CommandManager { public Object process(Object commandState) { // grab a new instance of the appropriate Command interface Command command = createCommand(); // set the state on the (hopefully brand new) Command instance command.setState(commandState); return command.execute(); } // okay... but where is the implementation of this method? protected abstract Command createCommand();}
<!-- a stateful bean deployed as a prototype (non-singleton) --><bean id="command" class="fiona.apple.AsyncCommand" scope="prototype"> <!-- inject dependencies here as required --></bean><!-- commandProcessor uses statefulCommandHelper --><bean id="commandManager" class="fiona.apple.CommandManager"> <lookup-method name="createCommand" bean="command"/></bean>
当commandManager调用createCommand()时,会获得一个新的command实例
方法替换
public class MyValueCalculator { public String computeValue(String input) { // some real code... } // some other methods...}
/*** meant to be used to override the existing computeValue(String)* implementation in MyValueCalculator*/public class ReplacementComputeValue implements MethodReplacer { public Object reimplement(Object o, Method m, Object[] args) throws Throwable { // get the input value, work with it, and return a computed result String input = (String) args[0]; ... return ...; }}
<bean id="myValueCalculator" class="x.y.z.MyValueCalculator"> <!-- arbitrary method replacement --> <replaced-method name="computeValue" replacer="replacementComputeValue"> <arg-type>String</arg-type> </replaced-method></bean><bean id="replacementComputeValue" class="a.b.c.ReplacementComputeValue"/>
- spring 框架说明文档学习记录(3.3)
- spring 框架说明文档学习记录(1)
- spring 框架说明文档学习记录(2)
- spring 框架说明文档学习记录(3)
- spring 框架说明文档学习记录(3.1)
- spring 框架说明文档学习记录(3.2)
- spring 框架说明文档学习记录(3.4)
- spring 框架说明文档学习记录(3.5)
- spring 框架说明文档学习记录(3.6)
- spring 框架说明文档学习记录(3.7)
- Spring框架学习记录
- Spring-Validator 说明文档
- Spring-Validator 说明文档
- Spring说明文档翻译1——第一部分,spring框架预览
- spring框架说明
- Spring Framework 5.0.0.M3中文文档 翻译记录 Part I. Spring框架概览1-2.2
- Spring的定时器说明文档
- Spring Framework 中文说明文档
- Eclipse中SVN修改的*星号没了,解决方法
- 第八节:Array的遍历-转换以及-常规用法
- 来谈谈WebAssembly是个啥?为何说它会影响每一个Web开发者?
- 数据库泵(expdp/impdp)导入导出流程
- .NET插件技术-应用程序热升级
- spring 框架说明文档学习记录(3.3)
- Android 使用<layer-list>实现微信聊天输入框
- 求解强联通分量 tarjan算法
- phpnow简单链接数据库,打印代码
- 免索引邻接vs混合索引的图数据库
- Python自省(反射)指南
- 第九节:List-以及常规用法
- 深入tornado中的IOStream
- solr学习笔记(2)--solr搭建运行