Spring篇
目录
一、Spring入门
1.1 Spring的由来和体系结构
Spring是一个轻量级的Java开发框架,有多轻呢?一个完整的Spring框架可以在大小只有1MB多的JAR文件上运行,它的出现大大提高了开发者的效率,使得JAVA开发者可以更加专注于应用开发。
关于具体的体系结构和优点,我觉得可以在百度百科查询,里面很详细就不多说明了:
https://baike.baidu.com/item/spring/85061?fr=aladdin,
下面讲一讲Spring核心容器的主要作用,Spring篇章基本也是围绕这几个核心容器在讲
Spring的核心容器包含以下几个模块:
(1)Spring-core模块:负责提供框架的基本组成部分,含有:控制反转和依赖注入,
问题一:什么是控制反转呢?
标准答案:用来减低计算机代码之间的耦合度。 其中最常见的方式叫做依赖注入(Dependency Injection,简称DI), 通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中……
暂停!看不懂?这是百度百科权威的回答,如果看不懂就对了,反正我刚开始看的时候也没明白,现在我谈谈我的认识,不对的地方希望指出
我的理解:这就好比你要建房子,你是去自己组建一支建房队伍好呢?还是请一个包工头呀?如果你是自己组建队伍,你得东找西找的,还要想你需要多少水泥工,多少电工等等,还要挨个告诉他们你要的房子怎么样,需要什么配置,需要什么设计。如果你请了一个包工头,你只需要把你的需求告诉他一个人就行了,他就会帮你负责到底,只要钱给到位,肯定没问题,是不是特别省心呢?这就是控制反转的思想!你并没有自己参与到具体的建房子当中去,你只是把自己的需求告诉了一个人就行了。
在Java中,如果你是使用普通思想,你在需要调用对象的时候就要不断的new一个Java对象,这样你后期要维护起来特别麻烦,但是你要使用包工头思想,也就是控制反转,Spring会负责分配控制程序之间的关系,这样控制权就转移到了Spring容器了,(就好像聘请包工头,你把对建房子的控制权转让给他,他会根据你的不同需求分配给不同的工种,比如你对电路有特殊要求,他就会把这个需求告诉电工,而不是焊工,也省去了你单独去找电工的麻烦)控制权发生了转让就是控制反转!
问题二:什么是依赖注入?
标准答案:控制反转最常见的方法就是依赖注入, 组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。
靠!还是不明白,思来想去还是只能搬出包工头
我的理解:到了交房的时间,你不用再去关心电线是怎么走的,网线有没有弄好,包工头只要把每个任务都完成好,并且这些功能能够注入你的生活需求就行了,换句话说,你不再关心他是怎么实现建造一套房子的,你只需要确认这个房子满足你的需求即可,这就是依赖注入。
关于控制反转和依赖注入先讲到这,后面Spring IoC还会讲到的,我们依旧会拿这个例子来解释种种问题
(2)Spring-beans模块:提供BeanFactory,后面我们会讲到
(3)Spring-context模块:提供一个框架式的对象访问方式
(4)Spring-context-support模块:
(5)Spring-expression模块:提供强大的表达式语言去支持运行时查询和操作对象图
二、Spring IoC
2.1 Spring IoC的基本概念:
控制反转是Spring框架的核心,用来消减程序的耦合度,关于什么是控制反转上一节已经讲诉这里便不再重复,还不懂的可以去上面在看一下。这里简单讲一讲什么是耦合
问题 一:什么是耦合?
标准答案: 对象之间的耦合度就是对象之间的依赖性。指导使用和维护对象的主要问题是对象之间的多重依赖性。对象之间的耦合越高,维护成本越高。因此对象的设计应使类和构件之间的耦合最小。
还是看不太懂,拿出我的理解方式:
我的理解:假如说你现在依旧是自己组建建房子队伍,很不幸你还很抠,要求一个工人至少会两样以上的技能,工程进度到了一半,你给的工钱太少,那个会瓦工和涂料工技能的钢筋工不干了,不巧,你又没有多请一瓦工和涂料工,但这时候你又很需要这两个工种,而钢筋工干的事别人没办法干,你也没有多请人,此时工程就耽误了,这就是高耦合度。那怎么办?此时如果把那个钢筋工请回来他估计看着你如此需要他,估计会漫天要价,这时候你就不得不请三个人,一个只会砌体的瓦工,一个只会刷墙的涂料工,一个只会绑扎钢筋的钢筋工。此时你就降低了耦合度。
2.2 Spring IoC容器:
主要基于BeanFactory和ApplicationContext两个接口
2.2.1 BeanFactory:提供完整的IoC服务支持,是一个管理Bean的工厂,负责初始化Bean。创建接口通常使用XmlBeanFactory,值得注意的是,创建BeanFactory实例时需要提供XML文件的绝对路径,接下来,我们通过对BeanFactory的理解来一起体会一下控制反转有什么不同吧!
预备:导入相关jar包,记得Build Path它们呦!
第一步:创建TestIoC接口
在src目录下创建一个test.dao包,并在包下面创建下面的接口
package test.dao;
public interface TestIoC {
public void testIoC();
}
第二步:创建实现类TestIoCImpl继承上面的接口
package test.dao;
public class TestIoCImpl implements TestIoC {
@Override
public void testIoC() {
// TODO Auto-generated method stub
System.out.println("This is First SpringIoC test!");
}
}
第三步:创建配置文件applicatonContext.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.xsd">
<bean id="test" class="test.dao.TestIoCImpl"/>
</beans>
配置文件可以自定义自己的名称,而配置文件中的约束信息不需用自己书写,可以在Spring帮助文档里面获取,不知道的也可以百度复制粘贴,这里就一笔带过了。
第四步:创建测试方法
public class Test {
public static void main(String[] args) {
BeanFactory beanFc = new XmlBeanFactory(new
FileSystemResource("D:\\eclipse-workspace\\ch0\\src\\applicationContext.xml"));
TestIoC testDao =(TestIoC)beanFc.getBean("test");
testDao.testIoC();
}
}
问题二:如何获取配置文件的绝对路径呢?
右键配置文件→Properties→Resource→Location就可以看到配置文件的绝对路径,复制粘贴即可用
问题三:遇到“Invalid escape sequence (valid ones are \b \t \n \f \r \" \' \\ )”的问题怎么解决?
这是一个正则表达式错误,在每个反斜杠上再加一条就可以了
运行后我们可以看到
2.2.2 ApplicationContext:BeanFactory的子接口,包含BeanFactory的所有功能,还添加了对咨询访问,国际化,事件传播等内容支持。创建接口实例通常有三种:
① 通过ClassPathXmlApplicationContext创建:从src根目录开始寻找指定的XML配置文件,不需要提供XML的绝对路径
实例:修改上面的main方法
public class Test {
public static void main(String[] args) {
BeanFactory applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
TestIoC testDao =(TestIoC) applicationContext.getBean("test");
testDao.testIoC();
}
}
②通过FileSystemXmlApplicationContext创建:同XmlBeanFactory用法相同,使用绝对路径缺乏灵活性,一般不推荐使用。
③通过Web服务器实例化ApplicationContext容器实现:后面遇到我们再详细讲,记住还有这东西就好
2.3 依赖注入
依赖注入有两种实现方式:一种是构造方法注入,一种是setter方法注入,我个人比较喜欢setter方法注入。
现在我们来体验一下构造方法注入,我们在上一节的基础上进行更改:
2.3.1构造方法注入
第一步:创建test.service包,并在包中创建TestDIService接口和TestDIServiceImpl实现类
package test.service;
public interface TestDIService {
public void FirstDiService();
}
public class TestDIServiceImpl implements TestDIService{
private TestIoC testIoC;
public TestDIServiceImpl(TestIoC testIoC) {
super();
this.testIoC=testIoC;
}
@Override
public void FirstDiService() {
testIoC.testIoC();
System.out.println("构造方法注入!");
}
}
第二步:修改配置文件
<?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.xsd">
<bean id="myTestIoC" class="test.dao.TestIoCImpl"/>
<bean id="myTestDiService" class="test.service.TestDIServiceImpl">
<constructor-arg index="0" ref="myTestIoC"/>
</bean>
</beans>
第三步:修改Test中的main方法
public class Test {
public static void main(String[] args) {
BeanFactory applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
TestDIService testDao =(TestDIService) applicationContext.getBean("myTestDiService");
testDao.FirstDiService();
}
}
运行后结果:
我们来仔细分析一下配置文件中的代码意思:
<bean id="myTestIoC" class="test.dao.TestIoCImpl"/>
<bean id="myTestDiService" class="test.service.TestDIServiceImpl">
<constructor-arg index="0" ref="myTestIoC"/>
</bean>
每一个id对应一个实现类,例如id="myTestIoC" class="test.dao.TestIoCImpl"
constructor-arg:指定构造方法的参数,index属性指定参数的序号,从0开始算;ref属性指定其他Bean的引用关系
我们再来体验一下用setter方法注入是怎么操作的
2.3.2 setter方法注入
第一步:在原有的test.service包内创建新的实现类TestDIServiceImpl2
public class TestDIServiceImpl2 implements TestDIService{
private TestIoC testIoC;
public void setTestIoC(TestIoC testIoC) {
this.testIoC = testIoC;
}
@Override
public void FirstDiService() {
testIoC.testIoC();
System.out.println("setter方法注入!");
}
}
第二步:将TestDIServiceImpl2实现类托管给Spring配置文件applicationContext
<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.xsd">
<bean id="myTestIoC" class="test.dao.TestIoCImpl"/>
<bean id="TestDiService2" class="test.service.TestDIServiceImpl2">
<property name="testIoC" ref="myTestIoC"/>
</bean>
</beans>
第三步:更改main方法,加入setter方法注入
public class Test {
public static void main(String[] args) {
BeanFactory applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
TestDIService testDao =(TestDIService) applicationContext.getBean("TestDiService2");
testDao.FirstDiService();
}
}
运行结果:
同样,我们来看一下更改后的配置文件内容
<bean id="myTestIoC" class="test.dao.TestIoCImpl"/>
<bean id="TestDiService2" class="test.service.TestDIServiceImpl2">
<property name="testIoC" ref="myTestIoC"/>
</bean>
在这里面多了一个 <property name="testIoC" ref="myTestIoC"/>,这里的name属性所对应的值是TestDIServiceImpl2类中的属性testIoC,所以name的属性值必须和它一致,才能将myTestIoC注入到TestDIServiceImpl2的属性testIoC,否则会报错
三、Spring Bean
我们把Spring看作了包工头,那么Bean就是不同工种的工人,开发者需要在配置文件中配置Bean,相当于授予包工头能够招聘和管理这类建筑工人的权力,<bean>元素内有很多属性和子元素,等我们遇到了在细谈。一下子列举出来反正也记不起来。
3.1 Bean的实例化
Bean的实例化一共有三种方式:构造方法实例化(最常用)、静态工厂实例化和实例工厂实例化
3.1.1 构造方法实例化
我们具体来讲一讲最常用的构造方法实例化:
第一步:创建新的Web应用,记得导入Spring支持和依赖的JAR包,所需JAR包和上面的一样
第二步:创建一个新的test.instance包,在该包内创建一个”工人”BeanClassTest类
public class BeanClassTest {
public String message;
public BeanClassTest() {
message = "这是构造方法实例化";
}
public void print() {
System.out.println("This is BeanClass");
}
}
第三步:创建一个包工头applicationContext.xml,并告诉包工头你可以管理BeanClassTest这个工人
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="beanInstance" class="test.instance.BeanClassTest"/>
</beans>
第四步:验房,我们在src目录下创建test.test包,并在包下创建测试类
public class TestInstanceBean {
public static void main(String[] args) {
ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml");
BeanClassTest beanclass = (BeanClassTest) appCon.getBean("beanInstance");//getBean()内对应的是配置文件中bean属性的id名称
System.out.println(beanclass+beanclass.message);
beanclass.print();
}
}
我们来看一下我们的劳动成果
看到了吧,这就是构造方法实例化,我们并没有直接new一个出来,而是通过包工头applicationContext.xml获取BeanClassTest的无参构造函数来创建对象,从而使用它的功能print()
3.1.2 静态工厂实例化
那我们继续来看一看静态工厂实例化吧!为了避免重复导包的麻烦,我们依旧在上面的基础上进行操作
第一步:修改BeanClassTest类
public class BeanClassTest {
public String message;
public BeanClassTest(String message) {
this.message=message;
}
public void print() {
System.out.println("This is BeanClass");
}
}
第二步:在instance包中创建静态工厂类StaticBeanTest
public class StaticBeanTest {
private static BeanClassTest beanInstance = new BeanClassTest("这是静态工厂方法实例化");
public static BeanClassTest createInstance() {
return beanInstance;
}
}
第三步:修改配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--factory-method属性内对应的是BeanClassTest方法名,务必正确填写不然检索不到 -->
<bean id="staticInstance" class="test.instance.StaticBeanTest" factory-method="createInstance"/>
</beans>
第四步:修改main方法
public class TestInstanceBean {
public static void main(String[] args) {
ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml");
BeanClassTest beanclass = (BeanClassTest) appCon.getBean("staticInstance");
System.out.println(beanclass);
System.out.println(beanclass.message);
beanclass.print();
}
}
运行结果如下:
3.1.2 实例工厂实例化
我们接着来看看实例化工厂是怎么使用的,不再做详细介绍,大家对比体验一下
第一步:创建InstanceFactory工厂类
public class InstanceFactory {
public BeanClassTest createBeanInstance() {
return new BeanClassTest("这是实例工厂实例化");
}
}
第二步:修改配置文件applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="factoryInstane" class="test.instance.InstanceFactory"/>
<!--factory-bean属性指定需要的配置工厂,这里需要的是实例化工厂的所以选择id为factoryInstane -->
<bean id="instanceFactory" factory-bean="factoryInstane" factory-method="createBeanInstance"/>
</beans>
第三步:修改main方法
public class TestInstanceBean {
public static void main(String[] args) {
ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml");
BeanClassTest beanclass = (BeanClassTest) appCon.getBean("instanceFactory");
System.out.println(beanclass);
System.out.println(beanclass.message);
beanclass.print();
}
}
运行结果如下:
3.2 Bean的生命周期
每一个工人他都有工作时间,Bean也不例外。一个对象的生命周期就是初始化/实例化,使用和销毁等阶段,Bean对象也一样。但Spring提供许多对外接口,所以我们可以在初始化、使用和销毁的前后做一些手脚来完成我们的需求。此时你请的包工头Spring容器又出来了,它能精准知道Bean什么时候被创建、初始化完成和什么时候被销毁,但这个只有在<bean>中的scope为singleton时才能有这样的权限,如果是prototype的话,Spring只负责创建。
那么我们先来简单了解一下Bean的作用域,Bean的作用域总共有六种,最常见的是singleton和prototype,后面四种request、session、application和websorket是Web Spring中才会使用,暂且不说
singleton:翻译过来就是单身,单独的意思,顾名思义就是Spring容器仅生成和管理一个Bean实例,这也是默认方式,如果不自己填写,系统默认就是这个模式
prototype:翻译过来就是原形,所以Spring容器将会在每次请求的时候创建一个新的实例
我们不打算详谈作用域,而是开始直接将生命周期,在生命周期的实例中在测试这两个作用域有什么不同即可
我将Bean的生命周期整理如下:
1、实例化一个Bean
2、初始化Bean的属性
3、在Spring配置文件中设置init-method属性,将调用你配置的初始化方法*
4、在Spring配置文件中设置destroy-method属性,将调用你配置的销毁方法**
*如果Bean实现了BeanXXXAware的接口,那么久调用它实现的setBeanXXX方法,有以下几个接口:
①BeanNameAware接口;②BeanFactoryAware接口;③ApplicationContextAware接口
如果Bean实现InitializingBean接口,将调用afterPropertiesSet方法
如果Bean实现BeanPostProcessor接口,将调用postProcessBeforeInitialization
**如果Bean实现了DisposableBean接口,则调用其实现的destroy方法销毁Bean
好了,了解那么多,我们通过两个实例来验证一下,首先我们就先来完成自定义方法的实例
第一步:新建一个新的web项目,在src目录下创建一个bean.life包,在该包下创建BeanLife类 ,代码如下:
public class BeanLife {
public void initBeanLife() {
System.out.println("执行自定义的初始方法:"+this.getClass().getName());
}
public void destoryBeanLife() {
System.out.println("执行自定义的销毁方法:"+this.getClass().getName());
}
}
第二步:配置applicationContext.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.xsd">
<bean id="beanLife" class="bean.life.BeanLife" init-method="initBeanLife" destroy-method="destoryBeanLife"/>
</beans>
第三步:测试类BeanLifeTest
public class BeanLifeTest {
public static void main(String[] args) {
System.out.println("获得对象之前");
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BeanLife blife = (BeanLife) ctx.getBean("beanLife");
System.out.println("获取对象之后:"+blife);
ctx.close();
}
}
运行结果如下:
现在我们来看一下实现BeanNameAware和DisposableBean接口的方法
第一步:修改bean.life包下的BeanLife类
public class BeanLife implements BeanNameAware ,DisposableBean{
@Override
public void setBeanName(String arg0) {
System.out.println("I belong to ---->"+arg0);
}
@Override
public void destroy() throws Exception {
// TODO Auto-generated method stub
System.out.println("DisposableBean方式销毁Bean");
}
}
第二步:修改配置文件
<bean id="myBeanNameAware" class="bean.life.BeanLife"/>
第三步:修改测试类BeanLifeTest
public class BeanLifeTest {
public static void main(String[] args) {
System.out.println("获得对象之前");
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BeanLife blife = (BeanLife) ctx.getBean("myBeanNameAware");
System.out.println("获取对象之后:"+blife);
ctx.close();
}
}
结果如下:
现在我们在原有<bean>元素里加上scope="prototype"看看和默认值singleton有什么不同
修改配置文件中的<bean>
<bean id="myBeanNameAware" scope="prototype" class="bean.life.BeanLife"/>
结果如图 :
可以看到prototype相比singleton,prototype只负责在每一次请求中创建新的实例,而不执行销毁步骤。
3.3 Bean的装配方式
每个工人都是人,只是他们拥有不同的技能和作用而已,Bean也一样,我们可以先创建一个实例类,通过Bean依赖注入到Spring容器中,Bean的装载方式最常见的有三种,分别是XML配置的装配,注解装配,自动装配,其中注解装配最受喜爱。现在我们来分别看一下这三个有什么不同
3.3.1XML配置的装配
第一步:创建实现类
public class ConstructionWorker {
private String typeWork;//工种,bean中index=0
private List<String> skill;//技能,bean中index=1
private Map<String,String> tool;//工具,bean中index=2
private Set<String> wages;//工薪,bean中index=3
private String[] remarks;//备注,bean中index=4
/*
* 构造方法注入需要提供有参数的构造方法
* */
public ConstructionWorker(String typeWork, List<String> skill, Map<String, String> tool, Set<String> wages,
String[] remarks) {
super();
this.typeWork = typeWork;
this.skill = skill;
this.tool = tool;
this.wages = wages;
this.remarks = remarks;
}
@Override
public String toString() {
return "ConstructionWorker [typeWork=" + typeWork + ", skill=" + skill + ",\n tool=" + tool + ", \n wages=" + wages
+ ", \n remarks=" + Arrays.toString(remarks) + "]";
}
第二步:编写配置文件applicationContext.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="worker" class="bean.worker.ConstructionWorker">
<constructor-arg index="0" value="粉刷工"/>
<constructor-arg index="1">
<list>
<value>浇水泥</value>
<value>刷墙</value>
</list>
</constructor-arg>
<constructor-arg index="2">
<map>
<entry key="luoyangchan" value="洛阳铲"/>
<entry key="mozi" value="抹子"/>
</map>
</constructor-arg>
<constructor-arg index="3">
<set>
<value>每小时30元</value>
<value>每天200元</value>
<value>每月5000元</value>
</set>
</constructor-arg>
<constructor-arg index="4">
<array>
<value>联系地址:XXXXXXXX</value>
<value>联系电话:XXXXXXXX</value>
</array>
</constructor-arg>
</bean>
</beans>
第三步:编写测试类
public class Test {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
ConstructionWorker worker = (ConstructionWorker) applicationContext.getBean("worker");
System.out.println(worker);
}
}
3.3.2注解装配
第一步:修改上面的实现类,提供setter方法
public class ConstructionWorker {
private String typeWork;//工种,bean中index=0
private List<String> skill;//技能,bean中index=1
private Map<String,String> tool;//工具,bean中index=2
private Set<String> wages;//工薪,bean中index=3
private String[] remarks;//备注,bean中index=4
public void setTypeWork(String typeWork) {
this.typeWork = typeWork;
}
public void setSkill(List<String> skill) {
this.skill = skill;
}
public void setTool(Map<String, String> tool) {
this.tool = tool;
}
public void setWages(Set<String> wages) {
this.wages = wages;
}
public void setRemarks(String[] remarks) {
this.remarks = remarks;
}
@Override
public String toString() {
return "ConstructionWorker [typeWork=" + typeWork + ", skill=" + skill + ",\n tool=" + tool + ", \n wages=" + wages
+ ", \n remarks=" + Arrays.toString(remarks) + "]";
}
}
第二步:修改上面的配置文件,将constructor-arg改为property,而index改为name,name的属性值为实现类的属性名
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="worker" class="bean.worker.ConstructionWorker">
<property name="typeWork" value="粉刷工"/>
<property name="skill">
<list>
<value>浇水泥</value>
<value>刷墙</value>
</list>
</property>
<property name="tool">
<map>
<entry key="luoyangchan" value="洛阳铲"/>
<entry key="mozi" value="抹子"/>
</map>
</property>
<property name="wages">
<set>
<value>每小时30元</value>
<value>每天200元</value>
<value>每月5000元</value>
</set>
</property>
<property name="remarks">
<array>
<value>联系地址:XXXXXXXX</value>
<value>联系电话:XXXXXXXX</value>
</array>
</property>
</bean>
</beans>
测试类main方法不需做更改,运行结果如下
3.3.3 注解装配
注解装配的有好几种:@Component;@Repository;@Service;@Controller;@Autowired;@Resource;@Qualify等等,我们拿第一个来说明一下,后面以后遇到再详谈
@Component:泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。 作用是把普通实例化到spring容器中,相当于配置文件中的 <bean id="" class=""/>
第一步:修改实现类,提供setter和getter方法
@Component
/**
*相当于@Component("constructionWorker),在main方法引用的时候getBean("")需填constructionWorker
**/
public class ConstructionWorker {
@Value("粉刷工")
private String typeWork;//工种,bean中index=0
@Value("浇水泥")
private String skill;//技能,bean中index=1
public String getTypeWork() {
return typeWork;
}
public void setTypeWork(String typeWork) {
this.typeWork = typeWork;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
@Override
public String toString() {
return "ConstructionWorker [typeWork=" + typeWork + ", skill=" + skill + "]";
}
}
第二步:修改上面的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="bean.worker"/>
</beans>
第三步:修改main方法
public class Test {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
ConstructionWorker worker = (ConstructionWorker) applicationContext.getBean("constructionWorker");
System.out.println(worker.toString());
}
}
运行结果如下:
四、Spring AOP
五、Spring事务管理
这两章将会放在Spring篇(二)