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 {

    @Override
public String chop() {
return "石斧砍柴好慢";
} }

steelAxe.java

package com.lfy.impl;

import com.lfy.bean.Axe;

public class SteelAxe implements Axe {

    @Override
public 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;
} @Override
public 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());
} }

运行结果:

spring-第五篇之spring容器中的bean的更多相关文章

  1. spring源码 — 二、从容器中获取Bean

    getBean 上一节中说明了容器的初始化,也就是把Bean的定义GenericBeanDefinition放到了容器中,但是并没有初始化这些Bean.那么Bean什么时候会初始化呢? 在程序第一个主 ...

  2. 【String注解驱动开发】如何按照条件向Spring容器中注册bean?这次我懂了!!

    写在前面 当bean是单实例,并且没有设置懒加载时,Spring容器启动时,就会实例化bean,并将bean注册到IOC容器中,以后每次从IOC容器中获取bean时,直接返回IOC容器中的bean,不 ...

  3. Spring第五篇

    在Spring第四篇中 我们主要介绍了set get的注入方式 在Spring第五篇中 我们主要介绍使用注解配置Spring 主要分为两个步骤 1 导包的同时引入新得约束 导包如下 1.1 重写注解代 ...

  4. 从Spring容器中获取Bean。ApplicationContextAware

    引言:我们从几个方面有逻辑的讲述如何从Spring容器中获取Bean.(新手勿喷) 1.我们的目的是什么? 2.方法是什么(可变的细节)? 3.方法的原理是什么(不变的本质)? 1.我们的目的是什么? ...

  5. String框架搭建的基本步骤,及从 IOC & DI 容器中获取 Bean(spring框架bean的配置)--有实现数据库连接池的链接

    Spring框架的插件springsource-tool-suite-3.4.0.RELEASE-e4.3.1-updatesite(是一个压缩包)导入步骤: eclipse->help-> ...

  6. Spring容器中的Bean

    一,配置合作者的Bean Bean设置的属性值是容器中的另一个Bean实力,使用<ref.../>元素,可制定一个bean属性,该属性用于指定容器中其他Bean实例的id属性 <be ...

  7. 在listener或者工具中使用spring容器中的bean实例

    在项目中经常遇见需要在Listener中或者工具中使用Spring容器中的bean实例,由于bean不能在stataic的类中使用. 介绍一种方式: public class SpringTool { ...

  8. FastJson序列化Json自定义返回字段,普通类从spring容器中获取bean

    前言: 数据库的字段比如:price:1 ,返回需要price:1元. 这时两种途径修改: ① 比如sql中修改或者是在实体类转json前遍历修改. ②返回json,序列化时候修改.用到的是fastj ...

  9. spring 在容器中一个bean依赖另一个bean 需要通过ref方式注入进去 通过构造器 或property

    spring  在容器中一个bean依赖另一个bean 需要通过ref方式注入进去 通过构造器 或property

  10. 7 -- Spring的基本用法 -- 5... Spring容器中的Bean;容器中Bean的作用域;配置依赖;

    7.5 Spring容器中的Bean 7.5.1 Bean的基本定义和Bean别名 <beans.../>元素是Spring配置文件的根元素,该元素可以指定如下属性: default-la ...

随机推荐

  1. Bootstrap真的总是好的吗

    原文地址:Bootstrap considered harmful 原文作者:Hidde de Vries 译文出自:neal 译者: Neal 个人主页:http://neal1991.python ...

  2. UVAlive 3485 Bridge(抛物线弧长积分)

    Bridge A suspension bridge suspends the roadway from huge main cables, which extend from one end of ...

  3. 自动化测试平台环境docker部署

    参考资料:testin云测 https://www.testin.cn接口自动化测试平台:http://120.79.232.23星云测试 http://www.threadingtest.com腾讯 ...

  4. 美国的科技公司是如何使用加密的DNS

    加密设备和“以隐私为中心”的提供商之间的DNS流量可以阻止某人窥探您的浏览器所指向的位置,或者使用DNS攻击将其发送到其他地方. 该网络中立性的死亡和法规对互联网服务供应商如何处理客户的网络流量的松动 ...

  5. 【leetcode】1091. Shortest Path in Binary Matrix

    题目如下: In an N by N square grid, each cell is either empty (0) or blocked (1). A clear path from top- ...

  6. ht-2 arrayList特性

    一.arrayList对象创建 当调用无参构造方法来构造一个ArrayList对象时,它会在内部分配一个初始大小为10的一个Object类型数组, 当添加的数据容量超过数组大小的时候,会产生一个新的数 ...

  7. nginx之访问静态文件

    如何配置nginx,访问服务器上的静态文件? 1.在目录/data/interface_test下创建静态文件queryAppData.json,内容如下: 如何访问该文件呢? 2.修改/usr/lo ...

  8. 彻底关闭Postprocess

    即使场景中没有postprocess volume,场景中也会有默认的postprocess volume效果,如果需要彻底关闭postprocess, 可以使用命令: sg.PostProcessQ ...

  9. C++ 运算符优先级顺序表 (最新/完整)

    优先级 运算符 结合律 助记 1 :: 从左至右 作用域 2 a++.a--.type().type{}.a().a[]...-> 从左至右 后缀自增减.函数风格转型.函数调用.下标.成员访问 ...

  10. ArayList的一些常用法<一> 转

    转:http://yy.azj.blog.163.com/blog/static/18508700320122893451389/ import java.util.ArrayList; import ...