【Spring】03 XML配置
Alias别名设置
可以为一个Bean的ID再设置一个ID
多一个可用标识,大概...
在获取实例注入参数时,两个标识都可以使用
除了Alias可以设置别名之外,Bean的标签本身也可以设置第二别名
name属性还可以设置多个别名,使用的分隔符没有限制
所以目前得出的结论是,别名标签是早期Spring设计出的一个功能,
但是在后面的版本被其他更强大的功能替代了,
所以放在现在看来,别名标签的用途似乎非常鸡肋
Import 多容器合并导入
在快速入门的测试类中,Spring官方给出的是一个多容器文件注入
其实多个容器文件可以使用此标签合并至一个容器中统一处理
实际的开发用途可以表现在多人协作开发中
依赖注入 Dependency Injection
依赖 即:对象的创建依赖于Spring容器实现
注入 即:对象的属性由Spring容器注入
三种方式:
构造器注入
Setter方法注入
拓展方式注入
构造器注入
1、调用带参构造器注入值,name表示按参数的标识符注入
2、也可以按参数列表的形式,直接取参数的索引位置注入
3、根据参数的类型注入,如果定义多个同类型参数如何才能分辨呢?
4、根据引用来注入,此方式是引用Spring容器的其他Bean的ID
由于还未注册其他Bean,约束提示语法错误
Setter方法注入
设置一个新的实体类
package cn.dai.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; /** * @author ArkD42 * @file Spring * @create 2020 - 05 - 04 - 19:38 */ @Data @NoArgsConstructor @AllArgsConstructor public class Person { private String name; private Address address; private String[] books; private List<String> hobbys; private Map<String,Object> card; private Set<String> game; private String wife; private Properties info; }
里面基本包括了所有的数据类型
常用的数据类型
<property name="name" value="arkD42"/>
引用类型,被引用的类必须在Bean容器中注册才能被引用
<property name="address" ref="ads"/>
数组类型
<property name="books"> <array> <value>编程思想 </value> <value>高效的Java </value> <value>Think in Java </value> <value>C Prime Plus </value> <value>TCP/IP Agreement</value> </array> </property>
List集合
<property name="hobbys"> <list> <value>骑车</value> <value>敲代码</value> <value>学习</value> </list> </property>
Map集合
<property name="card"> <map> <entry key="ID" value="336696219682038"/> <entry key="BankID" value="3365v234xcv2324xrw2343"/> </map> </property>
空赋值
<property name="wife"> <!-- 空字符串 <property name="wife" value="" /> --> <null/> <!-- <null></null> --> </property>
Set集合
<property name="game"> <set> <value>LOL</value> <value>CSGO</value> <value>COD</value> </set> </property>
配置类
<property name="info"> <props> <prop key="username">root</prop> <prop key="password">123456</prop> </props> </property>
拓展方式注入
需要约束支持
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
实体类
package cn.dai.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @author ArkD42 * @file Spring * @create 2020 - 05 - 04 - 21:07 */ @Data @AllArgsConstructor @NoArgsConstructor public class User { private String username; private String password; }
C命名【构造器命名注入】
可以使用C约束构造器参数注入
<bean id="user" class="cn.dai.pojo.User" c:username="root" c:password="123456"/>
除了直接按参数标识符注入之外
构造器跟标签一样支持了
1、参数索引注入
2、引用类型注入【Bean注入】
P命名【字段命名注入】
可以使用P约束直接字段赋值注入
<bean id="user" class="cn.dai.pojo.User" p:username="root" p:password="123456"/>
P属于Setter方法注入,不是参数列表
但是也有引用式的Bean注入
P & C就是字段和构造器的简写
Spring称这是一种更为快捷的注入方式,
但是如果是复杂类型的数据注入,最好还是以XML标签的形式配置
Bean的作用域 Scope
Singleton单例模式
当一个bean的作用域为Singleton,那么Spring IoC容器中只会存在一个共享的bean实例,
并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。
Singleton是单例类型,就是在创建起容器时就同时自动创建了一个bean的对象,
不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。
注意,Singleton作用域是Spring中的缺省作用域。
要在XML中将bean定义成singleton,可以这样配置:
Prototype 原型模式
当一个bean的作用域为Prototype,表示一个bean定义对应多个对象实例。
Prototype作用域的bean会导致在每次对该bean请求
(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)
时都会创建一个新的bean实例。
Prototype是原型类型,它在我们创建容器的时候并没有实例化,
而是当我们获取bean的时候才会去创建一个对象,
而且我们每次获取到的对象都不是同一个对象。
根据经验,对有状态的bean应该使用prototype作用域,
而对无状态的bean则应该使用singleton作用域。在XML中将bean定义成prototype,可以这样配置:
1、Scope属性默认是单例的,每次获取的都是同一个对象
2、原型模式每次从容器获取的都是不同的对象
3、其余的Session、Request、Application、Socket都是在Web应用中使用
自动装配、自动匹配 AutoWired
Spring可以依靠这一特性给对象自动的匹配属性
这也是Bean依赖的一种方式
三种自动装配方式:
1、XML显示配置
2、Java显示配置
3、缺省配置
测试环境:
猫类 & 狗类 & 人类
public class Cat { public void meow(){ System.out.println("喵喵喵???"); } }
public class Dog { public void bark(){ System.out.println("汪汪汪???"); } }
@Data @NoArgsConstructor @AllArgsConstructor public class Person { private Cat cat; private Dog dog; private String name; }
bean容器
<?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="cat" class="cn.dai.pojo.Cat"/> <bean id="dog" class="cn.dai.pojo.Dog"/> <bean id="person" class="cn.dai.pojo.Person"> <property name="name" value="ajj" /> <property name="cat" ref="cat"/> <property name="dog" ref="dog"/> </bean> </beans>
测试
public class AutoWiredTest { @Test public void awt(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml"); Person person = applicationContext.getBean("person", Person.class); System.out.println(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.xsd"> <bean id="cat" class="cn.dai.pojo.Cat"/> <bean id="dog" class="cn.dai.pojo.Dog"/> <bean id="person" class="cn.dai.pojo.Person" autowire="byName"> <property name="name" value="ajj" /> </bean> </beans>
autowire="byName" 根据Bean的ID或者其别名进行自动装配
标识符能在容器中被查找到,匹配了和Person类的setter方法所注入的参数标识
将狗类的ID故意写错,Spring容器将无法识别到
autowire="byType" 根据类型自动查找,即是名称写错也会进行匹配
并正确的注入
但是ByType的问题就是,容器中不可以存在多个相同类型的Bean,
这对ByType来说造成了歧义
总而言之:
ByName 按Bean的标识 + 别名 进行匹配,
必须和setter方法的参数标识一样,但是Bean可以设置多个
ByType 按Bean的类型 匹配
必须保证容器的Bean是唯一的