spring 第5天不同作用域的bean,注入Field,方法返回值

[b]协调作用域不同步的bean[/b]
问题是;当一个singleton的bean依赖一个prototype的bean的时候,会产生不同步的现象
解决问题的方法
1:放弃部分依赖,当singleton的bean每次需要prototype的bean 的时候,主动向容器中访问新的bean. 这样会造成 与springAPI 严重耦合
2.利用方法注入 (我们用这种)

//singleton bean
package cn.sh.springmvc.model;

import cn.sh.springmvc.model.interfaces.Axe;
import cn.sh.springmvc.model.interfaces.Person;

/**
* 不同作用于的 依赖与协同
* 采用方法注入新的Bean ,解决:singleton Bean中使用个prototypeBean 的问题
* @author Bin
*
*/
public abstract class Japanese implements Person {

//定义一个方法 让spring 跟我们实现,这样就能保证每次都是新的对象
public abstract Axe getAxe();

@Override
public void useAxe() {
System.out.println("正在使用"+getAxe()+"劈柴");
System.out.println(getAxe().chop());
}

}


//prototype bean
package cn.sh.springmvc.model;

import cn.sh.springmvc.model.interfaces.Axe;


public class StoneAxe implements Axe {

private String name;

public StoneAxe() {
System.out.println("石头初始化StoneAxe");
}
@Override
public String chop() {
// TODO Auto-generated method stub
return name+"石斧看柴慢";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}


}

配置lookup-method 让spring帮我们实现

<!-- 不同作用于的协同工作 -->
<bean id="stoneAxe1" class="cn.sh.springmvc.model.StoneAxe" scope="prototype">
<property name="name" value="磨过"/>
</bean>
<bean id="japanese" class="cn.sh.springmvc.model.Japanese" scope="singleton">
<lookup-method name="getAxe" bean="stoneAxe1"/>
</bean>




//测试 不同作用域的Bean相互依赖后出现的工作不协调问题
@Test
public void test17() {
AbstractApplicationContext act=new ClassPathXmlApplicationContext("classpath*:applicationContent.xml");
Japanese p=act.getBean("japanese",Japanese.class);
p.useAxe();
p.useAxe();
System.out.println(p.getAxe()==p.getAxe());
}


[b]深入理解依赖配置关系[/b]
前面都是bean之间的依赖,下面讲的是,bean依赖bean之间的属性,方法返回值,field值

在spring配置文件中使用xml元素进行配置,实际上是让spring执行相应的java代码
例如:
1.使用<bean>元素,就是让spring执行无参数构造函数
2.使用<property> 就是让spring执行setter方法
但是java程序还有可能还有其他语句,调用getting,调用普通方法,访问类或者对象的file,spring也为这种语句提供利配置的语法

3.调用getter方法:使用 PropertyPathFactoryBean
4.访问类或对象的Field值,使用FieldRetrievingFactoryBean
5.调用普通方法:使用MethodInvokingFactoryBean
由此可见,spring可以然我们不写java代码就可以实现java编程,只要使用合适XML 语法进行配置,spring就可通过反射执行任意的底层java代码.

[b]注入其他bean的属性值[/b]

<!-- 注入其他Bean的属性 -->
<bean id="chinese1" class="cn.sh.springmvc.model.Chinese">
<property name="axe" ref="stoneAxe"/>
</bean>
<!-- Bean 之间的属性依赖 -->
<bean id="chinese2" class="cn.sh.springmvc.model.Chinese">
<property name="axe">
<!--注意这里,并不是bean的ID,而是属性的表达式 -->
<bean id="chinese1.axe" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
</property>
</bean>

[b]将其他bean的属性值定义成一个bean[/b]

<!-- 指定一个Bean实例的属性定义为一个 Bean -->
<bean id="pro_stoneAxe" class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetBeanName" value="chinese1"/>
<property name="propertyPath" value="axe"/>
</bean>
<bean id="stone_name" class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetBeanName" value="chinese1"/>
<property name="propertyPath" value="axe.name"/>
</bean>

<bean id="chinese_list" class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetBeanName" value="chinese"/>
<property name="propertyPath" value="schools"/>
</bean>

<bean id="chinese_list_ele" class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetBeanName" value="chinese"/>
<property name="propertyPath" value="schools[0]"/>
</bean>

<bean id="chinese_map_ele" class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetBeanName" value="chinese"/>
<property name="propertyPath" value="entrySet[0]"/>
</bean>

<!-- 注意有些集合不是 有序的,如果集合没有采用泛型定义,注意返回的类型 -->
<bean id="chinese_set_ele_str" class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetBeanName" value="chinese"/>
<property name="propertyPath" value="axes[0]"/>
</bean>

<bean id="chinese_set_ele_obj" class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetBeanName" value="chinese"/>
<property name="propertyPath" value="axes[1]"/>
</bean>

<!-- 采用嵌套bean -->
<bean id="new_stone_name" class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetObject">
<bean class="cn.sh.springmvc.model.SteelAxe">
<property name="name" value="打磨过的"/>
</bean>
</property>
<property name="propertyPath" value="name"/>
</bean>



//测试 Bean实例属性之间的依赖,以及将一个实例Bean的属性定义成一个Bean
//注意 org.springframework.beans.factory.config.PropertyPathFactoryBean
//如果将对象的属性定义成Bean 的时候,要指定targetBeanName 和 propertyPath 两个属性
@Test
public void test18() {
AbstractApplicationContext act=new ClassPathXmlApplicationContext("classpath*:applicationContent.xml");
//属性之间的传递
Chinese c2=act.getBean("chinese2",Chinese.class);
System.out.println(c2.getAxe().chop());

//属性的对象
Axe a=act.getBean("pro_stoneAxe",Axe.class);
System.out.println(a.chop());

//属性对象的属性
String name=act.getBean("stone_name",String.class);
System.out.println(name);

//对象的 list
List<String> schools=act.getBean("chinese_list",List.class);
System.out.println(schools.get(0));

//对象的 list 中的元素
String schools_Name=act.getBean("chinese_list_ele",String.class);
System.out.println(schools_Name);

//对象的 map 中的元素
/*Set<Map.Entry<String,Object>> set=act.getBean("chinese_map_ele",Set.class);
for(Iterator<Map.Entry<String,Object>> it=set.iterator();it.hasNext();){
Map.Entry<String,Object> entry=it.next();
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}*/
Map.Entry<String,Object> entry=act.getBean("chinese_map_ele",Map.Entry.class);
System.out.println(entry.getKey());
System.out.println(entry.getValue());


String set1=act.getBean("chinese_set_ele_str",String.class);
System.out.println(set1);

SteelAxe obj=act.getBean("chinese_set_ele_obj",SteelAxe.class);
System.out.println(obj.chop());

//使用内嵌Bean的属性
String stone_Name=act.getBean("new_stone_name",String.class);
System.out.println(stone_Name);
}


[b]注入其他bean的Field值[/b]

<!-- 注入其他Bean的Field的值 -->
<!-- 将 java.sql.Connection.TRANSACTION_SERIALIZABLE属性值给 user的age属性-->
<bean id="user1" class="cn.sh.springmvc.model.User">
<property name="age">
<bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"/>
</property>
</bean>
<!--将 java.sql.Connection.TRANSACTION_SERIALIZABLE 定义成一个bean -->
<bean id="theAge" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<property name="targetClass" value="java.sql.Connection"/>
<property name="targetField" value="TRANSACTION_SERIALIZABLE"/>
</bean>
<!-- 如果 字段为静态 的,还可以简写 -->
<bean id="theAge1" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<property name="staticField" value="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>
</bean>


//测试 注入其他Bean的Field字段值
//FieldRetrievingFactoryBean targetClass targetField staticField
@Test
public void test19() {
AbstractApplicationContext act=new ClassPathXmlApplicationContext("classpath*:applicationContent.xml");
User u= act.getBean("user1",User.class);
System.out.println(u.getAge());

Integer level=act.getBean("theAge",Integer.class);
System.out.println(level);
Integer level1=act.getBean("theAge1",Integer.class);
System.out.println(level1);
}



[b]注入其他bean的方法返回值[/b]

<!-- 注入 其他Bean的方法返回值 -->
<bean id="valueGenerate" class="cn.sh.springmvc.model.ValueGenerator"/>
<bean id="user2" class="cn.sh.springmvc.model.User">
<property name="age">
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="valueGenerate"/>
<property name="targetMethod" value="getValue"/>
</bean>
</property>
</bean>

<!-- 如果是静态方法 -->
<bean id="user3" class="cn.sh.springmvc.model.User">
<property name="age">
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<!-- 如果是静态方法.可以不用 targetObject -->
<property name="targetClass" value="cn.sh.springmvc.model.ValueGenerator"/>
<property name="targetMethod" value="getStaticVal"/>
</bean>
</property>
</bean>

<!-- 如果方法方法存在重载 指定参数-->
<bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="java.lang.System"/>
<property name="targetMethod" value="getProperties"/>
</bean>

<bean id="java_version" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="java.lang.System"/>
<property name="targetMethod" value="getProperty"/>
<property name="arguments">
<list>
<value>java.version</value>
</list>
</property>
</bean>

<bean id="mth_stoneAxe_sft" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="cn.sh.springmvc_java.factory.AxeFactory"/>
<property name="targetMethod" value="getAxe"/>
<property name="arguments">
<list><value>stone</value></list>
</property>
</bean>
<!-- 如果是静态的method 可以省略 targetClass -->
<bean id="mth_steelAxe_sft" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="cn.sh.springmvc_java.factory.AxeFactory.getAxe"/>
<property name="arguments">
<list><value>steel</value></list>
</property>
</bean>
<!-- 使用嵌套bean -->
<bean id="mth_people_sft" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject">
<bean class="cn.sh.springmvc_java.factory.PeopleFactory"/>
</property>
<property name="targetMethod" value="getPeople"/>
<property name="arguments">
<list><value>chin</value></list>
</property>
</bean>


//测试 注入其他Bean的方法返回值
//MethodInvokingFactoryBean targetClass targetMethod
@Test
public void test20() {
AbstractApplicationContext act=new ClassPathXmlApplicationContext("classpath*:applicationContent.xml");
User u= act.getBean("user2",User.class);
System.out.println(u.getAge());

User u1=act.getBean("user3",User.class);
System.out.println(u1.getAge());

Properties syspro=act.getBean("sysProps",Properties.class);
System.out.println(syspro.getProperty("java.version"));

System.out.println(act.getBean("java_version"));

System.out.println(System.getProperty("java.version"));

Axe saxe=act.getBean("mth_stoneAxe_sft",Axe.class);
System.out.println(saxe.chop());

Axe saxe1=act.getBean("mth_steelAxe_sft",Axe.class);
System.out.println(saxe1.chop());


People p=act.getBean("mth_people_sft",People.class);
System.out.println(p.sayHello("admin"));

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值