1、什么是Bean管理
- Bean管理指的是两个操作
- Spring创建对象
- Spring注入属性
2、Bean管理操作有两种方式
- 基于xml配置文件方式实现
- 基于注解方式实现
IOC操作Bean管理(xml方式)
1、基于xml方式创建对象
- 在spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
在bean标签有很多属性,介绍常用属性
- id属性:唯一标识
- class属性:类全路径(类包路径)
3.默认用无参数构造方法完成对象创建
2、基于xml注入属性
第一种方法:set方法进行注入
- 对象需要生成set方法 ```java package com.daijunyi.model;
public class Book { private String name; private String author;
public void setAuthor(String author) {
this.author = author;
}
public void setName(String name) {
this.name = name;
}
}
通过xml配置注入属性
```xml
<bean id="book" class="com.daijunyi.model.Book">
<property name="name" value="红领巾历险记"/>
<property name="author" value="红领巾"/>
</bean>
第二种有参数构造方法进行注入。
创建有参数构造函数的order类
public class Order { private String orderId; private Integer number; public Order(String orderId, Integer number) { this.orderId = orderId; this.number = number; } }
xml配置对象的创建
<!-- 创建对象--> <bean id="order" class="com.daijunyi.model.Order"> <!-- 有参数的构造函数--> <constructor-arg name="number" value="1"/> <constructor-arg name="orderId" value="1232qwd"/> </bean>
3、p名称空间注入
- p名称空间注入,可以用来简化xml配置
第一步 配置好xmlns:p的命名空间
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
xml文件中修改set的p命名空间的注入方式
<!--用p命名空间方便 set方法的注入-->
<bean id="book" class="com.daijunyi.model.Book" p:name="红领巾历险记" p:author="红领巾">
</bean>
4、xml属性中注入其他类型的值
null值:
<!--用p命名空间方便 set方法的注入--> <bean id="book" class="com.daijunyi.model.Book" p:name="红领巾历险记" p:author="红领巾"> <property name="page"> <null></null> </property> </bean>
特殊符号:使用<!CDATA[具体内容]>写法可以写任何特殊符号
<!--用p命名空间方便 set方法的注入--> <bean id="book" class="com.daijunyi.model.Book"> <property name="author" value="红领巾"/> <!--特殊符号 <的写法等等,CDATA写法 <!DATA[具体内容]> --> <property name="name"> <value><![CDATA[<红领巾历险记>]]></value> </property> <property name="page"> <null></null> </property> </bean>
5、属性中注入外部bean
创建两个类service类和dao类
- 在service类中添加dao类的成员变量,并设置set方法
- xml配置dao类的bean注入 核心点是xml中使用ref引用其他bean ```java package com.daijunyi.dao;
public interface UserDao {
public void doTest();
}
```java
package com.daijunyi.dao;
public class UserDaoImp implements UserDao {
@Override
public void doTest() {
System.out.println("dao调用了");
}
}
package com.daijunyi.service;
import com.daijunyi.dao.UserDao;
public class UserService {
private UserDao dao;
public void setDao(UserDao dao) {
this.dao = dao;
}
public void doTest(){
dao.doTest();
}
}
配置xml文件
<!--创建dao对象-->
<bean id="userDao" class="com.daijunyi.dao.UserDaoImp"/>
<!--创建service对象-->
<bean id="userService" class="com.daijunyi.service.UserService">
<!--注入dao对象-->
<property name="dao" ref="userDao"/>
</bean>
6、内部bean注入和级联赋值
1 内部bean注入:
- 创建一个员工类和部门类
- 在员工类中添加成员变量部门
- 配置xml进行属性注入,在property 中可以嵌套bean标签进行对象注入 ```java package com.daijunyi.model;
public class Dept { private String name;
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dept{" +
"name='" + name + '\'' +
'}';
}
}
```java
package com.daijunyi.model;
public class Emp {
private String name;
private Dept dept;
public void setName(String name) {
this.name = name;
}
public void setDept(Dept dept) {
this.dept = dept;
}
@Override
public String toString() {
return "Emp{" +
"name='" + name + '\'' +
", dept=" + dept +
'}';
}
}
<bean id="emp" class="com.daijunyi.model.Emp">
<property name="name" value="红领巾"/>
<property name="dept">
<bean id="dept" class="com.daijunyi.model.Dept">
<property name="name" value="开发部"></property>
</bean>
</property>
</bean>
2.级联赋值
<!--级联赋值-->
<bean id="emp" class="com.daijunyi.model.Emp">
<property name="name" value="红领巾"/>
<property name="dept" ref="dept"></property>
<!--可以进行.的方式进行对象的调用,在进行属性的复制,前提是dept有get方法-->
<property name="dept.name" value="女装部"></property>
</bean>
<bean id="dept" class="com.daijunyi.model.Dept">
<property name="name" value="开发部"></property>
</bean>
7、操作Bean管理注入集合属性
1.注入数组类型属性
2.注入List集合类型属性
3.注入Map集合类型属性
package com.daijunyi.model;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class CollectionModel {
private String[] courses;
private List<String> list;
private Map<String,String> maps;
private Set<String> sets;
public void setList(List<String> list) {
this.list = list;
}
public void setMaps(Map<String, String> maps) {
this.maps = maps;
}
public void setSets(Set<String> sets) {
this.sets = sets;
}
public void setCourses(String[] courses) {
this.courses = courses;
}
}
<bean id="collectionModel" class="com.daijunyi.model.CollectionModel">
<!--数组的注入方式-->
<property name="courses">
<array>
<value>课程1</value>
<value>课程2</value>
</array>
</property>
<!--list的注入方式-->
<property name="list">
<list>
<value>值1</value>
<value>值2</value>
</list>
</property>
<!--map的注入方式-->
<property name="maps">
<map>
<entry key="ke1" value="value1"></entry>
<entry key="key2" value="value2"></entry>
</map>
</property>
<!--set的注入方式-->
<property name="sets">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
</bean>
8、在集合中注入对象
1.创建Course类
2.CollectionModel增加List
3.配置xml
<bean id="collectionModel" class="com.daijunyi.model.CollectionModel">
<!--集合中对象注入-->
<property name="courseList">
<list>
<ref bean="course"/>
<bean id="course2" class="com.daijunyi.model.Course">
<property name="price" value="1201.1"/>
<property name="name" value="Mybatis"/>
</bean>
</list>
</property>
</bean>
<bean id="course" class="com.daijunyi.model.Course">
<property name="name" value="Spring5框架"/>
<property name="price" value="100.1"/>
</bean>
9、把集合注入抽取出来设置成公共部分
1.需要添加util命名空间
2.配置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: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="collectionModel" class="com.daijunyi.model.CollectionModel">
<!--集合中注入对象,并且采用引入抽取的方法引入-->
<property name="courseList" ref="courseList"/>
</bean>
<bean id="course" class="com.daijunyi.model.Course">
<property name="name" value="Spring5框架"/>
<property name="price" value="100.1"/>
</bean>
<!--抽取的方法-->
<util:list id="courseList">
<ref bean="course"/>
<bean id="course3" class="com.daijunyi.model.Course">
<property name="price" value="1222.1"/>
<property name="name" value="Mysql"/>
</bean>
</util:list>
10、操作Bean管理(FactoryBean)
1、Spring有两种类型bean,一种普通bean,另外一种工厂bean(FactoryBean)
2、普通bean:在配置文件中定义bean类型就是返回类型
3、工厂bean:在配置文件定义bean类型可以和返回类型不一样
第一步创建类,让这个类作为工厂bean,实现接口FactoryBean
第二步 实现接口里面的方法,在方法中返回bean类型
package com.daijunyi.factorybean;
import com.daijunyi.model.Course;
import org.springframework.beans.factory.FactoryBean;
public class MyBean implements FactoryBean {
//定义返回类型
@Override
public Course getObject() throws Exception {
Course course = new Course();
course.setName("Spring5");
course.setPrice(11.1);
return course;
}
@Override
public Class<?> getObjectType() {
return Course.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
<?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="myBean" class="com.daijunyi.factorybean.MyBean">
</bean>
</beans>
测试方法
@Test
public void testMyBean(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
Object myBean = context.getBean("myBean");
System.out.println(myBean.toString());
}
输出结果
Course{name='Spring5', price=11.1}
Process finished with exit code 0
11、操作bean管理(bean作用域)
1、在Spring里面,设置创建bean实例是单例还是多实例
2、在Spring里面,默认情况下是单实例。
@Test
public void testSigtest(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
Object myBean = context.getBean("sinTest");
Object myBean2 = context.getBean("sinTest");
System.out.println(myBean);
System.out.println(myBean2);
}
com.daijunyi.factorybean.SinTest@1a3869f4
com.daijunyi.factorybean.SinTest@1a3869f4
Process finished with exit code 0
设置多实例对象
<bean id="sinTest" class="com.daijunyi.factorybean.SinTest" scope="prototype"></bean>
scope值prototype和singleton
- singleton(单实例)加载spring配置文件时候就会创建单实例对象
- prototype(多实例)不是在加载spring配置文件时候创建对象,在调用getBean获取对象的时候才创建对象。每次都会创建一个。
12、操作Bean管理(生命周期)
12.1 bean生命周期
- 通过构造器创建bean实例(无参数构造)
- 为bean的属性设置值和对其他bean引用(调用set方法)
- 调用bean的初始化的方法(需要进行配置初始化的方法)
- bean可以使用了(对象获取到了)
- 当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法) ```java package com.daijunyi.factorybean;
public class SinTest {
private String name;
public SinTest() {
System.out.println("第一步构造函数执行");
}
public void setName(String name) {
this.name = name;
System.out.println("第二步设置属性");
}
public void initMethod(){
System.out.println("第三步 初始化");
}
public void destroyMethod(){
System.out.println("第五步 销毁方法");
}
}
测试代码
```java
@Test
public void testSigtest(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
Object myBean = context.getBean("sinTest");
System.out.println(myBean+"第四步获取对象操作");
context.close();
}
xml配置文件
<bean id="sinTest" class="com.daijunyi.factorybean.SinTest" init-method="initMethod" destroy-method="destroyMethod">
<property name="name" value="11"></property>
</bean>
输出结果:
第一步构造函数执行
第二步设置属性
第三步 初始化
com.daijunyi.factorybean.SinTest@78ac1102第四步获取对象操作
第五步 销毁方法
Process finished with exit code 0
13、配置后置处理器
1、创建一个类实现接口BeanPostProcessor
package com.daijunyi.model;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class BeanPost implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("调用了postProcessAfterInitialization方法"+beanName);
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("调用了postProcessBeforeInitialization方法"+beanName);
return bean;
}
}
2、配置xml 添加bean
<bean id="beanPost" class="com.daijunyi.model.BeanPost"/>
这样每个bean实例就都会在初始化方法前后调用该方法了
调用了postProcessBeforeInitialization方法myBean
调用了postProcessAfterInitialization方法myBean
第一步构造函数执行
第二步设置属性
调用了postProcessBeforeInitialization方法sinTest
第三步 初始化
调用了postProcessAfterInitialization方法sinTest
com.daijunyi.factorybean.SinTest@a74868d第四步获取对象操作
第五步 销毁方法
Process finished with exit code 0
另外注意即使我们自己不配置nit-method也会调用这两个方法。
14、操作Bean管理(xml自动装配)
1、什么是自动装配
根据指定装配规则(属性名称)
2、演示,使用 autowire 来配置
根据名称找 autowire=”byName”
<!--根据名称自动注入 emp中的dept属性自动根据名称找到dept的bean--> <bean id="emp" class="com.daijunyi.model.Emp" autowire="byName"> <property name="name" value="红领巾"/> </bean> <bean id="dept" class="com.daijunyi.model.Dept"> <property name="name" value="研发部"/> </bean>
根据类型找 autowire=”byType”
<!--根据名称自动注入 emp中的dept属性自动根据类型找到dept的bean--> <bean id="emp" class="com.daijunyi.model.Emp" autowire="byType"> <property name="name" value="红领巾"/> </bean> <bean id="dept" class="com.daijunyi.model.Dept"> <property name="name" value="研发部"/> </bean>
15、操作Bean管理(外部属性文件)
1、直接配置数据库信息
1、xml配置dataSource数据
2、引入druid包和数据Driver包@Test public void poolTest(){ ApplicationContext context = new ClassPathXmlApplicationContext("db.xml"); try { DataSource dataSource = (DataSource) context.getBean("dataSource"); Connection connection = dataSource.getConnection(); String sql = "select * from tb_city"; PreparedStatement preparedStatement = connection.prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery(); ResultSetMetaData metaData = preparedStatement.getMetaData(); while (resultSet.next()){ for (int i=0;i<metaData.getColumnCount();i++){ Object object = resultSet.getObject(metaData.getColumnLabel(i+1)); System.out.println(object); } } } catch (SQLException e) { e.printStackTrace(); } }
<?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="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/learn"/> <property name="username" value="root"/> <property name="password" value="qwerasdf123"/> </bean> </beans>
2、配置外部文件
1、创建外部文件jdbc.properties文件
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/learn username=root password=qwerasdf123
2、配置xml context 名称空间
<?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: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/context http://www.springframework.org/schema/context/spring-context.xsd">
3、xml文件中引入外部jdbc.properties文件
<!--引入外部属性文件--> <context:property-placeholder location="classpath:jdbc.properties"/>
4、使用${}语法把xml文件中的value值修改为这个语句中的 ```xml <?xml version=”1.0” encoding=”UTF-8”?>
<!--引入外部属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</bean>
```