一、Spring配置说明
1.别名
- 方式一:alias 标签
<bean id="user" class="com.gaolang.pojo.User">
<property name="name" value="高朗"/>
</bean>
<!--前面bean的别名-->
<alias name="user" alias="newUser"/>
- 方式二:bean标签的name属性,且更高级,可以取多个别名,逗号或空格等隔开
<bean id="user" class="com.gaolang.pojo.User" name="newUser">
<property name="name" value="高朗"/>
</bean>
- 小结:
别名:如果添加了别名,我们可以使用别名获取到这个对象
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//别名获取对象
User user = (User) context.getBean("newUser");
2.Bean的配置
bean元素的常用属性:
属性名称 | 描述 |
---|---|
id | 是一个 Bean 的唯一标识符,Spring 容器对 Bean 的配置和管理都通过该属性完成 |
name | Spring 容器同样可以通过此属性对容器中的 Bean 进行配置和管理,name 属性中可以为 Bean 指定多个名称,每个名称之间用逗号或分号隔开 |
class | 该属性指定了 Bean 的具体实现类,它必须是一个完整的类名,使用类的全限定名 |
scope | 用于设定 Bean 实例的作用域,其属性值有 singleton(单例)、prototype(原型)、request、session 和 global Session。其默认值是 singleton |
constructor-arg | <bean>元素的子元素,可以使用此元素传入构造参数进行实例化。该元素的 index 属性指定构造参数的序号(从 0 开始),type 属性指定构造参数的类型 |
property | <bean>元素的子元素,用于调用 Bean 实例中的 Set 方法完成属性赋值,从而完成依赖注入。该元素的 name 属性指定 Bean 实例中的相应属性名 |
ref | <property> 和 <constructor-arg> 等元素的子元索,该元素中的 bean 属性用于指定对 Bean 工厂中某个 Bean 实例的引用 |
value | <property> 和 <constractor-arg> 等元素的子元素,用于直接指定一个常量值 |
list | 用于封装 List 或数组类型的依赖注入 |
set | 用于封装 Set 类型属性的依赖注入 |
map | 用于封装 Map 类型属性的依赖注入 |
entry |
3.import
有多个不同的beans.xml可以用import标签导入合并到一个总的applicationContext.xml中,使用的时候,直接使用总的配置就可以了。
<import resource="beans.xml"/>
<import resource="beans2.xml"/>
<import resource="beans3.xml"/>
<import resource="beans4.xml"/>
二、DI依赖注入
- 依赖:bean对象的创建依赖于容器。
- 注入:bean对象中的所有属性,由容器来注入。
1.构造器注入
指 IoC 容器使用构造方法注入被依赖的实例。基于构造器的 DI 通过调用带参数的构造方法实现,每个参数代表一个依赖。
2.set方式注入
指 IoC 容器使用 setter 方法注入被依赖的实例。通过调用无参构造器或无参 static 工厂方法实例化 bean 后,调用该 bean 的 setter 方法,即可实现基于 setter 的 DI。
前面文章有写到构造器和set方式注入:了解Spring框架
不够都是一些比较简单的数据类型的注入,接下来涉及一些其他类型的set方式注入。
包括:String类型,bean,数组,List,Map,Set,null ,Properties
- UserTest.java
package com.gaolang.pojo;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class UserTest {
private String name;
private User user;
private String[] books;
private List<String> hobbys;
private Map<String,String> card;
private Set<String> games;
private String girlfriend;
private Properties info;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String[] getBooks() {
return books;
}
public void setBooks(String[] books) {
this.books = books;
}
public List<String> getHobbys() {
return hobbys;
}
public void setHobbys(List<String> hobbys) {
this.hobbys = hobbys;
}
public Map<String, String> getCard() {
return card;
}
public void setCard(Map<String, String> card) {
this.card = card;
}
public Set<String> getGames() {
return games;
}
public void setGames(Set<String> games) {
this.games = games;
}
public String getGirlfriend() {
return girlfriend;
}
public void setGirlfriend(String girlfriend) {
this.girlfriend = girlfriend;
}
public Properties getInfo() {
return info;
}
public void setInfo(Properties info) {
this.info = info;
}
}
- beans.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.gaolang.pojo.User">
<property name="name" value="高朗"/>
</bean>
<bean id="userT" class="com.gaolang.pojo.UserTest">
<!--String类型注入-->
<property name="name" value="小明"/>
<!--bean 注入-->
<property name="user" ref="user"/>
<!--数组注入-->
<property name="books">
<array>
<value>傅雷家书</value>
<value>红楼梦</value>
<value>水浒传</value>
</array>
</property>
<!--List注入-->
<property name="hobbys">
<list>
<value>打篮球</value>
<value>晨跑</value>
<value>听歌</value>
</list>
</property>
<!--Map注入-->
<property name="card">
<map>
<entry key="身份证" value="123"/>
<entry key="学生证" value="456"/>
<entry key="银行卡" value="789"/>
</map>
</property>
<!--Set注入-->
<property name="games">
<set>
<value>LOL</value>
<value>GAME2</value>
<value>GAME3</value>
</set>
</property>
<!--null注入-->
<property name="girlfriend">
<null/>
</property>
<!--Properties注入
key=value
-->
<property name="info">
<props>
<prop key="driver">VALUE1</prop>
<prop key="url">VALUE2</prop>
<prop key="username">root</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
</beans>
- 测试类MyTest.java
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserTest userT = (UserTest) context.getBean("userT");
System.out.println(userT.toString());
}
}
- 运行结果:
UserTest{name='小明',
user=User{name='高朗'},
books=[傅雷家书, 红楼梦, 水浒传],
hobbys=[打篮球, 晨跑, 听歌],
card={身份证=123, 学生证=456, 银行卡=789},
games=[LOL, GAME2, GAME3], girlfriend='null',
info={password=123456, url=VALUE2, driver=VALUE1, username=root}}
3.拓展方式注入
我们可以用p命名空间和c命名空间,但是不能直接使用,需要导入xml约束:
- p命名空间:使用的是set方式注入,使用的话,需要有set方法
xmlns:p="http://www.springframework.org/schema/p"
- c命名空间:构造器注入,需要有参构造器
xmlns:c="http://www.springframework.org/schema/c"
- p命名空间和c命名空间的具体使用:
userbeans.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--p命名空间注入,可以直接注入属性的值:set注入-->
<bean id="user" class="com.gaolang.pojo.User" p:name="高朗" p:age="18"/>
<!--c命名空间注入,可以直接注入属性的值:构造器注入-->
<bean id="user2" class="com.gaolang.pojo.User" c:name="小明" c:age="20"/>
</beans>
MyTest.java
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
//p命令空间
User user = (User) context.getBean("user");
System.out.println(user.toString());
//c命令空间
User user2 = (User) context.getBean("user2");
System.out.println(user2.toString());
}
运行结果:
User{name='高朗', age=18}
User{name='小明', age=20}
4.bean的作用域
1)singleton
单例模式,使用 singleton 定义的 Bean 在 Spring 容器中只有一个实例,这也是 Bean 默认的作用域。
2)prototype
原型模式,每次通过 Spring 容器获取 prototype 定义的 Bean 时,容器都将创建一个新的 Bean 实例。
3)request
在一次 HTTP 请求中,容器会返回该 Bean 的同一个实例。而对不同的 HTTP 请求,会返回不同的实例,该作用域仅在当前 HTTP Request 内有效。
4)session
在一次 HTTP Session 中,容器会返回该 Bean 的同一个实例。而对不同的 HTTP 请求,会返回不同的实例,该作用域仅在当前 HTTP Session 内有效。
5)global Session
在一个全局的 HTTP Session 中,容器会返回该 Bean 的同一个实例。该作用域仅在使用 portlet context 时有效。
最常用的是第一种和第二种:
- 单例模式:(Spring默认的模式)
scope="singleton"
只有一个对象被创建
<bean id="user" class="com.gaolang.pojo.User" p:name="高朗" p:age="18" scope="singleton"/>
User user = (User) context.getBean("user");
User user2 = (User) context.getBean("user");
user和user2是同一个对象,hashcode相同。
- 原型模式:
scope="prototype"
每次从容器中get的时候,都会产生一个新对象。
<bean id="user" class="com.gaolang.pojo.User" p:name="高朗" p:age="18" scope="prototype"/>
User user = (User) context.getBean("user");
User user2 = (User) context.getBean("user");
System.out.println(user==user2);
user和user2是不同的对象