一、基于XML创建Bean
Bean管理指的是两个操作 Spring创建对象
和 Spring注入属性
Bean实现这两个操作有两种方式:XML配置文件
和 注解方式
创建之前需要引入4个依赖
spring-beans-5.1.5.RELEASE.jar
spring-context-5.1.5.RELEASE.jar
spring-core-5.1.5.RELEASE.jar
spring-expression-5.1.5.RELEASE.jar
1) 创建普通对象
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<!-- bean 为创建一个对象 -->
<bean id="book" class="com.zhiyou100.model.Book"></bean>
<bean id="book2" class="com.zhiyou100.model.Book"></bean>
</beans>
2) 基于setter方式
<!-- property 在这里面 可以直接为对象添加属性 基于setter方式 -->
<!-- 通过set/get方法创建对象 -->
<bean id="people3" class="com.zhiyou100.model.People">
<property name="id" value="24"></property>
<property name="name" value="人类"></property>
</bean>
3) 基于构造方法
<!-- 通过有参构造方法 -->
<bean id="people4" class="com.zhiyou100.model.People">
<constructor-arg index="0" value="41"></constructor-arg>
<constructor-arg index="1" value="你好"></constructor-arg>
</bean>
4) 注入空值和特殊符号
<!--null 值-->
<property name="address">
<null />
</property>
<!--属性值包含特殊符号-->
<!--属性值包含特殊符号
1 把<>进行转义 < >
2 把带特殊符号内容写到 CDATA
-->
<property name="address">
<value><![CDATA[<<南京>>]]></value>
</property>
5) 注入外部Bean
<bean id="userService" class="com.atguigu.spring5.service.UserService">
<!--注入 userDao 对象
name 属性:类里面属性名称
ref 属性:创建 userDao 对象 bean 标签 id 值 -->
<property name="userDao" ref="userDaoImpl"></property>
</bean>
<bean id="userDaoImpl" class="com.atguigu.spring5.dao.UserDaoImpl"></bean>
6) 注入内部Bean
<!-- 一个对象里面包含另一个对象-->
<bean id="book4" class="com.zhiyou100.model.Book">
<property name="id" value="23"></property>
<property name="name" value="水浒传"></property>
<property name="author">
<bean class="com.zhiyou100.model.People">
<property name="id" value="31"></property>
<property name="name" value="哈哈哈"></property>
<property name="sex" value="男"></property>
</bean>
</property>
</bean>
7) 级联赋值
<bean id="emp" class="com.atguigu.spring5.bean.Emp">
<!--设置两个普通属性-->
<property name="ename" value="lucy"></property>
<property name="gender" value="女"></property>
<!--级联赋值-->
<property name="dept" ref="dept"></property>
<property name="dept.dname" value="技术部"></property>
</bean>
<bean id="dept" class="com.atguigu.spring5.bean.Dept">
<property name="dname" value="财务部"></property>
</bean>
8) 注入数组、List、Map
<!--1 集合类型属性注入-->
<bean id="stu" class="com.atguigu.spring5.collectiontype.Stu">
<!--数组类型属性注入-->
<property name="courses">
<array>
<value>java 课程</value>
<value>数据库课程</value>
</array>
</property>
<!--list 类型属性注入-->
<property name="list">
<list>
<value>张三</value>
<value>小三</value>
</list>
</property>
<!--map 类型属性注入-->
<property name="maps">
<map>
<entry key="JAVA" value="java"></entry>
<entry key="PHP" value="php"></entry>
</map>
</property>
<!--set 类型属性注入-->
<property name="sets">
<set>
<value>MySQL</value>
<value>Redis</value>
</set>
</property>
</bean>
二、beans子元素
XML配置文件可以使用的基础标签
1.bean 元素
注入一个普通bean最基础的标签,就不多介绍了
<bean></bean>
2.beans 元素
【作用】:与元素之间可以相互嵌套
<?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">
<beans>
<description>beans 与 beans 嵌套使用</description>
</beans>
</beans>
3.alias 元素
【作用】:设置别名
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<alias name="name" alias="book" />
</beans>
4.import 元素
【作用】:引入另一个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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<import resource="bean.xml" />
</beans>
5.description 元素
【作用】:描述配置文件的作用
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<description>描述作用:当前这个XML配置的作用,不能重复出现,必须在第一个元素位置</description>
</beans>
三、beans的属性
可以配置的属性
1.profile 属性
【作用】:区分不同环境下的类加载
定义不同环境下的2个相同名称的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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<beans profile="dev">
<bean id="book" class="com.h3c.ss.Book">
<constructor-arg index="0" value="Dev环境"></constructor-arg>
</bean>
</beans>
<beans profile="prod">
<bean id="book" class="com.h3c.ss.Book">
<constructor-arg index="0" value="prod环境"></constructor-arg>
</bean>
</beans>
</beans>
获取
@SpringBootTest
// 扫描配置文件
@ContextConfiguration(locations = "classpath:bean.xml")
// 设置环境
@ActiveProfiles("prod")
public class Test {
@Autowired
private Book book;
@org.junit.jupiter.api.Test
public void m3() {
System.out.println(book);
}
}
2.default-lazy-init 属性
【作用】:容器级别的延迟加载,定义整个 范围内的 的延迟加载方式(在使用时加载)
<?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"
default-lazy-init="true">
</beans>
3.default-init-method 属性
【作用】:容器级别的初始化方法,定义整个 范围内的 的初始化方法
4.default-destroy-method 属性
【作用】:容器级别的销毁方法,定义整个 范围内的 的销毁方法
4.default-autowire 属性
【作用】:容器级别的依赖注入方式,定义整个 范围内的
5.default-autowire-candidates 属性
定义整个 范围内的 是否依赖注入
6.default-merge 属性
四、bean属性
可以配置的属性
1.id 属性
bean在spring容器的唯一标识,spring容器中不可能同时存在两个相同的id。
2.name属性
设置别名,在BeanFactory的getBean(“name”)中可以获取相应的bean。
需要注意的是,bean属性的id和name,是bean的唯一标识,同一个spring的配置文件中,不同bean的id和name是不能相同的。否则会报错。不同的spring配置文件中,id和name可以重复。此时spring针对相同的id或name采取的策略是根据DefaultListableBeanFactory类中的allowBeanDefinitionOverriding属性值来判断的。默认为true,即相同的id或name会被覆盖。如果设置为false,则会抛出异常。
通过阅读spring初始化源码可以知道,spring是获取到spring的配置文件后,利用循环遍历读取配置信息的。所以不同的配置文件会循环多次,后面的覆盖前面的。
利用这个特性,我们可以通过spring配置文件的替换或覆盖,来做版本的更新。
3.class 属性
类的全限定名(类名+包名),用“.”号连接
4.abstract + parent 属性
abstract
:设置bean是否为抽象类,默认为false。如果为true,则该bean不会被实例化。那不被实例化,还定义它有啥用呢?这就要讲parent属性了。
parent
:bean标签中的parent属性和java中的继承有些类似,但又不一样。parent属性可以指定一个类。那么bean和parent指定的类可以是继承关系,也可以不是继承关系。 只要指定了parent,那么parent类中的属性名,就可以自动继承到bean类中了。当然bean也可以对parent的属性进行覆盖。同时可以扩展其他的属性。
注意:
好多人将parent指向的类说是子类继承了父类,其实说法不正确,正确的说法应该是子bean父bean而不是子类父类,因为如果子bean指定的类已经继承了其他的类,那么在这里一样可以有一个父bean,(如果真像大家说的那样那不成多重继承了吗)
必要条件:
- 子bean必须与父bean保持兼容,也就是说子bean中必须有父bean定义的所有属性。
- 父bean必须是抽象bean或者定义lazy-init=true也就是不让bean工厂实例化该bean
应用:
子类可以继承父类中的属性,这样如果存在多个,可以重复使用,类似于代码抽取,子类把父类中的属性拿过来以后,然后子类可以继续扩展
5.scope 属性
默认为单例,即BeanFactory的getBean都返回同一个对象。可以设置为多例,每次getBean返回不同的对象。这也就是为何多例不实例化的原因了。
singleton:表示整个IOC容器共享一个Bean,也就是说每次说每次通过getBean获取的bean都是同一个。
prototype:每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。
request:每次HTTP请求将会生成各自的bean实例
session:每次会话请求对应一个bean实例
singleton和prototype经常使用,request和session基本不使用。
6.lazy-init 属性
lazy-init 设置只对scop属性为singleton的bean起作用,非单例不实例化
lazy-init=”false” 立即加载, 在spring启动时,立刻进行实例.
lazy-init=”true” 延迟加载 ,设置为true的bean将不会在ApplicationContext启动时提前被实例化,而是在第一次向容器通过getBean索取bean时实例化的。
如果一个设置了立即加载的bean1,引用了一个延迟加载的bean2,那么bean1在容器启动时被实例化,而bean2由于被bean1引用,所以也被实例化,这种情况也符合延迟加载的bean在第一次调用时才被实例化的规则。
7.init-method + destroy-method 属性
初始化方法 + 销毁方法
8.depends-on 属性
它的作用是一个bean实例化的过程需要依赖于另一个bean的初始化,也就是说被依赖的bean将会在需要依赖的bean初始化之前加载。多个依赖bean之间用","号分割;
被依赖的类,不一定会被引用到bean的属性,只是先于这个bean初始化。当然销毁时,也是后于这个bean销毁。当遇到类必须有先后加载顺序场景时,可以应用此属性。
9.autowire-candidate 属性(用的少)
默认为true。如果设置为false,则该bean将不能通过依赖注入,传给需要这个对象类型的地方。也就是@Autowired等注解,无法依赖注入该对象。
应用:我们在开发中,更换service实现类时,又想保留原service的实现类,那就可以把该属性设置为false。那么依赖注入service时,spring就会把新的service实现类注入进去,旧的不会被注入。
10.autowire 属性(不推荐)
和@Autowired作用一样,只不过是在xml里的bean里配置的属性,都是用于依赖注入另一个bean作为属性。不推荐使用此属性,因为这么定义类的注入关系不能一目了然,不方便项目的维护。
11.primary 属性
autowire-candidate属性提到,当一个类型的对象有多个时,可以设置为true,不对这个bean进行依赖注入。
我们也可以不把这个bean屏蔽掉,而是设置primary,来定义首选依赖注入哪个类。当然primary属性只能设置相同类型的一个bean,否则会出问题。
12.factory-method + factory-bean 属性
【factory-method】
我们创建一个bean常用的是指定class属性,然后spring框架会通过其构造方法进行bean的初始化,例如:
<!--该bean的初始化会通过指定class的构造方法创建-->
<bean id="book" class="com.h3c.ss.Book" />
而factory-method
提供的是工厂方法模式,其会指向该class类中的一个静态方法,通过其完成bean的初始化
<!--该bean的初始化就不会通过构造方法,而是通过factory-method指定的静态方法进行初始化-->
<!--必须是静态方法-->
<bean id="book" class="com.h3c.ss.Book" factory-method="createInstance" />
<!--若这个工厂方法需要参数的话,使用constructor-arg 元素来指定它的参数-->
<bean id="book3" class="com.h3c.ss.Book" factory-method="createInstance">
<constructor-arg index="0" value="world"></constructor-arg>
</bean>
【示例】
@Data
public class Book {
private String book;
public Book() {
}
public Book(String book) {
this.book = book;
}
// 定义的静态方法,必须是静态方法
public static String createInstance(){
return "hello";
}
// 带参数的
public static String createInstance(String str) {
return str;
}
}
private static void m4() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Object book1 = context.getBean("book1");
Object book2 = context.getBean("book2");
Object book3 = context.getBean("book3");
System.out.println(book1);
System.out.println(book2);
System.out.println(book3);
}
// 结果
Book(book=null)
hello
world
【factory-bean】
在使用factory-method时,可以使用factory-bean来代替class属性,这个工厂方法将会是通过指定bean名称调用getBean返回对象的一个实例方法。
<!--通过factory-bean指定具体bean-->
<!--factory-method指定调用的方法, 必须是非静态方法-->
<bean id="book4" factory-method="createInstance3" factory-bean="book1" />
【示例】
@Data
public class Book {
private String book;
public Book() {
}
public Book(String book) {
this.book = book;
}
// 必须是非静态方法
public String createInstance3(){
return "非静态方法";
}
}
private static void m4() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Object book4 = context.getBean("book4");
System.out.println(book4);
}
// 结果
非静态方法
五、bean子元素
可以使用的元素
1.constructor-arg 元素
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5hkRh46o-1679923198591)(E:\Gitee\Spring\image-20221109164039779.png)]
constructor-arg标签属性:
-
name属性:通过参数名找到参数列表中对应参数
-
index属性:通过参数在参数列表中的索引找到参数列表中对应参数,index从0开始:
-
type属性:通过参数数据类型找到参数列表中对应参数
-
value属性:设置参数列表参数对应的值,用于设定基本数据类型和String类型的数据
-
ref属性:如果参数值为非基本数据类型,则可通过ref为参数注入值,其值为另一个bean标签id或name属性的属性值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vwTqFhK9-1679923198592)(E:\Gitee\Spring\image-20221109164343742.png)]
constructor-arg子标签:
- ref子标签:对应ref属性,该标签name属性的属性值为另一个bean标签id或name属性的属性值;
- value子标签:对应value属性,用于设置基本数据类型或String类型的参数值;
- list子标签:为数组或List类型的参数赋值
- set子标签:为Set集合类型参数赋值
- map子标签:为Map集合类型参数赋值
- props子标签:为Properties类型的参数赋值
2.qualifier 元素
【作用】:指定注入bean的名称
<qualifier type="" value=""></qualifier>
3.description 元素
【作用】:设置该bean的描述
<description></description>
4.property 元素
属性注入
<bean id="book1" class="com.h3c.ss.Book">
<property name="name" value="新华图书" ></property>
</bean>
5.replaced-method 元素
replaced-method可以让我们通过配置完成对原有的bean中的方法实现进行重新替换。
该标签name属性的属性值为另一个bean标签id或name属性的属性值;
- value子标签:对应value属性,用于设置基本数据类型或String类型的参数值;
- list子标签:为数组或List类型的参数赋值
- set子标签:为Set集合类型参数赋值
- map子标签:为Map集合类型参数赋值
- props子标签:为Properties类型的参数赋值
2.qualifier 元素
【作用】:指定注入bean的名称
<qualifier type="" value=""></qualifier>
3.description 元素
【作用】:设置该bean的描述
<description></description>
4.property 元素
属性注入
<bean id="book1" class="com.h3c.ss.Book">
<property name="name" value="新华图书" ></property>
</bean>
5.replaced-method 元素
replaced-method可以让我们通过配置完成对原有的bean中的方法实现进行重新替换。