Spring基础—装配bean(一)
在讲解Spring配置beans之前首先想一下一部成功的电影都需要哪些成员参与。首先,最重要的是要有导演、编剧、演员和投资人;其次,还有没那么明显的成员,音乐人、特技演员和艺术指导;此外,还有其他很重要但是容易被忽略的人,调音师、服装师、化妆师、宣传员、摄影师、摄影师助手、灯光指导和外卖小哥。一部成功的电影应当是将各个人员合理而且有序的组织起来,然后各自完成他们各自的工作,他们之间会有很多联系,大部分工作也需要很多人员共同完成。
对应到一个应用中,有很多个对象,这些对象之间只有相互发送消息才能实现功能,在原始的Java程序中,使各个对象产生联系的方法就是不停地new来new去,这就导致了代码复杂化,使其难以复用和实现单元测试。而在Spring里面,一个对象当需要用到另一个对象的时候,它并不负责找到这个对象并且创建它,相反,仅仅给出需要的对象的引用就可以了,具体的对象实例是放在container里面的。
将一个应用中不同对象联系起来的行为就是依赖注入(dependency injection)的本质,称之为装配(wiring),本文讲解的就是装配beans的方式,这些内容是Spring最常用到的。
1 声明bean
1.1 在XML文件中配置Spring
前文已经说过,容器是Spring的基础,而我们将各个beans创建出来并且将它们联系起来是通过一个或多个XML文件的配置来实现的。当在XML中声明beans的时候,基本元素就是<beans>
,一个标准的Spring配置的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-3.0.xsd">
<!-- Bean declarations go here -->
</beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
在<beans>
里面可以做Spring的相关配置,包括<bean>
声明。但是beans
并非Spring唯一的命名空间,Spring框架的核心总共有十个配置的命名空间,如下:
- aop:为声明切面以及将用@AspectJ注解的类自动代理为Spring切面提供了配置元素
- beans:声明和装配bean,是Spring最核心也是最原始的命名空间
- context:用来配置Spring应用上下文环境的元素,包括自动检测和装配bean以及注入某些非Spring直接管理的对象的能力。
- jee:提供了与Java EE API的集成,比如JNDI和EJB(原文:Offers integration with Java EE APIs such as JNDI and EJB.)
- jms:为声明消息驱动的POJOs提供了配置元素(不是太懂,原文:Provides configuration elements for declaring message-driven POJOs.)
- lang:可以声明由Groovy,JRuby或者BeanShell脚本实现的bean(原文:Enables declaration of beans that are implemented as Groovy, JRuby, or BeanShell
scripts.) - mvc:可以使用MVC的能力,如面向注解的控制器、视图控制器和拦截器
- oxm:提供Spring的对象到XML的映射
- tx:提供声明的事物配置(原文:Provides for declarative transaction configuration.)
- util:提供各种各样的工具类元素,包括把集合声明为bean、支持属性占位符元素(原文:A miscellaneous selection of utility elements. Includes the ability to declare collections as beans and support for property placeholder elements.)
1.2 声明一个简单的bean
首先写一个非常实例:用Spring配置一个bean,这个bean指向的类里有一个方法,用来描述一下动作:java学习者在写博客。
首先写出这个类:Javaer.java
package com.springinaction.springidol;
/*** Java程序员* @author 白鑫* @date 2016-1-5下午11:13:16*/
public class Javaer implements Coder {private int blogNum = 2;//博客数public Javaer() {}public Javaer(int blogNum) {this.blogNum = blogNum;}public void perform() {System.out.println("Trigl is writing " + blogNum + " blogs.");}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
继承的接口:Coder.java
package com.springinaction.springidol;
/*** Coder接口类* @author 白鑫* @date 2016-1-5下午11:15:27*/
public interface Coder {void perform();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
继承的目的是为了减藕,毋庸多言。
XML配置bean:spring-idol.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-3.0.xsd">
<!-- Bean declarations go here --><bean id="javaer" class="com.springinaction.springidol.Javaer"></bean>
</beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
<bean>
是Spring中最基本的配置单元,它会告诉Spring为你创建一个对象。id属性是这个bean的名字,通过它指向Spring容器。class属性说明这个bean对应的类。
当Spring的容器加载bean的时候,就会使用默认的构造器实例化名为javaer的bean,但是本质上,javaer的创建就是通过以下的Java代码:
new com.springinaction.springidol.Javaer();
- 1
在main方法中加载加载上下文环境进行测试
public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("com/springinaction/springidol/spring-idol.xml");Coder coder = (Coder) ctx.getBean("javaer");coder.perform();}
- 1
- 2
- 3
- 4
- 5
- 6
结果输出为:
Trigl is writing 2 blogs.
- 1
1.3 在bean中自定义构造器参数
我们可以通过自定义一个构造器来创建一个对象,这个操作同样可以在Spring中实现,只要将构造器的参数写进XML的bean配置即可。
还是举一个实例来说明:用Spring配置一个bean,这个bean指向的类里有一个方法,用来描述一下动作:java学习者在写10篇博客同时还在听歌。(这里加入10和歌曲是为了在构造器中加入一个原始数据类型和一个类作为构造器参数)
首先写出主体类:SongJavaer.java
package com.springinaction.springidol;/*** 听歌的Java程序员* @author 白鑫* @date 2016-1-6上午12:29:11*/
public class SongJavaer extends Javaer {private Song song;public SongJavaer(int blogNum, Song song) {super(blogNum);this.song = song;}public void perform() {super.perform();System.out.println("While listening...");song.play();}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
由于这个例子与上个例子相比多了个听歌这个动作,所以我们新建一个SongJavaer类继承上面的Javaer类,可以看到与上面的例子相比多了个构造方法,这个构造方法的参数一个是int原始数据类型的,一个是类Song,在下面我会给出在XML文件中配置构造器参数的方法。
Song接口类:Song.java
package com.springinaction.springidol;
/*** Song接口* @author 白鑫* @date 2016-1-6上午12:36:05*/
public interface Song {void play();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
再写一个继承Song接口的类:SongJay.java
package com.springinaction.springidol;
/*** Jay的歌* @author 白鑫* @date 2016-1-6上午12:37:28*/
public class SongJay implements Song {private static String[] LYRICS = {"一盏离愁孤灯伫立在窗口","我在门后假装你人还没走","旧地如重游月圆更寂寞","夜半清醒的烛火不忍苛责我","一壶漂泊浪迹天涯难入喉","你走之后酒暖回忆思念瘦","水向东流时间怎么偷","花开就一次成熟我却错过","谁在用琵琶弹奏一曲东风破","岁月在墙上剥落看见小时候","犹记得那年我们都还很年幼","而如今琴声幽幽我的等候你没听过","谁在用琵琶弹奏一曲东风破","枫叶将故事染色结局我看透","篱笆外的古道我牵着你走过","荒烟漫草的年头就连分手都很沉默"};public void play() {for (int i = 0; i < LYRICS.length; i++){System.out.println(LYRICS[i]);}}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
在XML文件spring-idol.xml中配置bean
<bean id="songJavaer" class="com.springinaction.springidol.SongJavaer"><constructor-arg value="20" /><constructor-arg ref="songJay" /></bean><bean id="songJay" class="com.springinaction.springidol.SongJay" />
- 1
- 2
- 3
- 4
- 5
- 6
可以看到,在<bean>
中配置构造器参数是通过<constructor-arg>
属性来配置的。其中对于简单的原始数据类型如int、String类型,是通过<constructor-arg>
的value属性来传参的;对于具体的类,是通过使用<constructor-arg>
的ref属性来传参的,ref中的值等于相应bean的id。
在main方法中加载上下文环境进行测试
public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("com/springinaction/springidol/spring-idol.xml");Coder coder = (Coder) ctx.getBean("songJavaer");coder.perform();}
- 1
- 2
- 3
- 4
- 5
- 6
控制台输出的结果是:
Trigl is writing 20 blogs.
While listening...
一盏离愁孤灯伫立在窗口
我在门后假装你人还没走
旧地如重游月圆更寂寞
夜半清醒的烛火不忍苛责我
一壶漂泊浪迹天涯难入喉
你走之后酒暖回忆思念瘦
水向东流时间怎么偷
花开就一次成熟我却错过
谁在用琵琶弹奏一曲东风破
岁月在墙上剥落看见小时候
犹记得那年我们都还很年幼
而如今琴声幽幽我的等候你没听过
谁在用琵琶弹奏一曲东风破
枫叶将故事染色结局我看透
篱笆外的古道我牵着你走过
荒烟漫草的年头就连分手都很沉默
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
通过工厂方法创建单实例
在Spring中可以将一个单实例类配置成为一个bean,如下面的Head.java
package com.springinaction.springidol;
/*** 工厂方法实现单实例类* @author 白鑫* @date 2016-1-6下午08:46:01*/
public class Head {private Head() {}private static class HeadSingletonHolder {static Head instance = new Head();}public static Head getInstance() {return HeadSingletonHolder.instance;}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
在XML中的配置为:
<bean id="theHead" class="com.springinaction.springidol.Head"factory-method="getInstance"></bean>
- 1
- 2
- 3
单实例类每次创建都是以static的形式,这就保证了每次创建的对象都是一样的。在Spring中的配置是通过<bean>
元素中的factory-method属性来配置,里面的值对应于类中的一个static方法getInstance。注意factory-method不仅局限于将一个单实例配置成为bean,对于任何你想要编写一个通过static方法创造类的时候,都可以使用工厂方法。
1.4 Bean的作用域
所以的Spring的bean都默认是单实例的,即每次Spring分配一个bean以后,总是会产生完全相同的对象。有时候我们不需要单实例,而是需要每次都产生唯一的实例。比如说买票,必须保证每次创建票的bean时候都是唯一的,我们可以通过以下方式来配置:
<bean id="ticket"
class="com.springinaction.springidol.Ticket" scope="prototype" />
- 1
- 2
也就是通过设置<bean>
的scope属性值为prototype来保证每次加载的bean都会创造唯一的实例。
Spring基础—装配bean(一)相关推荐
- spring(2)装配Bean
[0]README 0)本文部分文字描述转自:"Spring In Action(中/英文版)",旨在review spring(2)装配Bean 的相关知识: 1)在sprin ...
- Spring之装配Bean(一)
Spring中装配bean的三种主要方式 1.隐式的bean发现机制和自动化装配 组件扫描( component scanning) : Spring会自动发现应用上下文中所创建的bean. 自动装配 ...
- spring二:装配bean(自动装配)
创建应用对象之间协作关系的行为通常称为装配(wiring),这就是依赖注入(DI)的本质. Spring提供了三种主要的装配机制: 1. 在xml中进行显式配置. 2. 在java中进行显式配置. ...
- Spring实战(三)Spring中装配Bean的三种方式---XML、JavaConfig、AutoWire
创建应用对象之间协作关系的行为称为装配(wiring),这也是依赖注入的本质. Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系,而开发者需要告诉Spring需要创建哪些 ...
- Spring笔记——装配Bean
1.Spring配置的可选方案 在XML中进行显式配置. Java中进行显式配置. 隐式的bean发现机制和自动装配. 2.自动化装配bean Spring从两个角度来实现自动化装配: 组件扫描(co ...
- spring三: 装配bean( 在xml中进行显式配置, 在java中进行显式配置)
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class); SpringCon ...
- Spring自动装配Bean
除了使用 XML 和 Annotation 的方式装配 Bean 以外,还有一种常用的装配方式--自动装配.自动装配就是指 Spring 容器可以自动装配(autowire)相互协作的 Bean 之间 ...
- spring基础——普通bean xml注入
一.基本类型注入 1.set注入,前提是类中声明了属性的set方法 使用\ 2.有参构造器注入,前提是类中声明了有参构造器 使用<constructor-arg name="参数名&q ...
- Spring 自动化装配Bean
声明一张cd的接口: public interface CompactDisc {public abstract void play(); } 实现cd接口: @Component("Sgt ...
最新文章
- 细数 Spring 那些最常见的面试问题
- PWN-PRACTICE-BUUCTF-7
- 60-130-336-源码-source-kafka相关-Flink读取kafka
- 期末总结20135320赵瀚青LINUX内核分析与设计期末总结
- 微信小程序tap事件中target与currentTarget的区别
- Visual Studio C# Winform应用程序图标修改不了 更改图标不生效,发送桌面快捷方式与图标不一致解决办法
- android高仿微信表情输入与键盘输入详解
- 4.JavaScript对象和初始面向对象
- android 第三方SDK接入一般流程
- 【MyBatis】缓存——使查询变得快快快!
- matplotlib官方中文手册pdf下载
- 实战案例分享:我用 Python 预测房价走势
- 新任学校领导的国家简报
- PatterNodes for Mac(创建图形矢量模式工具)
- 基于Android13的系统启动流程分析(六)之SystemServer内部逻辑分析
- 成都农科院计算机专业考纲,成都农业科技职业学院2020高职单招考试内容
- python cgi 文件下载
- PdfiumViewer组件扩展
- 更新Linux网卡驱动
- 基于vue element-ui 的省市区数据结构 省市区三级联动数据---
热门文章
- 基于java的在线考试系统设计(含源文件)
- Linux(Ubuntu)下C语言编译与调试
- 云计算、Web2.0、SOA、SaaS、SNS到底是不是笑话?
- winpe修复计算机无法启动,用winpe来修复无法进入系统的问题
- 捕获海康威视IPCamera图像,转成OpenCV能够处理的图像(二)
- 请说说你对互联网行业的理解。
- 【造轮子/更新】打造一个简单的万能Excel读写工具
- Android手机靠近蓝牙模块自动连接蓝牙模块,断后自动重连。也可以手机靠近手机自动连接。连接成功率百分之百,可后台运行
- 基于Qt平台开发安卓应用
- python爬虫——爬取搜狗影视热门电视剧