spring-第五篇之spring容器中的bean
1、bean的基本定义和bean别名
2、容器中bean的作用域
singleton:单例模式,在整个spring IoC容器中,singleton作用域的bean将只生成一个实例。
prototype:每次通过容器的getBean()方法获取prototype作用域的bean时,都将产生一个新的bean实例。
request:对于一次HTTP请求,request作用域的bean将只生成一个实例,这意味着,在同一次HTTP请求内,程序每次请求该bean,得到的总是同一个实例。只有在Web应用中使用spring时,该作用域才真正的有效。
session:对于一次HTTP会话,sesion作用域的bean将只生成一个实例,这意味着,在同一次HTTP会话内,程序每次请求该bean,得到的总是同一个实例。只有在Web应用中使用spring时,该作用域才真正的有效。
global session:每个全局的HTTP Session对应一个bean实例。在典型的情况下,仅在使用portlet context的时候有效。只有在Web应用中使用spring时,该作用域才真正的有效。
比较常用的是singleton和prototype。对于singleton作用域的bean,每次请求该bean都将获得相同的实例。容器负责跟踪bean实例的状态,负责维护bean实例的生命周期行为;对于prototype作用域的bean,程序每次请求该id的bean,spring都会新建一个bean实例,然后返回给程序。这种情况下,spring容器仅仅使用new关键字创建bean实例,一旦创建成功,容器就不再跟踪实例,也不会维护bean实例的状态。
如果不指定bean的作用域,spring容器默认使用singleton作用域。
spring配置文件通过scope属性指定bean的作用域,该属性可以接受singleton、prototype、request、session、globalSession五个值。
3、request作用域
4、session作用域
5、配置依赖
在依赖注入方式总结的时候,我们总结类两种依赖注入方式:
设值注入:通过<property.../>元素驱动spring执行setter方法。
构造注入:通过<constructor-arg.../>元素驱动spring执行带参数的构造器。
对这两种设值方式的底层实现模拟:
Person.java
package com.lfy.bean;public class Person {private String name;private int age;/*** 定义一个无参构造器*/public Person() {}/*** 定义一个带参构造器* @param name* @param age 构造器使用Integer,class字段属性是int*/public Person(String name,Integer age) {this.name=name;this.age=age;}public void sayHello(String name) {System.out.println(name+",Hello.Nice to see you.");}public void selfIntroduction() {System.out.println("Hello,I am "+name+".I am "+age);} }
ReflexTest.java
package com.lfy.main;import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;import com.lfy.bean.Person;/*** java反射的应用* @author lfy**/ public class ReflexTest {public static void main(String[] args) {/*** spring设值注入底层代码实现简单例子*/try {Class targetClass=Class.forName("com.lfy.bean.Person");try {Object bean=targetClass.newInstance();try {String name="lfy";Method targetMethod=targetClass.getMethod("sayHello", name.getClass());//这里演示没有使用Person.name的setter方法,但道理一样的try {targetMethod.invoke(bean, name);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();}} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}} catch (ClassNotFoundException e) {e.printStackTrace();}/*** spring构造注入底层实现简单例子*/try {Class targetClass=Class.forName("com.lfy.bean.Person");try {String param1="lfy";Integer param2=21;Constructor targetCtr=targetClass.getConstructor(param1.getClass(),param2.getClass());try {//以指定构造器创建bean实例Object bean=targetCtr.newInstance(param1,param2);Person p=(Person)bean;p.selfIntroduction();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();}} catch (ClassNotFoundException e) {e.printStackTrace();}} }
运行结果:
6、自动装配注入合作者bean(即:被依赖bean),缺点是明显降低了配置文件的可读性
<beans.../>元素下是default-autowire属性,<bean.../>元素下是autowire,它们可接受的值有:
no:不使用自动装配。bean依赖必须通过ref元素定义,是默认配置。
byName:根据setter方法名进行自动装配。spring容器查找容器中的全部bean,找出其id与setter方法名去掉set前缀,并小写字母后同名的bean来完成注入。如果没有匹配到任何bean实例,spring不会进行任何注入。
byType:根据setter方法的形参类型来自动装配。spring容器查找容器中的全部bean,如果正好有一个bean类型与setter方法的形参类型匹配,就自动注入这个bean;如果找到多个这样的bean,就抛出一个异常;如果没有找到这样的bean,则什么都不发生,setter方法不会被调用。
constructor:与byType类似,区别是用于自动匹配构造器的参数。如果容器不能恰好找到一个与构造器参数类型匹配的bean,则会抛出一个异常。
autodetect:spring容器根据bean内部结构,自行决定使用constructor或byType策略。如果找到一个默认的构造器,那么就会应用byType策略。
7、注入嵌套bean
如果某个bean所依赖的bean不想被spring容器直接访问,则可以使用嵌套bean。
将<bean.../>配置成<property.../>或<constructor-args.../>的子元素,则该bean仅作为设值注入、构造注入的参数,该bean就叫做嵌套bean。由于容器不能获取嵌套bean,故无需配置嵌套bean的id属性。
8、注入集合值
如果要被注入的值是集合类型,无论设值注入,还是构造注入,则可以使用集合元素<list.../>、<set.../>、<map.../>和<props.../>分别来设值类型为List、Set、Map和Properties的集合参数值。
看个例子:
beans.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- spring配置文件的根元素,使用spring-beans-4.0.xsd语义约束 --> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://www.springframework.org/schema/beans"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"><bean id="stoneAxe" class="com.lfy.impl.StoneAxe"/><bean id="steelAxe" class="com.lfy.impl.SteelAxe"/><bean id="chinese" class="com.lfy.impl.Chinese"><!-- List<String> --><property name="schools"><list><!-- 每个value、ref、bean...都配置一个List元素 --><value>小学</value><value>中学</value><value>大学</value></list></property><!-- Map --><property name="scores"><map><!-- 每个entry代表一个key-value对 --><entry key="数学" value="87"/><entry key="英语" value="89"/><entry key="语文" value="82"/></map></property><!-- Map<String,Axe> --><property name="phaseAxes"><map><entry key="原始社会" value-ref="stoneAxe"/><entry key="农业社会" value-ref="steelAxe"/></map></property><!-- Properties --><property name="health"><props><!-- 每个prop元素配置一个属性项,其中key指定属性名 --><prop key="血压">正常</prop><prop key="血压">175</prop></props></property><!-- Set --><property name="axes"><set><!-- 每个value、ref、bean...都配置一个Set元素 --><value>普通的字符串</value><bean class="com.lfy.impl.SteelAxe"/><ref bean="stoneAxe"/><list><value>20</value><!-- 再次为List配置一个Set集合作为元素 --><set><value type="int">30</value></set></list></set></property><!-- String[] --><property name="books"><list><!-- 每个value、ref、bean...都配置一个数组元素 --><value>疯狂java讲义</value><value>疯狂Android讲义</value><value>轻量级java ee企业应用实战</value></list></property></bean> </beans>
stoneAxe.java
package com.lfy.impl;import com.lfy.bean.Axe;public class StoneAxe implements Axe {@Overridepublic String chop() {return "石斧砍柴好慢";}}
steelAxe.java
package com.lfy.impl;import com.lfy.bean.Axe;public class SteelAxe implements Axe {@Overridepublic String chop() {return "钢斧砍柴真快";}}
Chinese.java
package com.lfy.impl;import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set;import com.lfy.bean.Axe; import com.lfy.bean.Person;public class Chinese implements Person {private Axe axe;private List<String> schools;private Map scores;private Map<String,Axe> phaseAxes;private Properties health;private Set axes;private String[] books;public Chinese() {System.out.println("spring实例化主调bean:Chinese实例...");}//设值注入所需的setter方法public void setAxe(Axe axe) {this.axe=axe;}public void setSchools(List schools) {this.schools=schools;}public void setScores(Map scores) {this.scores=scores;}public void setPhaseAxes(Map<String,Axe> phaseAxes) {this.phaseAxes=phaseAxes;}public void setHealth(Properties health) {this.health=health;}public void setAxes(Set axes) {this.axes=axes;}public void setBooks(String[] books) {this.books=books;}@Overridepublic void useAxe() {//调用axe的chop()方法//表明Person对象依赖于axe对象 System.out.println(axe.chop());}public void test() {System.out.println(schools);System.out.println(scores);System.out.println(phaseAxes);System.out.println(health);System.out.println(axes);System.out.println(Arrays.toString(books));}}
springTest.java
package com.lfy.main;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import com.lfy.impl.Chinese;public class SpringTest {public static void main(String[] args) {ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");Chinese c=ctx.getBean("chinese", Chinese.class);c.test();}}
运行结果:
9、组合属性的设值
举个例子,猫组合了一个主人相关的属性:
Chinese.java
package com.lfy.impl;import com.lfy.bean.Person;public class Chinese implements Person {//姓名private String name;public String getName() {return name;}public void setName(String name) {this.name=name;} }
Cat.java
package com.lfy.impl;import com.lfy.bean.Animal;public class Cat implements Animal {//猫的主人是个中国人private Chinese chinese=new Chinese();public Chinese getChinese() {return chinese;} }
beans.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- spring配置文件的根元素,使用spring-beans-4.0.xsd语义约束 --> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://www.springframework.org/schema/beans"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"><bean id="cat" class="com.lfy.impl.Cat"><property name="chinese.name" value="lfy"/> </bean> </beans>
SpringTest.java
package com.lfy.main;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import com.lfy.impl.Cat; import com.lfy.impl.Chinese;public class SpringTest {public static void main(String[] args) {ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");Cat c=ctx.getBean("cat", Cat.class);System.out.println("猫的主人的名字叫做:"+c.getChinese().getName());}}
运行结果:
转载于:https://www.cnblogs.com/ZeroMZ/p/11324701.html
spring-第五篇之spring容器中的bean相关推荐
- Spring注解驱动开发第7讲——如何按照条件向Spring容器中注册bean?这次我懂了!!
写在前面 当bean是单实例,并且没有设置懒加载时,Spring容器启动时,就会实例化bean,并将bean注册到IOC容器中,以后每次从IOC容器中获取bean时,直接返回IOC容器中的bean,而 ...
- java servlet 部署到tomcat_如何把spring boot项目部署到tomcat容器中
把spring-boot项目按照平常的web项目一样发布到tomcat容器下 一.修改打包形式 在pom.xml里设置 war 二.移除嵌入式tomcat插件 在pom.xml里找到spring-bo ...
- FastJson序列化Json自定义返回字段,普通类从spring容器中获取bean
前言: 数据库的字段比如:price:1 ,返回需要price:1元. 这时两种途径修改: ① 比如sql中修改或者是在实体类转json前遍历修改. ②返回json,序列化时候修改.用到的是fastj ...
- SpringBoot 之 普通类获取Spring容器中的bean
SpringBoot 之 普通类获取Spring容器中的bean 转载于:https://www.cnblogs.com/lwmp/p/8892927.html
- Servlet自动注入Spring容器中的Bean解决方法
Servlet自动注入Spring容器中的Bean解决方法 参考文章: (1)Servlet自动注入Spring容器中的Bean解决方法 (2)https://www.cnblogs.com/jank ...
- 【SpringBoot】在普通类中获取spring容器中的bean
这段时间公司搞封闭开发,做一个联通总部的客服系统项目,是基于springboot的.在开发工程中遇到一个页面datagrid数据排序的功能,因为有多个表的数据都要用到排序功能,于是我就写了一个排序功能 ...
- Spring中将BeanDefinition注册到IOC容器中
Spring中将BeanDefinition注册到IOC容器中 XML配置元信息 <bean name="-" - /> 注解: @Bean,@Component,@I ...
- 在普通类中获取spring容器中的bean
在普通类中获取spring容器中的bean 1.工具类 package com.itheima.hchat.util;import org.springframework.beans.BeansExc ...
- Spring容器中的Bean是否会被GC呢?
Spring容器中的Bean是否会被GC呢?最近好几次被校招实习生问及,对于初学者来说,这应该是一个有意思的问题,鉴于此,笔者顺便写个这个文档. 1.Spring容器中Bean的作用域 当通过Spri ...
- Spring注解驱动开发第10讲——在@Import注解中使用ImportBeanDefinitionRegistrar向容器中注册bean
写在前面 在前面的文章中,我们学习了如何使用@Import注解向Spring容器中导入bean,不仅可以使用@Import注解快速向容器中导入bean,也可以在@Import注解中使用ImportSe ...
最新文章
- Linux之rpm包管理
- 【C#】允许泛型方法T返回空值Null
- 清除浏览器缓存之后为什么还是显示旧的html页面_H5缓存机制浅析-移动端Web加载性能优化...
- python stm32-【ST开发板评测】使用Python来开发STM32F411
- spirng 如何把404转到特定的页面展示
- 20220208--CTF刷题记录--6道简单的MISC题目
- labelimg如何调整框的颜色_P图改字:来看看吧!教你如何用PS墙壁发光灯泡广告文字图片...
- axure原件 总是丢失_Axure实现提示文本单击显示后自动消失的效果
- 高性能缓存服务器Varnish架构配置
- 女子驾驶蔚来汽车被迫停留长安街超1小时 官方回应:司机连续误操作
- 单位阶跃信号是周期信号吗_vivoS7e是5G手机吗-支持5G吗-5G信号怎么样
- 不同业务场景下如何进行数据库水平切分?
- 读取P12格式证书的密钥
- 突破10万高并发的nginx性能优化经验(含内核参数优化)...
- java中char占几bits_char类型占几个字节
- Disease Ontology:人类疾病分类数据库
- 安全测试者偏爱的安全测试工具
- mysql 分表联合查询_解决分表后联合查询
- android录制视频设置分辨率,Android录制视频的全面屏适配
- urlwrite------url地址重写