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
<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 id="book" class="com.zhiyou100.model.Book">bean>
<bean id="book2" class="com.zhiyou100.model.Book">bean>
beans>
<bean id="people3" class="com.zhiyou100.model.People">
<property name="id" value="24">property>
<property name="name" value="人类">property>
bean>
<bean id="people4" class="com.zhiyou100.model.People">
<constructor-arg index="0" value="41">constructor-arg>
<constructor-arg index="1" value="你好">constructor-arg>
bean>
<property name="address">
<null />
property>
<property name="address">
<value>>]]>value>
property>
<bean id="userService" class="com.atguigu.spring5.service.UserService">
<property name="userDao" ref="userDaoImpl">property>
bean>
<bean id="userDaoImpl" class="com.atguigu.spring5.dao.UserDaoImpl">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>
<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>
<bean id="stu" class="com.atguigu.spring5.collectiontype.Stu">
<property name="courses">
<array>
<value>java 课程value>
<value>数据库课程value>
array>
property>
<property name="list">
<list>
<value>张三value>
<value>小三value>
list>
property>
<property name="maps">
<map>
<entry key="JAVA" value="java">entry>
<entry key="PHP" value="php">entry>
map>
property>
<property name="sets">
<set>
<value>MySQLvalue>
<value>Redisvalue>
set>
property>
bean>
注入一个普通bean最基础的标签,就不多介绍了
<bean>bean>
【作用】:与元素之间可以相互嵌套
<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>
【作用】:设置别名
<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>
【作用】:引入另一个XML配置
<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>
【作用】:描述配置文件的作用
<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>
【作用】:区分不同环境下的类加载
定义不同环境下的2个相同名称的bean标签
<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);
}
}
【作用】:容器级别的延迟加载,定义整个 范围内的 的延迟加载方式(在使用时加载)
<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>
【作用】:容器级别的初始化方法,定义整个 范围内的 的初始化方法
【作用】:容器级别的销毁方法,定义整个 范围内的 的销毁方法
【作用】:容器级别的依赖注入方式,定义整个 范围内的
定义整个 范围内的 是否依赖注入
bean在spring容器的唯一标识,spring容器中不可能同时存在两个相同的id。
设置别名,在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配置文件的替换或覆盖,来做版本的更新。
类的全限定名(类名+包名),用“.”号连接
abstract
:设置bean是否为抽象类,默认为false。如果为true,则该bean不会被实例化。那不被实例化,还定义它有啥用呢?这就要讲parent属性了。
parent
:bean标签中的parent属性和java中的继承有些类似,但又不一样。parent属性可以指定一个类。那么bean和parent指定的类可以是继承关系,也可以不是继承关系。 只要指定了parent,那么parent类中的属性名,就可以自动继承到bean类中了。当然bean也可以对parent的属性进行覆盖。同时可以扩展其他的属性。
注意:
好多人将parent指向的类说是子类继承了父类,其实说法不正确,正确的说法应该是子bean父bean而不是子类父类,因为如果子bean指定的类已经继承了其他的类,那么在这里一样可以有一个父bean,(如果真像大家说的那样那不成多重继承了吗)
必要条件:
应用:
子类可以继承父类中的属性,这样如果存在多个,可以重复使用,类似于代码抽取,子类把父类中的属性拿过来以后,然后子类可以继续扩展
默认为单例,即BeanFactory的getBean都返回同一个对象。可以设置为多例,每次getBean返回不同的对象。这也就是为何多例不实例化的原因了。
singleton:表示整个IOC容器共享一个Bean,也就是说每次说每次通过getBean获取的bean都是同一个。
prototype:每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。
request:每次HTTP请求将会生成各自的bean实例
session:每次会话请求对应一个bean实例
singleton和prototype经常使用,request和session基本不使用。
lazy-init 设置只对scop属性为singleton的bean起作用,非单例不实例化
lazy-init=”false” 立即加载, 在spring启动时,立刻进行实例.
lazy-init=”true” 延迟加载 ,设置为true的bean将不会在ApplicationContext启动时提前被实例化,而是在第一次向容器通过getBean索取bean时实例化的。
如果一个设置了立即加载的bean1,引用了一个延迟加载的bean2,那么bean1在容器启动时被实例化,而bean2由于被bean1引用,所以也被实例化,这种情况也符合延迟加载的bean在第一次调用时才被实例化的规则。
初始化方法 + 销毁方法
它的作用是一个bean实例化的过程需要依赖于另一个bean的初始化,也就是说被依赖的bean将会在需要依赖的bean初始化之前加载。多个依赖bean之间用","号分割;
被依赖的类,不一定会被引用到bean的属性,只是先于这个bean初始化。当然销毁时,也是后于这个bean销毁。当遇到类必须有先后加载顺序场景时,可以应用此属性。
默认为true。如果设置为false,则该bean将不能通过依赖注入,传给需要这个对象类型的地方。也就是@Autowired等注解,无法依赖注入该对象。
应用:我们在开发中,更换service实现类时,又想保留原service的实现类,那就可以把该属性设置为false。那么依赖注入service时,spring就会把新的service实现类注入进去,旧的不会被注入。
和@Autowired作用一样,只不过是在xml里的bean里配置的属性,都是用于依赖注入另一个bean作为属性。不推荐使用此属性,因为这么定义类的注入关系不能一目了然,不方便项目的维护。
autowire-candidate属性提到,当一个类型的对象有多个时,可以设置为true,不对这个bean进行依赖注入。
我们也可以不把这个bean屏蔽掉,而是设置primary,来定义首选依赖注入哪个类。当然primary属性只能设置相同类型的一个bean,否则会出问题。
【factory-method】
我们创建一个bean常用的是指定class属性,然后spring框架会通过其构造方法进行bean的初始化,例如:
<bean id="book" class="com.h3c.ss.Book" />
而factory-method
提供的是工厂方法模式,其会指向该class类中的一个静态方法,通过其完成bean的初始化
<bean id="book" class="com.h3c.ss.Book" factory-method="createInstance" />
<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返回对象的一个实例方法。
<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);
}
// 结果
非静态方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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子标签:
【作用】:指定注入bean的名称
<qualifier type="" value="">qualifier>
【作用】:设置该bean的描述
<description>description>
属性注入
<bean id="book1" class="com.h3c.ss.Book">
<property name="name" value="新华图书" >property>
bean>
replaced-method可以让我们通过配置完成对原有的bean中的方法实现进行重新替换。
该标签name属性的属性值为另一个bean标签id或name属性的属性值;
【作用】:指定注入bean的名称
<qualifier type="" value="">qualifier>
【作用】:设置该bean的描述
<description>description>
属性注入
<bean id="book1" class="com.h3c.ss.Book">
<property name="name" value="新华图书" >property>
bean>
replaced-method可以让我们通过配置完成对原有的bean中的方法实现进行重新替换。