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. EasyUi 表格自适应宽度

    第一次接触EasyUi想要实现表格宽度自适应,网上找了好多文章,都没有实现,有网友实现了可是自己看不懂.可能是太简单高手都懒得分享,现在把自己的理解和实现记录一下,希望可以帮到向自己一样的菜鸟,步骤如 ...

  2. 20191119PHP.class类练习

    <?phpclass person{ public $name; private $age; public $sex; const WOMAN=0; const MAN=1; function ...

  3. 浅谈使用canvas绘制多边形

    本文主要使用坐标轴的使用来绘制多边形,点位则都是在y轴上寻找,这种方法能够更好的理解图形与修改. //id为html里canvas标签的属性id: //x,y为坐标轴的起始位置,因为canvas默认坐 ...

  4. WEB服务动静结合

    基本介绍 1)WEB服务仅能处理静态请求,如果处理动态请求则需要对应的动态资源服务软件,即:应用程序服务软件 2)常见的应用服务软件有:PHP.Java.Python等 3)问题:WEB服务如何与外部 ...

  5. mysql查询每个部门/班级前几名

    Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id . +----+-------+--------+--------------+ | I ...

  6. visual studio 中添加命令行参数

    argc argv

  7. 为什么需要bootloader

    本文链接:https://blog.csdn.net/u012351051/article/details/50557899 受单片机和ARM7等小型CPU设备编程思维的影响,开始对嵌入式linux和 ...

  8. 去除重复嵌套的html标签函数

    去除重复嵌套的html标签 function strip_multi_tags($str, $tag = 'div'){ preg_match_all('/<'.$tag.'>|<\ ...

  9. What are the differences between an LES-SGS model and a RANS based turbulence model?

    The biggest difference between LES and RANS is that, contrary to LES, RANS assumes that \(\overline{ ...

  10. ht-4 hashmap特性

    一.hashmap底层原理: hashmap调用默认构造方法会产生一个默认底层是长度为16的Entry数组,首先调用key的hasCode()方法来得到一个整数, int hash = hash(ke ...