问题是;当一个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相互依赖后出现的工作不协调问题 @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()); }
深入理解依赖配置关系
前面都是bean之间的依赖,下面讲的是,bean依赖bean之间的属性,方法返回值,field值
在spring配置文件中使用xml元素进行配置,实际上是让spring执行相应的java代码 例如: 1.使用元素,就是让spring执行无参数构造函数 2.使用 就是让spring执行setter方法 但是java程序还有可能还有其他语句,调用getting,调用普通方法,访问类或者对象的file,spring也为这种语句提供利配置的语法 3.调用getter方法:使用 PropertyPathFactoryBean 4.访问类或对象的Field值,使用FieldRetrievingFactoryBean 5.调用普通方法:使用MethodInvokingFactoryBean 由此可见,spring可以然我们不写java代码就可以实现java编程,只要使用合适XML 语法进行配置,spring就可通过反射执行任意的底层java代码.
注入其他bean的属性值
将其他bean的属性值定义成一个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 Listschools=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 > set=act.getBean("chinese_map_ele",Set.class); for(Iterator > it=set.iterator();it.hasNext();){ Map.Entry entry=it.next(); System.out.println(entry.getKey()); System.out.println(entry.getValue()); }*/ Map.Entry 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); }
注入其他bean的Field值
//测试 注入其他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); }
注入其他bean的方法返回值
java.version
stone
steel
chin
//测试 注入其他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")); }