你不知道的Spring——实用特性(二)

这次记录的主要是一些标签的特殊用法和不常用标签用法及使用场景
1.alias标签
平常设置bean的别名的方法是:
<bean id="spring" class="cn.wxdl.Spring"/>
<alias name="spring" alias="spring1,spring2,spring3"/>
看见源码中有一段这样的解析
List<String> aliases = new ArrayList<String>();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);//MULTI_VALUE_ATTRIBUTE_DELIMITERS = ",; "
aliases.addAll(Arrays.asList(nameArr));
}
发现还可以设置成这样
<bean id="spring" name="spring1,,; spring2,; spring3" class="cn.wxdl.Spring"/>
另外还发现一段逻辑
String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
if (logger.isDebugEnabled()) {
logger.debug("No XML 'id' specified - using '" + beanName +"' as bean name and " + aliases + " as aliases");
}
}
如果id不存在,还会自动用aliases第一个补充,也就是:
<bean name="spring,; spring1,; spring2,; spring3" class="cn.wxdl.Spring"/>
实现一样的逻辑
2.depends-on标签
spring默认是懒加载,使用的时候才会去实例化bean对象。对于我们开发,有时候需要确定加载顺序。例如:A Bean要正常使用,需要B Bean的服务先一步实例化。此时可如下配置:
<bean id="A" class="cn.wxdl.A" depends-on="B"/>
<bean id="B" class="cn.wxdl.B" />
当然也可以配置多个需要预先实例化的Bean
<bean id="A" class="cn.wxdl.A" depends-on="B,; C,; D"/>
实例化顺序为B->C-D-A
不允许循环依赖(depends),如下:
<bean id="A" class="cn.wxdl.A" depends-on="B"/>
<bean id="B" class="cn.wxdl.B" depends-on="C"/>
3.lookup-method
这个标签不常用,但在设计可插拔的
功能上很合适
使用方法,示例如下:
定义接口
public interface Tool {
public void used();
}
接口实现
public class Qizi implements Tool{
@Override
public void used() {
System.out.println("我正在使用起子");
}
}
lookup-method配置方法
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd" >
<beans>
<bean id="doWork" class="bean.DoWork">
<lookup-method name="whatIused" bean="qizi"/>
</bean>
<bean id="qizi" class="bean.Qizi"/>
</beans>
</beans>
public class LookupTest {
public static void main(String[] args) {
ApplicationContext bf = new ClassPathXmlApplicationContext("beanFactoryTest.xml");
DoWork tool = (DoWork)bf.getBean("doWork");
tool.used();
}
}
如果不再使用Qizi,我们可以实现其他的Tool,在xml中重新配置
示例如下:
public class Cuizi implements Tool {
@Override
public void used() {
System.out.println("我正在用锤子");
}
}
使用新的实现类Cuizi替换
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd" >
<beans>
<bean id="doWork" class="bean.DoWork">
<lookup-method name="whatIused" bean="cuizi"/>
</bean>
<bean id="cuizi" class="bean.Cuizi"/>
<bean id="qizi" class="bean.Qizi"/>
</beans>
</beans>
4.replace-method
可以在运行时用新的方法替换现有的方法
使用示例如下:
public class ChangeMethod {
public void changeMe(){
System.out.println("请替换这个方法");
}
}
待替换的类需要实现接口org.springframework.beans.factory.support.MethodReplacer
public class TestMethodReplacer implements MethodReplacer{
@Override
public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {
System.out.println("我替换了原来的方法");
return null;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd" >
<beans>
<bean id="changeMethod" class="bean.ChangeMethod">
<replaced-method name="changeMe" replacer="replace"/>
</bean>
<bean id="replace" class="bean.TestMethodReplacer"></bean>
</beans>
</beans>
测试替换结果
public class ReplacedTest {
public static void main(String[] args) {
ApplicationContext bf = new ClassPathXmlApplicationContext("beanFactoryTest.xml");
ChangeMethod tool = (ChangeMethod)bf.getBean("changeMethod");
tool.changeMe();
}
}