`
Luob.
  • 浏览: 1589929 次
  • 来自: 上海
社区版块
存档分类
最新评论

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

阅读更多
协调作用域不同步的bean
问题是;当一个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());
	}


深入理解依赖配置关系
前面都是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代码.

注入其他bean的属性值
  <!-- 注入其他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>

将其他bean的属性值定义成一个bean
  <!-- 指定一个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);
	}


注入其他bean的Field值
<!-- 注入其他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);
	}
	


注入其他bean的方法返回值
 <!-- 注入 其他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"));
		
	}
分享到:
评论

相关推荐

    spring的bean作用域

    在Spring中,有五种主要的Bean作用域: 1. **Singleton作用域**: - Singleton是Spring默认的Bean作用域。这意味着,无论何时,只要Spring容器被初始化,它都会创建一个Bean实例,并将其缓存起来。后续对相同ID的...

    详解Spring中bean的作用域

    Prototype 作用域是指每一次请求(将其注入到另一个 bean 中,或者以程序的方式调用容器的 getBean()方法)都会产生一个新的 bean 实例,相当于一个 new 的操作。对于 prototype 作用域的 bean,有一点非常重要,那...

    Spring 的bean的作用域总结

    Spring 的bean的作用域总结,详细的总结了 Spring 的bean的作用域

    详解Spring中Bean的生命周期和作用域及实现方式

    Spring中Bean的生命周期和作用域及实现方式 Spring是一个非常流行的Java应用程序框架,它提供了一个灵活的机制来管理Bean的生命周期和作用域。Bean的生命周期和作用域是Spring框架中两个非常重要的概念,它们决定了...

    Spring容器中Bean的作用域编程开发技术共3页.pd

    同时,合理使用依赖注入可以帮助管理不同作用域Bean之间的关系。 在编程开发中,Spring提供了多种API和注解来声明和控制Bean的作用域。例如,使用`@Scope`注解可以明确指定Bean的作用域,如`@Scope("prototype")`。...

    spring Bean的作用域之间有什么区别1

    Spring Bean 的作用域之间有什么区别:Bean的作用域: 可以通过scope 属性来指定bean的作用域 ①singleton: 默认值。当IOC容器

    Spring实战之Bean的作用域singleton和prototype用法分析

    在Spring框架中,Bean的作用域是决定如何管理和创建Bean实例的关键概念。本篇文章将深入探讨两种主要的作用域:singleton和prototype,并通过实例分析其用法和注意事项。 首先,`singleton`是Spring默认的作用域,...

    关于spring boot中几种注入方法的一些个人看法

    @Bean 可以使用在方法上,以便将该方法的返回值转换为一个 Spring bean。 在 Spring Boot 中,以上几种注入方法都是非常重要的,它们可以帮助我们在编写 Spring Boot 应用程序时,使代码更加简洁、灵活和可维护。

    Spring定义bean的三种方式和自动注入

    这种方式需要Bean有对应的setter方法,以便Spring进行依赖注入。 ```xml &lt;bean id="student" class="test.Student"&gt; 张三"/&gt; &lt;/bean&gt; &lt;bean id="teacher" class="test.Teacher"&gt; 李四"/&gt; &lt;/bean&gt; ``` 2....

    通过@Autowired注解注入bean的顺序,以及@bean注入.rar

    当我们在字段、构造函数、方法或方法参数上使用`@Autowired`时,Spring会自动查找与所需类型匹配的bean,并将其注入到相应的位置。如果找到多个匹配的bean,可以通过指定`@Qualifier`来明确选择一个特定的bean。默认...

    Spring框架中Bean的生命周期 Spring中Bean有几种作用域

    在Spring框架中,Bean的生命周期管理和作用域是其核心特性之一,它们对于理解Spring如何管理对象的创建、初始化、使用以及销毁至关重要。首先,我们来深入探讨Bean的生命周期。 Spring中的Bean生命周期主要分为两个...

    spring-aware接口实现与bean作用域(spring多容器层面)

    关于`bean的作用域`,Spring支持多种Bean的作用域,包括单例(Singleton)、原型(Prototype)、会话(Session)和请求(Request)。这些作用域定义了Bean的生命周期和创建行为: 1. **单例(Singleton)**:默认...

    spring bean 的作用域(scope)

    spring bean 的作用域(scope), SPringle bean的作用域

    Spring Bean的作用域.docx

    Spring提供了五种不同的Bean作用域,每种都有其特定的使用场景和行为。 1. **Singleton作用域**:这是Spring的默认作用域,意味着无论何时从容器中请求一个特定的Bean,都会返回同一个实例。在配置文件中,可以使用...

    spring bean的生命周期

    3. **作用域** - **Singleton**:Spring容器中只会存在一个Bean实例,所有对Bean的请求都会返回同一个实例。 - **Prototype**:每次请求都会创建一个新的Bean实例。 - **Request**:在Web应用中,每个HTTP请求...

    Spring中Bean的作用域

    NULL 博文链接:https://huangminwen.iteye.com/blog/1486717

    Spring实战之Bean的作用域request用法分析

    主要介绍了Spring实战之Bean的作用域request用法,结合实例形式分析了spring中Bean的request作用域相关使用技巧与操作注意事项,需要的朋友可以参考下

    JSP 中Spring Bean 的作用域详解

    Bean元素有一个scope属性,用于定义Bean的作用域,该属性有如下五个值: 1&gt;singleton: 单例模式,在整个spring IOC容器中,单例模式作用域的Bean都将只生成一个实例。一般Spring容器默认Bean的作用域为singleton ...

    spring依赖注入bean

    **Spring 依赖注入 (DI) 与 Bean** Spring 框架的核心特性之一就是依赖注入(Dependency Injection,简称 DI),这是一种设计模式,它允许我们控制组件之间的耦合,而不是让组件自行创建它们所依赖的对象。这有助于...

Global site tag (gtag.js) - Google Analytics