💞基于XML配置Bean
上文中, 我们学习到了 Spring系列一:spring的安装与使用
接下来我们学习, 通过XML配置bean
Bean管理包括两方面: 创建bean对象, 给bean注入属性
💖通过类型获取bean
案例: 通过spring的ioc容器, 获取一个bean对象, 获取方式: 按类型.
1.src/beans.xml
增加如下配置
<!--配置Monster, 通过类型获取-->
<bean class="com.zzw.spring.bean.Monster">
<!--
解读
1.当我们给某个bean对象设置属性的时候
2.底层是使用对应的setter方法完成的, 比如setName()
3.如果没有这个方法, 就会报错
-->
<property name="monsterId" value="100"/>
<property name="name" value="孙悟空"/>
<property name="skill" value="火眼金睛"/>
</bean>
2.com/zzw/spring/test/SpringBeanTest.java
新增getBeanByType
方法
//演示通过bean的类型获取对象
@Test
public void getBeanByType() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
//直接传入class对象/类型
Monster bean = ioc.getBean(Monster.class);
System.out.println("bean=" + bean);
}
细节
按照类型获取bean, 要求ioc容器中的同一个类的bean只能有一个, 否则会抛出异常 NoUniqueBeanDefinationException
这种方式的应用场景: 比如XxxAction / Servlet / Controller, 或XxxService在一个线程中只需要一个对象实例(单例)的情况
在容器配置文件(比如beans.xml)中给属性赋值. 底层是通过setter方法完成的. 所以需要提供setter方法.
💖通过指定构造器配置bean
1.src/beans.xml
增加如下配置
<!--配置Monster对象, 并且指定构造器-->
<!--
解读
1.constructor-arg标签可以指定使用构造器的参数
2.index表示构造器的第几个参数, 从0开始计算的
3.除了可以通过index, 还可以通过name / type来指定参数方式
4.解除大家的疑惑: 类的构造器, 不能有完全相同类型和顺序的构造器, 所以可以通过type来指定
一个类中的两个构造器, 参数的类型和顺序不能完全相同
可以类型相同, 但顺序不同 [方法重载]
-->
<bean class="com.zzw.spring.bean.Monster" id="monster03">
<constructor-arg value="100" index="0"/>
<constructor-arg value="齐天大圣" index="1"/>
<constructor-arg value="如意金箍棒" index="2"/>
</bean>
<bean class="com.zzw.spring.bean.Monster" id="monster04">
<constructor-arg value="200" name="monsterId"/>
<constructor-arg value="斗战胜佛" name="name"/>
<constructor-arg value="无法无天" name="skill"/>
</bean>
<bean class="com.zzw.spring.bean.Monster" name="monster05">
<constructor-arg value="300" type="java.lang.Integer"/>
<constructor-arg value="猪悟能" type="java.lang.String"/>
<constructor-arg value="追嫦娥~" type="java.lang.String"/>
</bean>
2.com/zzw/spring/test/SpringBeanTest.java
新增setBeanByConstructor
方法
//演示通过构造器来设置属性
@Test
public void setBeanByConstructor() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
Monster monster03 = ioc.getBean("monster03", Monster.class);
System.out.println("monster03=" + monster03);
}
3.在com.zzw.spring.bean.Monster
中介绍方法重载
通过index属性来区分是第几个参数;
通过type属性来区分是什么类型(按照顺序, 这是可以的)
💖通过p名称空间配置bean
1.src/beans.xml
增加如下配置
xmlns:p=“http://www.springframework.org/schema/p”
<!--通过p名称空间来配置bean
将光标放在p这个位置, 输入alt+enter, 就会自动的添加xmlns.
有时需要多来几次, 有个识别的过程
-->
<bean class="com.zzw.spring.bean.Monster" id="monster06"
p:monsterId="400"
p:name="天蓬元帅"
p:skill="掌管十万天军"
/>
2.com/zzw/spring/test/SpringBeanTest.java
新增setBeanByP
方法
public class SpringBeanTest {
//演示通过p名称空间来设置属性
@Test
public void setBeanByP() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
Monster monster06 = ioc.getBean("monster06", Monster.class);
System.out.println("monster06=" + monster06);
}
}
💖通过ref配置bean
引用注入其它bean对象
在spring的ioc容器, 可以通过ref来实现bean对象的相互引用[ref全称: reference]
1.src/beans.xml
增加如下配置
<!--配置MemberDaoImpl对象-->
<bean class="com.zzw.spring.dao.MemberDaoImpl" id="memberDao"/>
<!--
配置MemberServiceImpl对象
1.ref="memberDao"表示 MemberServiceImpl对象属性memberDao引用的对象是id="memberDao"的对象
2.这里就体现出spring容器的依赖注入
3.注意: 在spring容器中, 它是作为一个整体来执行的, 即如果引用到了一个bean对象, 对配置的顺序没有要求
4.建议还是按顺序. 好处是在阅读的时候, 比较方便
-->
<bean class="com.zzw.spring.service.MemberServiceImpl" id="memberService">
<property name="memberDao" ref="memberDao"/>
</bean>
2.新建com.zzw.spring.service.MemberServiceImpl
public class MemberServiceImpl {
private MemberDaoImpl memberDao;
public MemberDaoImpl getMemberDao() {
return memberDao;
}
public void setMemberDao(MemberDaoImpl memberDao) {
this.memberDao = memberDao;
}
public void add() {
System.out.println("MemberServiceImpl add方法被调用...");
memberDao.add();
}
}
3.新建com.zzw.spring.dao.MemberDaoImpl
public class MemberDaoImpl {
public MemberDaoImpl() {
System.out.println("MemberDaoImpl 构造器...");
}
public void add() {
System.out.println("MemberDaoImpl add方法被执行");
}
}
4.测试: com/zzw/spring/test/SpringBeanTest.java
新增setBeanByRef
方法
public class SpringBeanTest {
//通过ref来设置bean属性
@Test
public void setBeanByRef() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
MemberServiceImpl memberService = ioc.getBean("memberService", MemberServiceImpl.class);
memberService.add();
}
}
💖通过内部bean配置属性
引用/注入内部bean对象
在spring的ioc容器, 可以直接配置内部bean对象
1.src/beans.xml
增加如下配置
<!--配置MemberServiceImpl对象-使用内部bean-->
<bean class="com.zzw.spring.service.MemberServiceImpl" id="memberService2">
<!--自己配置一个内部bean-->
<property name="memberDao">
<bean class="com.zzw.spring.dao.MemberDaoImpl"/>
</property>
</bean>
2.com/zzw/spring/test/SpringBeanTest.java
新增setBeanByPro
方法
public class SpringBeanTest {
//通过内部bean, 设置属性
@Test
public void setBeanByPro() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
MemberServiceImpl memberService2 = ioc.getBean("memberService2", MemberServiceImpl.class);
memberService2.add();
}
}
💖对集合数组属性进行配置
●引用/注入 集合/数据类型
1.主要掌握List / Map / Properties
三种集合的使用
2.Properties是Hashtable的子类, 是key-value
的形式
3.这里的properties
的k-v
, 都是String
类型
需求: 在spring的ioc容器中, 如何给bean对象的 集合/数组 类型的属性赋值
●代码实现
1.新建com.zzw.spring.bean.Master
public class Master {
private String name;//主人名字
private List<Monster> monsterList;
private Map<String, Monster> monsterMap;
private Set<Monster> monsterSet;
//数组
private String[] monsterName;
//Java基础
//这个Properties 是HashMap的子类, 是key-value的存放形式
//这里Properties key和value 都是String
private Properties properties;
//getter, setter方法
}
💕对List属性进行配置
1.src/beans.xml
增加如下配置
<!--配置Master对象
体会spring容器配置的特点 依赖注入
-->
<bean class="com.zzw.spring.bean.Master" id="master">
<property name="name" value="太上老君"/>
<!--给list属性赋值-->
<property name="monsterList">
<list>
<!--引用的方式加入的-->
<ref bean="monster03"/>
<ref bean="monster04"/>
<!--内部bean, 不再建议id-->
<bean class="com.zzw.spring.bean.Monster"
p:monsterId="300"
p:name="狮驼岭"
p:skill="紫金葫芦"
/>
</list>
</property>
</bean>
2.测试: com/zzw/spring/test/SpringBeanTest.java
新增setBeanByCollection
方法
public class SpringBeanTest {
//给集合/数组属性进行赋值
@Test
public void setBeanByCollection() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
Master master = ioc.getBean("master", Master.class);
System.out.println("master=" + master);
}
}
💕对Map属性进行配置
1.src/beans.xml
增加如下配置
<!--配置Master对象
体会spring容器配置的特点 依赖注入 非常灵活
-->
<bean class="com.zzw.spring.bean.Master" id="master">
<property name="name" value="太上老君"/>
<!--给list属性赋值-->
<!--给map属性赋值-->
<property name="monsterMap">
<map>
<entry>
<key>
<value>monster04</value>
</key>
<!--这里使用的是外部的bean, 引入-->
<ref bean="monster04"/>
</entry>
<entry>
<key>
<value>monster03</value>
</key>
<!--内部bean, 不再建议id-->
<bean class="com.zzw.spring.bean.Monster"
p:monsterId="300"
p:name="狮驼岭"
p:skill="紫金葫芦~"
/>
</entry>
</map>
</property>
</bean>
2.测试: com/zzw/spring/test/SpringBeanTest.java
的setBeanByCollection
方法
public class SpringBeanTest {
//给集合/数组属性进行赋值
@Test
public void setBeanByCollection() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
Master master = ioc.getBean("master", Master.class);
System.out.println("master=" + master);
}
}
💕对Set属性进行配置
1.src/beans.xml
增加如下配置
<!--配置Master对象
体会spring容器配置的特点 依赖注入 非常灵活
-->
<bean class="com.zzw.spring.bean.Master" id="master">
<property name="name" value="太上老君"/>
<!--给list属性赋值-->
<!--给map属性赋值-->
<!--给set属性赋值-->
<property name="monsterSet">
<set>
<!--这里使用的是外部的bean, 引入-->
<ref bean="monster05"/>
<ref bean="monster06"/>
<!--内部bean, 不再建议id-->
<bean class="com.zzw.spring.bean.Monster"
p:monsterId="300"
p:name="狮驼岭"
p:skill="紫金葫芦~"
/>
</set>
</property>
</bean>
2.测试: com/zzw/spring/test/SpringBeanTest.java
的setBeanByCollection
方法
public class SpringBeanTest {
//给集合/数组属性进行赋值
@Test
public void setBeanByCollection() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
Master master = ioc.getBean("master", Master.class);
System.out.println("master=" + master);
}
}
💕对Array属性进行配置
1.src/beans.xml
增加如下配置
<!--配置Master对象
体会spring容器配置的特点 依赖注入 非常灵活
-->
<bean class="com.zzw.spring.bean.Master" id="master">
<property name="name" value="太上老君"/>
<!--给数组属性赋值
补充: array标签中使用 value 还是 bean, ref ...要根据业务来决定
这里的monsterName是字符串
-->
<property name="monsterName">
<array>
<value>六耳猕猴</value>
<value>东海龙王</value>
<value>红孩儿</value>
</array>
</property>
</bean>
2.测试: com/zzw/spring/test/SpringBeanTest.java
的setBeanByCollection
方法
public class SpringBeanTest {
//给集合/数组属性进行赋值
@Test
public void setBeanByCollection() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
Master master = ioc.getBean("master", Master.class);
System.out.println("master=" + master);
}
}
💕对Properties属性进行配置
1.src/beans.xml
增加如下配置
<!--配置Master对象
体会spring容器配置的特点 依赖注入 非常灵活
-->
<bean class="com.zzw.spring.bean.Master" id="master">
<property name="name" value="太上老君"/>
<!--给list属性赋值-->
<!--给map属性赋值-->
<!--给set属性赋值-->
<!--给数组属性赋值-->
<!--对properties属性进行赋值 结构k(String)-v(String) -->
<property name="properties">
<props>
<prop key="username">root</prop>
<prop key="password">123456</prop>
<prop key="email">978964140@qq.com</prop>
</props>
</property>
</bean>
2.测试: com/zzw/spring/test/SpringBeanTest.java
的setBeanByCollection
方法
public class SpringBeanTest {
//给集合/数组属性进行赋值
@Test
public void setBeanByCollection() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
Master master = ioc.getBean("master", Master.class);
System.out.println("master=" + master);
}
}