前言

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>

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

Spring2:bean的使用的更多相关文章

  1. java基础(六):RabbitMQ 入门

    建议先了解为什么项目要使用 MQ 消息队列,MQ 消息队列有什么优点,如果在业务逻辑上没有此种需求,建议不要使用中间件.中间件对系统的性能做优化的同时,同时增加了系统的复杂性也维护难易度:其次,需要了 ...

  2. Java之Spring基础与IoC

    Spring About Spring 开源免费框架,轻量级,非入侵式框架.Spring就是一个轻量级的控制反转(IOC)和面向切片编程(AOP)的框架 Maven repo:Spring Web M ...

  3. 从头认识Spring-2.7 自己主动检測Bean(2)-过滤器&lt;context:include-filter/&gt;

    这一章节我们来讨论一下过滤器<context:include-filter/>的使用. 1.domain Person接口: package com.raylee.my_new_sprin ...

  4. spring2——IOC之Bean的装配

    spring容器对于bean的装配提供了两个接口容器分别是"ApplicationContext接口容器"和"BeanFactory接口容器",其中" ...

  5. 从头认识Spring-2.7 自己主动检測Bean(1)-@Component @Repository @Service @Controller

    这一章节我们来讨论一下自己主动检測Bean. 1.domain 厨师类: package com.raylee.my_new_spring.my_new_spring.ch02.topic_1_19; ...

  6. Spring Scope:Web项目中如何安全使用有状态的Bean对象?

    Web系统是最常见的Java应用系统之一,现在流行的Web项目多使用ssm或ssh框架,使用spring进行bean的管理,这为我们编写web项目带来了很多方便,通常,我们的controler层使用注 ...

  7. IOC装配Bean(注解方式)

    Spring的注解装配Bean Spring2.5 引入使用注解去定义Bean @Component 描述Spring框架中Bean Spring的框架中提供了与@Component注解等效的三个注解 ...

  8. IOC装配Bean(XML方式)

    Spring框架Bean实例化的方式 提供了三种方式实例化Bean 构造方法实例化(默认无参数,用的最多) 静态工厂实例化 实例工厂实例化 无参数构造方法的实例化 <!-- 默认情况下使用的就是 ...

  9. spring框架详解: IOC装配Bean

    1 Spring框架Bean实例化的方式: 提供了三种方式实例化Bean. 构造方法实例化:(默认无参数) 静态工厂实例化: 实例工厂实例化: 无参数构造方法的实例化: <!-- 默认情况下使用 ...

随机推荐

  1. ajax select option 数据。为了下次方便信手拈来!!

    为了下次方便信手拈来!! 示例1 var form = document.forms["maddraddform"]; $(form.province).change(functi ...

  2. 来自MarsEdit的博客测试

    使用MarsEdit编辑的第一个测试博客. 希望我们一帆风顺! 插图,在插图时可以调整尺寸:   六种公式写法,记得要在选项中打开-启用数学公式: \begin{equation}\sum\end{e ...

  3. iOS 的文字滚动条效果的实现

    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(50, 100, 300, 50)]; label.text  = @"欢 ...

  4. 命令安装VS

     Installing Visual Studio Visual Studio 2015   Other Versions Visual Studio 2013 Visual Studio 2010 ...

  5. <Operating System>进程调度

    在多道程序环境下,进程数目往往多于处理机数目,致使它们争用处理机.这就要求系统能按某种算法,动态地把处理机分配给就绪队列中的一个进程,使之执行.分配处理机的任务是由进程调度程序完成的. 三级调度 一个 ...

  6. c++中的指针

    指针用起来是一把利器,但用得不好的童鞋 无异于 火上浇油 ,下面笔者将自己学习 的一点小小心得,与君共享 指针在类中 1.对象指针 初始化 Point a(4,5); Point *p1 = & ...

  7. Python学习之路--面向对象

    1.面向对象概述 面向过程:根据业务逻辑从上到下写垒代码  函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可  面向对象:对函数进行分类和封装,让开发“更快更好更强...”  面向 ...

  8. C# XMAL与WPF

    通过老师上课的解释和我下课后的网上查询,我了解到了一些关于这三者的关系.XAML是.NET体系开发程序或者网页时前台编程的一种布局方式或者说开发语言,可以比较自由的用标签的方式进行布局,借鉴了HTML ...

  9. sql 注入的防范(一)

    为了保证程序的健壮性,我们必须对用户输入的数据做有效性验证,防止用户恶意提交数据. 关于防止 sql 注入 我主要从三个方面入手: 1.确认为正整数的,强制转化为int,$id  =$_GET('id ...

  10. Extjs的学习及MIS系统实践应用(系列文章)

    本系列文章从Extjs的实际运用出发,结合系统开发的实践经验,详细解释Extjs的基本控件及控件扩展的用法,和在平时的学习运用中一步一步查阅的资料.积累经验的集锦.标题及链接奉上,用一个小程序,开启了 ...