Spring5-IOC操作Bean管理(FactoryBean)
1 普通bean和工厂bean(FactoryBean)的区别
1.Spring有两种bean,一种是普通bean,另一种是工厂bean(FactoryBean)
2.普通bean:在配置文件中定义bean类型就是返回类型
3.工厂bean:在配置文件中定义的bean类型可以和返回值类型不一致
2.案例操作
第一步:创建类,让这个类作为工厂bean,实现接口FactoryBean
第二步:实现接口里面的方法,在实现的方法中定义返回的bean类型
创建MyBean类
package com.zzy.bean.pojo;
public class MyBean {
}
创建MyBeanFactory类
package com.zzy.bean.pojo;
import com.zzy.pojo.Course;
import org.springframework.beans.factory.FactoryBean;
public class MyBeanFactory implements FactoryBean<Course> {
//定义返回bean
@Override
public Course getObject() throws Exception {
Course course = new Course();
course.setCname("语文");
return course;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
创建Course类
package com.zzy.pojo;
public class Course {
private String cname;//课程名称
public void setCname(String cname) {
this.cname = cname;
}
public void test(){
System.out.println(cname);
}
}
编写配置文件beanFactoryBean.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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--普通bean :创建MyBean类的对象-->
<bean id="myBean" class="com.zzy.bean.pojo.MyBean"></bean>
</beans>
编写配置文件beanFactoryBean1.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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--普通bean :创建MyBeanFactory类的对象-->
<bean id="myBean1" class="com.zzy.bean.pojo.MyBeanFactory"></bean>
</beans>
测试并输出结果
package com.test;
import com.zzy.bean.pojo.MyBean;
import com.zzy.pojo.Course;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestFactoryBean {
//普通bean测试
@Test
public void testCon(){
ApplicationContext context =
new ClassPathXmlApplicationContext("beanFactoryBean.xml");
MyBean myBean = context.getBean("myBean", MyBean.class);
System.out.println(myBean);
}
//测试FactoryBean,定义的bean所返回的类型不一致
@Test
public void testCou(){
ApplicationContext context =
new ClassPathXmlApplicationContext("beanFactoryBean1.xml");
Course course = context.getBean("myBean1", Course.class);
System.out.println(course);
}
}
普通bean返回的是MyBean类的实例对象
FactoryBean返回的是制定类类型的实例对象Course
这里是引用
3.操作Bean管理-Bean的作用域
1 .在Spring里面,可以设置bean实例是单实例和多实例
2. 在Spring里面,默认是单实例
3. 如何设置单实例和多实例
(1)在spring配置文件bean标签里面有scope属性,用于设置单实例和多实例
(2)scope属性singleton(单实例)prototype(多实例)
单实例案例: 第一个值:默认值singleton,表示单实例对象
package com.zzy.scpoe.pojo;
public class Book {
private String name;
private String author;
public void setName(String name) {
this.name = name;
}
public void setAuthor(String author) {
this.author = author;
}
public void testBook(){
System.out.println("书名为"+name+"的作者是"+author);
}
}
<?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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="book" class="com.zzy.scpoe.pojo.Book" scope="singleton"></bean>
</beans>
//测试单实例和多实例
@Test
public void testScope(){
ApplicationContext context =
new ClassPathXmlApplicationContext("beanScope.xml");
Book book1 = context.getBean("book", Book.class);
Book book2 = context.getBean("book", Book.class);
System.out.println(book1);
System.out.println(book2);
System.out.println(book1==book2);
}
多实例案例:第二个值:prototype,表示多实例对象
<?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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--单实例-->
<!--<bean id="book" class="com.zzy.scpoe.pojo.Book" scope="singleton"></bean>-->
<!--多实例-->
<bean id="book" class="com.zzy.scpoe.pojo.Book" scope="prototype"></bean>
</beans>
//测试单实例和多实例
@Test
public void testScope(){
ApplicationContext context =
new ClassPathXmlApplicationContext("beanScope.xml");
Book book1 = context.getBean("book", Book.class);
Book book2 = context.getBean("book", Book.class);
System.out.println(book1);
System.out.println(book2);
System.out.println(book1==book2);
}
单实例和多实例在xml中的配置以及区别
区别:
singleton是单实例 prototypt是多实例
设置scope属性值是singleton的时候,在加载spring配置文件的时候就会创建单实例对象
设置scope属性的值是prototype的时候,不是在加载spring配置文件的时候创建对象,而是在调用getBean方法的时候,创建的多实例对象
4.操作Bean管理-Bean的生命周期
4.1什么是生命周期
从对象创建到对象销毁的过程称之为对象的生命周期
4.2 bean的生命周期(5步骤)
步骤
1.通过构造器创建Bean的实例
2. 为bean的属性设置值,和对其他bean的引用(调用set方法)
3.调用bean的初始化方法,需要自己进行配置
4.bean可以使用了,也就是对象获取到了
5.当容器在关闭的时候,调用bean的销毁的方法,需要自己进行配置
创建Orders类 ,设置属性set方法、无参构造方法 、初始化、销毁方法
package com.zzy.lifebean;
public class Orders {
private String oname;
//无参构造方法
public Orders() {
System.out.println("第一步:执行无参构造方法,创建bean的实例对象");
}
//set方法
public void setOname(String oname) {
this.oname = oname;
System.out.println("第二步:调用set方法为属性赋值");
}
//创建执行的初始化方法
public void init(){
System.out.println("第三步:执行初始化的方法");
}
//创建执行的销毁的方法
public void destory(){
System.out.println("第五步:执行销毁的方法");
}
}
创建spring的配置文件
init-method=“init” destroy-method="destory
分别表示Orders中的初始化方法和销毁方法
<?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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="orders" class="com.zzy.lifebean.Orders" init-method="init" destroy-method="destory">
<property name="oname" value="手机"></property>
</bean>
</beans>
测试输出结果
//测试bean的生命周期
@Test
public void testLife(){
ApplicationContext context =
new ClassPathXmlApplicationContext("beanLife.xml");
Orders orders = context.getBean("orders", Orders.class);
System.out.println("第四步:获取到创建的bean的实例");
System.out.println(orders);
//进行手动实例的销毁
((ClassPathXmlApplicationContext)context).close();
}
4.3 bean的后置处理器(7步骤)
步骤
1.通过构造器创建Bean的实例
2. 为bean的属性设置值,和对其他bean的引用(调用set方法)
3.1 把bean的实例传递给bean的后置处理器的方法postProcessBeforeInitialization
3.调用bean的初始化方法,需要自己进行配置
3.2 把bean的实例传递给bean的后置处理器的方法postProcessAfterInitialization
4.bean可以使用了,也就是对象获取到了
5.当容器在关闭的时候,调用bean的销毁的方法,需要自己进行配置
案例展示
创建后置处理器类MyBeanPostProcessor,并实现BeanPostProcessor接口,重写方法
package com.zzy.lifebean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.lang.Nullable;
class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在初始化init方法执行之前执行的方法");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在初始化init方法执行之后执行的方法");
return bean;
}
}
在spring文件中配置为当前所有的bean配置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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--bean的生命周期-->
<bean id="orders" class="com.zzy.lifebean.Orders" init-method="init" destroy-method="destory">
<property name="oname" value="手机"></property>
</bean>
<!--为当前所有的bean配置bean的后置处理器-->
<bean id="myBeanPostProcessor" class="com.zzy.lifebean.MyBeanPostProcessor"></bean>
</beans>
测试输出结果
//测试bean的生命周期
@Test
public void testLife(){
ApplicationContext context =
new ClassPathXmlApplicationContext("beanLife.xml");
Orders orders = context.getBean("orders", Orders.class);
System.out.println("第四步:获取到创建的bean的实例");
System.out.println(orders);
//进行手动实例的销毁
((ClassPathXmlApplicationContext)context).close();
}
5.IOC操作Bean管理的xml自动装配
5.1 什么是自动装配
根据指定装配规则,属性名称或者属性类型,Spring自动将匹配的属性值进行注入
5.2 演示自动装配过程
bean标签属性autowrie ,配置自动装配
autowrie属性常用两个值:
byNamw:autowire=“byName” 根据属性名称注入:注入bean的id值和类的属性名称要一致
byType:autowire="byType"根据属性类型注入:相同类型的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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--实现自动装配
bean标签属性autowrie ,配置自动装配
autowrie属性常用两个值:
byNamw:autowire="byName" 根据属性名称注入:注入bean的id值和类的属性名称要一致
byType:autowire="byType"根据属性类型注入:相同类型的bean只能定义一个
-->
<bean id="emp" class="com.zzy.autowried.Emp" autowire="byName">
<!--手动装配 如下-->
<!--<property name="dept" ref="dept"></property>-->
</bean>
<bean id="dept" class="com.zzy.autowried.Dept"></bean>
</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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--实现自动装配
bean标签属性autowrie ,配置自动装配
autowrie属性常用两个值:
byNamw:autowire="byName" 根据属性名称注入:注入bean的id值和类的属性名称要一致
byType:autowire="byType"根据属性类型注入:相同类型的bean只能定义一个
-->
<bean id="emp" class="com.zzy.autowried.Emp" autowire="byType">
<!--手动装配 如下-->
<!--<property name="dept" ref="dept"></property>-->
</bean>
<bean id="dept" class="com.zzy.autowried.Dept"></bean>
</beans>
6.IOC操作Bean管理-外部属性文件
6.1 配置数据库信息(以数据库信息为例)
(1)第一种方式:原始方式配置德鲁伊数据库连接池
引入德鲁伊Druid的jar包
<!--第一种:原始方式直接配置连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/jt"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
(2)第二种方式:引入外部文件配置数据库连接池
第一步:创建jdbc.properties
第二步:把外部文件jdbc.properties引入到Spring配置文件中
*引入名称空间context
*在spring的配置文件总使用标签引入外部属性文件
<?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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd>
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--第一种:原始方式直接配置连接池-->
<!--<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/jt"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>–>-->
<!--第二种:引入外部文件属性配置连接池-->
<!--引入外部文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置连接盒-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${prop.driverClassName}"></property>
<property name="url" value="${prop.url}"></property>
<property name="username" value="${prop.username}"></property>
<property name="password" value="${prop.password}"></property>
</bean>
</beans>