Spring框架学习(一)——Ioc容器管理
一、Spring——IOC(Inversion of Control)控制反转
思想:使用对象时,由主动产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部
Ioc: Spring提供了一个容器。称为Ioc容器,用来充当Ioc思想中的“外部”,Ioc负责对象的创建,初始化对象等一系列工作
Bean: 被创建或管理的对象称为Bean
Bean的本质上就是对象,实例化bean的三种方式:
1.构造方法实例化Bean
1
| <bean id="dao" class="com.test.dao.impl.BookDaoImpl"></bean>
|
2.使用静态工厂实例化Bean
1 2 3 4 5
| public class OrderDaoFactory{ public static OrderDao getOrderDao(){ return new OrderDaoImpl(); } }
|
1
| <bean id="orderDao" class="com.test.factory.OrderDaoFactory" factory-method="getOrderDao"/>
|
3.使用实例工厂实例化Bean
1 2 3 4 5
| public class UserDaoFactory{ public UserDao getUserDao(){ return new UserDaoImpl(); } }
|
1 2 3
| <bean id="userDaoFactory" class="com.test.factory.UserDaoFactory"/> 配合使用,无实际意义
<bean id="userDao" factory-method="getUserDao" factory-bean="userDaoFactory"/>方法名不固定,每次需要配置
|
优化如下:
4.使用FactoryBean实例化Bean(掌握)———-3.变种
第一步创建类,让这个类作为工厂 bean,实现接口 FactoryBean
第二步 实现接口里面的方法,在实现的方法中定义返回的 bean 类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class UserDaoFactoryBean implements FactoryBean<UserDao>{ public UserDao getObject() throws Exception{ return new UserDaoImpl(); } public Class<?> getObjectType(){ return UserDao.class; } public boolean isSingleton(){ return false; } }
|
1
| <bean id="userDao" class="com.test.factory.UserDaoFactoryBean" />
|
DI(Dependncy Injection) :在容器中建立bean与bean之间的依赖关系,称为依赖注入
1、什么是IOC(控制反转)
a)把对象创建和对象之间的调用过程,交给Spring进行管理
b)使用IOC目的:为了降低耦合度
2、IOC底层
a)XML 解析、工厂模式、反射
3、Spring提供的IOC容器实现的两种方式(两个接口)
a)BeanFactory接口:IOC容器基本实现是Spring内部接口的使用接口,不提供给开发人员进行使用(加载配置文件时候不会创建对象,在获取(或使用)对象时才会创建对象。)
b)ApplicationContext接口:BeanFactory接口的子接口,提供更多更强大的功能,提供给开发人员使用(加载配置文件时候就会把在配置文件对象进行创建)推荐使用!
二、IOC容器-Bean管理
1、IOC操作Bean管理
a)Bean管理就是两个操作:(1)Spring创建对象;(2)Spring注入属性
2、基于XML配置文件创建对象
1 2
| <bean id="user" class="com.atguigu.spring5.User"></bean>
|
3、基于XML方式注入属性(DI:依赖注入(注入属性))
引入:向一个类传递数据方式有几种? 1.普通方法(set方法) 2.构造方法
注入的数据类型:1.引用类型 2.简单类型(基本数据类型和String)
故,依赖注入方式分四个情况:
1.setter注入: (1)简单类型 (2)引用类型
2.构造器注入: (1)简单类型 (2)引用类型
a)setter方式注入简单类型
1 2 3 4 5 6 7 8 9
| public class Book { private String bname; public void setBname(String bname) { this.bname = bname; } }
|
1 2 3 4 5 6 7 8
| <bean id="book" class="com.atguigu.spring5.Book">
<property name="bname" value="Hello"></property> </bean>
|
b)setter注入引用数据类型
1 2 3 4 5 6 7
| public class BookServiceImpl implements BookService{ private BookDao bookDao; public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; System.out.println("service set ..."); }
|
1 2 3 4 5 6 7
| <bean id="dao" class="com.test.dao.impl.BookDaoImpl"></bean> <bean id="service" class="com.test.service.impl.BookServiceImpl">
<property name="bookDao" ref="dao"></property> </bean>
|
c)有参构造器注入简单数据类型
1 2 3 4 5 6 7 8 9 10 11
| public class Orders { private String oname; private String address; public Orders(String oname,String address) { this.oname = oname; this.address = address; } }
|
1 2 3 4 5
| <bean id="orders" class="com.atguigu.spring5.Orders"> <constructor-arg name="oname" value="Hello"></constructor-arg> <constructor-arg name="address" value="China!"></constructor-arg> </bean>
|
优化如下:
1 2 3 4 5
| <bean id="orders" class="com.atguigu.spring5.Orders"> <constructor-arg type="java.lang.String" value="Hello"></constructor-arg> <constructor-arg type="int" value=10></constructor-arg> </bean>
|
1 2 3 4 5
| <bean id="orders" class="com.atguigu.spring5.Orders"> <constructor-arg index="0" value="Hello"></constructor-arg> <constructor-arg index="1" value="China!"></constructor-arg> </bean>
|
d)有参构造注入引用数据类型
1 2 3 4 5 6
| public class BookServiceImpl implements BookService { private BookDao bookDao; public BookServiceImpl(BookDao dao){ this.bookDao=bookDao; } }
|
1 2 3 4 5
| <bean id="dao" class="com.test.dao.impl.BookDaoImpl"></bean> <bean id="service" class="com.test.service.impl.BookServiceImpl"> <constructor-arg name="bookDao" ref="dao"/> </bean>
|
e)p名称空间注入(了解即可)
1 2 3 4 5 6 7 8 9
| <?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" <!--在这里添加一行p-->
<bean id="book" class="com.atguigu.spring5.Book" p:bname="very" p:bauthor="good"> </bean>
|
1.强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
2.可选依赖使用setter注入进行,灵活性太强
3.Spring框架提倡使用构造器,第三方框架内部i大多采用构造器注入的形式,相对严谨
4.如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖注入
5.实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入
6.自己开发的模块推荐使用setter注入
4、注入空值和特殊符号
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <bean id="book" class="com.atguigu.spring5.Book"> <property name="address"> <null/> </property>
<property name="address"> <value><![CDATA[<<南京>>]]></value> </property> </bean>
|
5、注入属性-外部bean
a)创建两个类service和dao类
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class UserService {
private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void add() { System.out.println("service add..............."); userDao.update(); }
}
|
1 2 3 4 5 6 7 8
| public class UserDaoImpl implements UserDao {
@Override public void update() { System.out.println("dao update..........."); }
}
|
b)在spring配置文件中进行配置
1 2 3 4 5 6 7 8 9
| <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>
|
6、基于XML方式注入内部bean和级联赋值
a)注入属性-内部bean
(1)一对多关系:部门和员工
一个部门有多个员工,一个员工属于一个部门(部门是一,员工是多)
(2)在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示
1 2 3 4 5 6 7
| public class Dept { private String dname; public void setDname(String dname) { this.dname = dname; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class Emp { private String ename; private String gender; private Dept dept;
public void setDept(Dept dept) { this.dept = dept; } public void setEname(String ename) { this.ename = ename; } public void setGender(String gender) { this.gender = gender; }
}
|
(3)在spring配置文件中配置
1 2 3 4 5 6 7 8 9 10 11 12
| <bean id="emp" class="com.atguigu.spring5.bean.Emp"> <property name="ename" value="Andy"></property> <property name="gender" value="女"></property> <property name="dept"> <bean id="dept" class="com.atguigu.spring5.bean.Dept"> <property name="dname" value="宣传部门"></property> </bean> </property> </bean>
|
b)注入属性-级联赋值
1 2 3 4 5 6 7 8 9 10 11
| <bean id="emp" class="com.atguigu.spring5.bean.Emp"> <property name="ename" value="Andy"></property> <property name="gender" value="女"></property> <property name="dept" ref="dept"></property> </bean> <bean id="dept" class="com.atguigu.spring5.bean.Dept"> <property name="dname" value="公关部门"></property> </bean>
|
1 2 3 4
| public Dept getDept() { return dept; }
|
1 2 3 4 5 6 7 8 9 10 11
| <bean id="emp" class="com.atguigu.spring5.bean.Emp"> <property name="ename" value="jams"></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"> </bean>
|
7、IOC 操作 Bean 管理——xml 注入集合属性
1、注入数组类型属性 2、注入 List 集合类型属性 3、注入 Map 集合类型属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class Stu { private String[] courses; private List<String> list; private Map<String,String> maps; private Set<String> sets;
public void setSets(Set<String> sets) { this.sets = sets; } public void setCourses(String[] courses) { this.courses = courses; } public void setList(List<String> list) { this.list = list; } public void setMaps(Map<String, String> maps) { this.maps = maps; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <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>MySQL</value> <value>Redis</value> </set> </property> </bean>
|
8、在集合里面设置对象类型值
1 2 3 4 5 6
| private List<Course> courseList; public void setCourseList(List<Course> courseList) { this.courseList = courseList; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <bean id="course1" class="com.atguigu.spring5.collectiontype.Course"> <property name="cname" value="Spring5框架"></property> </bean> <bean id="course2" class="com.atguigu.spring5.collectiontype.Course"> <property name="cname" value="MyBatis框架"></property> </bean>
<property name="courseList"> <list> <ref bean="course1"></ref> <ref bean="course2"></ref> </list> </property>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <?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:util="http://www.springframework.org/schema/util" <!--添加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">
<util:list id="bookList"> <value>易筋经</value> <value>九阴真经</value> <value>九阳神功</value> </util:list>
<bean id="book" class="com.atguigu.spring5.collectiontype.Book" scope="prototype"> <property name="list" ref="bookList"></property> </bean>
|