前言

Spring最基础的功能就是一个bean工厂,所以本文讲解的是Spring生成bean的种种方法及细节,Spring配置文件的名字是bean.xml,定义几个类:

一个Person类:

public class Person
{
private String personName; // 人的名字
private int personAge; // 人的年龄 public Person(String personName, int personAge)
{
this.personName = personName;
this.personAge = personAge;
} public String getPersonName()
{
return personName;
} public void setPersonName(String personName)
{
this.personName = personName;
} public int getPersonAge()
{
return personAge;
} public void setPersonAge(int personAge)
{
this.personAge = personAge;
} public String toString()
{
return "personName = " + personName + ", personAge = " + personAge;
}
}

一个Family类,里面持有Person的引用:

public class Family
{
private Person person;
private String familyName; public Family(Person person, String familyName)
{
this.person = person;
this.familyName = familyName;
} public String toString()
{
return person.toString() + ", familyName = " + familyName;
}
}

一个单例类:

public class SingletonClass
{
private SingletonClass instance = new SingletonClass(); private SingletonClass(){} public SingletonClass getInstance()
{
return instance;
}
}

一个空的类,为了测试初始化和销毁用的:

public class EmptyClass
{
static
{
System.out.println("Enter EmptyClass.static block");
} public EmptyClass()
{
System.out.println("Enter EmptyClass.construct()");
} public void init()
{
System.out.println("Enter EmptyClass.init()");
} public void destory()
{
System.out.println("Enter EmptyClass.destory()");
}
}

一个集合类,为了演示集合注入:

public class CollectionClass
{
private List<String> list;
private Map<Family, Person> map;
private int[] ints; public List<String> getList()
{
return list;
} public void setList(List<String> list)
{
this.list = list;
} public Map<Family, Person> getMap()
{
return map;
} public void setMap(Map<Family, Person> map)
{
this.map = map;
} public int[] getInts()
{
return ints;
} public void setInts(int[] ints)
{
this.ints = ints;
}
}

最简单的bean实例化

bean.xml中注入这个bean,以Person类为例:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> <bean id="person" class="com.xrq.bean.Person" /> </beans>

main函数这么写:

public static void main(String[] args)
{
ApplicationContext ctx =
new ClassPathXmlApplicationContext("spring.xml");
Person person1 = (Person)ctx.getBean("person");
Person person2 = (Person)ctx.getBean("person");
System.out.println(person1 == person2);
}

运行结果为true,也就是说Spring默认以单例的形式给开发者构造出指定的bean。另外有两点要注意:

1、同一个spring.xml中不可以定义两个id相同的bean

2、ClassPathXmlApplicationContext中有一个可变长度的构造函数,用于加载多个.xml中的bean,如果bean中有id相同,那么id相同的bean,后加载的会覆盖先加载的

bean的作用域及生命周期

代码不动,把bean.xml文件修改一下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> <bean id="person" class="com.xrq.bean.Person" scope="prototype"
lazy-init="true"/> </beans>

这里出现了两个属性,scope和lazy-init:

1、scope表示的是bean的作用域,有prototype、request、session、singleton四种,其中singleton是默认的,表示单例。prototype表示每次创建都会产生一个bean实例。request和session只在web项目中才会用,其作用域就和web中的request和session一样

2、lazy-init表示的是bean的生命周期,默认为false。当scope=singleton时,bean会在装在配置文件时实例化,如果希望bean在产生时才实例化,可以把lazy-init设置为true。当scope=prototype时,在产生bean时才会实例化它。补充一点,如果希望该配置文件中所有的bean都延迟初始化,则应该在beans根节点中使用lazy-init="true"

三种注入方式

所谓注入即注入bean中的属性,Spring为用户提供了三种注入方式,settter注入、构造方法注入、注解注入,不过对于Spring的讲解,不讲注解,所以看一下前两种注入方式:

1、setter注入,bean.xml的写法为:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> <bean id="person" class="com.xrq.bean.Person">
<property name="personName" value="Alice"/>
<property name="personAge" value="10" />
</bean>
</beans>

2、构造方法注入,bean.xml的写法为:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> <bean id="family" class="com.xrq.bean.Family">
<constructor-arg name="person" ref="person" />
<constructor-arg name="familyName" value="friendly" />
</bean> <bean id="person" class="com.xrq.bean.Person">
<property name="personName" value="Alice"/>
<property name="personAge" value="10" />
</bean>
</beans>

这里故意把family的定义写在person的定义上面,说明即使前面的beanA持有beanB的引用,把beanA定义在beanB前面也不影响

集合注入

spring对于集合属性的支持非常好,以CollectionClass为例,看下如何配置bean.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> <bean id="collectionClass" class="com.xrq.bean.CollectionClass">
<property name="list">
<list>
<value>111</value>
<value>222</value>
</list>
</property>
<property name="map">
<map>
<entry key="111">
<bean class="com.xrq.bean.Person">
<property name="personName" value="Mike"/>
<property name="personAge" value="11" />
</bean>
</entry>
</map>
</property>
<property name="ints">
<array>
<value>333</value>
<value>444</value>
</array>
</property>
</bean>
</beans>

工厂方式生成类

Spring虽然可以指定bean以单例的方式生成出来,但是每次都要用getBean方法获取类的实例非常麻烦,有办法像单例模式一样使用XXX.getInstance()就好了,不过还真有,以SingletonClass作为例子:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> <bean id="singletonClass" class="com.xrq.bean.SingletonClass"
factory-method="getInstance">
</bean> </beans>

这样,我们就可以使用单例的方式去调用这个类了,如果类里面有一些私有属性,还可以注入的方式在生成这个bean的时候就注入进去,非常方便

init-method和destory-method

有时候我们希望,在某个bean加载的时候做一些事情,销毁的时候做一些事情(是不是想到了Servlet),所以我们可以自定义初始化和销毁的方法EmptyClass这个类,bean.xml的配置为:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> <bean id="emptyClass" class="com.xrq.bean.EmptyClass"
init-method="init" destroy-method="destory"/>
</beans>

注意两点:

1、实例化类的时候,几个方法的加载顺序为静态资源->构造方法->初始化方法

2、触发destory()方法的调用可以使用"((ClassPathXmlApplicationContext)ctx).close();",注意scope="prototype"是不会触发destory()的,没有为什么,设计就是这样

父子类继承关系

有时候我们有要求,一个类是某一个类/抽象类的子类,可以这么做:

public abstract class AbstractClass
{ }
public class ImplClass extends AbstractClass
{ }

此时bean.xml要这么写:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> <bean id="abstractClass" class="com.xrq.bean.abstractClass" abstract="true"/>
<bean id="implClass" class="com.xrq.bean.ImplClass" parent="abstractClass" />
</beans>

注意这种写法对接口也有效

bean的使用的更多相关文章

  1. Spring中Bean的作用域、生命周期

                                   Bean的作用域.生命周期 Bean的作用域 Spring 3中为Bean定义了5中作用域,分别为singleton(单例).protot ...

  2. Spring中Bean的实例化

                                    Spring中Bean的实例化 在介绍Bean的三种实例化的方式之前,我们首先需要介绍一下什么是Bean,以及Bean的配置方式. 如果 ...

  3. 基于注解的bean配置

    基于注解的bean配置,主要是进行applicationContext.xml配置.DAO层类注解.Service层类注解. 1.在applicationContext.xml文件中配置信息如下 &l ...

  4. Spring8:一些常用的Spring Bean扩展接口

    前言 Spring是一款非常强大的框架,可以说是几乎所有的企业级Java项目使用了Spring,而Bean又是Spring框架的核心. Spring框架运用了非常多的设计模式,从整体上看,它的设计严格 ...

  5. Spring Bean详细讲解

    什么是Bean? Spring Bean是被实例的,组装的及被Spring 容器管理的Java对象. Spring 容器会自动完成@bean对象的实例化. 创建应用对象之间的协作关系的行为称为:装配( ...

  6. 【解决方案】 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userHandler': Injection of resource dependencies failed;

    一个错误会浪费好多青春绳命 鉴于此,为了不让大家也走弯路,分享解决方案. [错误代码提示] StandardWrapper.Throwableorg.springframework.beans.fac ...

  7. 分享个 之前写好的 android 文件流缓存类,专门处理 ArrayList、bean。

    转载麻烦声明出处:http://www.cnblogs.com/linguanh/ 目录: 1,前序 2,作用 3,特点 4,代码 1,前序  在开发过程中,client 和 server 数据交流一 ...

  8. Spring Bean的生命周期(非常详细)

    Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring ...

  9. Spring IoC源码解析——Bean的创建和初始化

    Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...

  10. [spring]03_装配Bean

    3.1 JavaBean 3.1.1 JavaBean 是什么 JavaBean 是一种JAVA语言写成的可重用组件. 为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器. Jav ...

随机推荐

  1. ES6 学习 -- 解构赋值

    一.数组解构 **数组解构,解构出来的值跟数组下标是一一对应的,如果左边变量多于右边数组,则左边后面部分变量值为undefined,如果右边数组元素个数多于左边解构变量个数,则左边变量全都有值,且一一 ...

  2. 火狐浏览器缓存导致JS已经改变的ID没改变

    问题主要就是火狐浏览器缓存. 比如,自己写一个JS,如下: $(document).ready(function () { $("#bigRoom").live("cli ...

  3. expect安装

    expect是在tcl基础上创建起来的,因此在安装expect之前需要安装tcl 安装TCL下载地址:http://www.tcl.tk/software/tcltk/download.html[ro ...

  4. linux 下使用scp命令传输文件

    scp -P 1234 /home/wakasann/test.txt wakasann@192.168.1.30:/var/www/html/ 使用 1234端口,将 test.txt文件传输到服务 ...

  5. css---过渡天坑

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. 初识Qgis

    折腾了一天,qgis终于能在跟了自己8年的本本上顺利打开了,官网先后下载了3.8和3.4版本的都出现了同样的问题,"could not load qgis_app.dll",goo ...

  7. dp转图论——cf1070A好题

    dp的状态转移很像一张有向图:每个状态为一个点,每中转移方案是一条有向边 本题要求是求出最小的数,那我们用状态[i,j]表示模i,数位和为j,那么从每个点出发的十条有向边代表[0,9]十个数 从每个状 ...

  8. kubernetes监控和性能分析工具:heapster+influxdb+grafana

    1.部署heapster 下载 heapster 相关 yaml 文件 [root@master dashboard]# wget https://raw.githubusercontent.com/ ...

  9. Spring整合Dubbo框架

    Dubbo作为一个RPC框架,其最核心的功能就是要实现跨网络的远程调用.演示过程创建两个小工程,一个作为服务的提供者,一个作为服务的消费者.通过Dubbo来实现服务消费者远程调用服务提供者的方法. d ...

  10. Vue Virtual Dom 和 Diff原理(面试必备) 极简版

    我又来了,这是Vue面试三板斧的最后一招,当然也是极其简单了,先说Virtual Dom,来一句概念: 用js来模拟DOM中的节点.传说中的虚拟DOM. 再来一张图: 是不是一下子秒懂  没懂再来一张 ...