前言
跟随尚硅谷学习Spring5 IOC容器
一、原理讲解
?IOC(概念和原理)
- 什么是 IOC
- 控制反转,把对象创建和对象之间的调用过程,交给 Spring 进行管理
- 使用 IOC 目的:为了耦合度降低
- IOC 底层原理
IOC过程
使用工厂模式降低耦合度:
第一步xml配置文件,配置创建的对象
<bean id="dao" class="com. at guigu.UserDao"></ bean>
进一步降低耦合度
第二步有service类和dao类,创建工厂类
class UserFactory {
public static UserDao get Dao(){
String classValue = class属性值;1 / 1xml解析
Class clazz = Class.forName(classValue): 1/2通过反射创建对象
return (UserDao)clazz.newInstance() :
}
?IOC( BeanFactory 接口)
- IOC 思想基于 IOC 容器完成, IOC 容器底层就是对象工厂
- Spring 提供 IOC 容器实现两种方式:(两个接口)
- BeanFactory: IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用;加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象
- ApplicationContext: BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人员进行使用;加载配置文件时候就会把在配置文件对象进行创建
- ApplicationContext 接口有实现类
?IOC 操作 Bean 管理(概念)
- 什么是 Bean 管理
- Bean 管理指的是两个操作
- Spring 创建对象
- Spirng 注入属性
- Bean 管理操作有两种方式
二、IOC 操作 Bean 管理(基于xml方式)
?基于 xml 方式创建对象
<bean id="book" class="com.atguigu.spring5.dependencyInjection.BookConstructorInjection">
- 在 spring 配置文件中,使用 bean 标签,标签里面添加对应属性,就可以实现对象创建
- 在 bean 标签有很多属性,介绍常用的属性
?id 属性:唯一标识 ?class 属性:类全路径(包类路径) ?name属性:类似于id属性,id中不可以特殊符号,name中可以有 - 创建对象时候,默认也是执行无参数构造方法完成对象创建
?基于 xml 方式注入属性
- 第一种注入方式:使用 set 方法进行注入
?创建类,定义属性和对应的 set 方法
package com.atguigu.spring5;
public class Book {
private String bname;
private String bauthor;
public void setBname(String bname) {
this.bname = bname;
}
public void setBauthor(String bauthor) {
this.bauthor = bauthor;
}
public static void main (String[] args){
Book book=new Book();
book.setBname("abc");
}
}
??在 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"
xsi:schemaLocation="http:
https:
<!--配置User对象创建-->
<bean id="bok" class="com.atguigu.spring5.Book">
<!--配置property完成属性注入
name:类里的属性名称
value:向属性注入的值-->
<property name="bname" value="易筋经"></property>
<property name="bauthor" value="cjjj"></property>
</bean>
</beans>
??测试:
package com.atguigu.sprint5;
import com.atguigu.spring5.dependencyInjection.BookSetterInjection;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BookTest {
@Test
public void testBookSetterInjection() {
ApplicationContext context = new ClassPathXmlApplicationContext("bookSetterInjection.xml");
BookSetterInjection book = context.getBean("book", BookSetterInjection.class);
System.out.println(book);
}
}
- 第二种注入方式:使用有参数构造进行注入
?创建类,定义属性,创建属性对应有参数构造方法
package com.atguigu.spring5.dependencyInjection;
public class BookConstructorInjection {
private String bookName;
public BookConstructorInjection(String bookName) {
this.bookName = bookName;
}
@Override
public String toString() {
return "BookConstructorInjection{" +
"bookName='" + bookName + '\'' +
'}';
}
}
??在 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"
xsi:schemaLocation="http:
https:
<!--配置User对象创建-->
<bean id="book" class="com.atguigu.spring5.dependencyInjection.BookConstructorInjection">
<!--有参数构造属性注入-->
<constructor-arg name="bookName" value="金刚经"/>
</bean>
</beans>
??测试:
package com.atguigu.sprint5;
import com.atguigu.spring5.dependencyInjection.BookConstructorInjection;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BookTest {
@Test
public void testBookConstructorInjection() {
ApplicationContext context = new ClassPathXmlApplicationContext("bookConstructorInjection.xml");
BookConstructorInjection book = context.getBean("book", BookConstructorInjection.class);
System.out.println(book);
}
}
三、IOC 操作 Bean 管理(xml 注入其他类型属性)
?字面量
- null 值
省略创建类步骤,可参考第二章内容 在 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"
xsi:schemaLocation="http:
https:
<!--配置User对象创建-->
<bean id="book" class="com.atguigu.spring5.dependencyInjection.BookNullValueInjection">
<property name="bookName" value="易筋经"/>
<!--null值-->
<property name="address">
<null/>
</property>
</bean>
</beans>
??测试:
package com.atguigu.sprint5;
import com.atguigu.spring5.dependencyInjection.BookConstructorInjection;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BookTest {
@Test
public void testBookNullInjection() {
ApplicationContext context = new ClassPathXmlApplicationContext("bookNullValueInjection.xml");
BookNullValueInjection book = context.getBean("book", BookNullValueInjection.class);
System.out.println(book);
}
}
- 属性值包含特殊符号
省略创建类步骤,可参考第二章内容 在 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"
xsi:schemaLocation="http:
https:
<!--配置User对象创建-->
<bean id="book" class="com.atguigu.spring5.dependencyInjection.BookSpecialCharactersInjection">
<property name="bookName" value="易筋经"></property>
<!--属性值包含特殊符号,如"<<广州>>"
方式1:把<>特殊符号进行转义
方式2:把特殊符号内容写到CDATA
-->
<!--方式1-->
<!-- <property name="address" value="<<广州>>"></property>-->
<!--方式2
<![CDATA[<<广州>>]]>
-->
<property name="address">
<value><![CDATA[<<南京>>]]></value>
</property>
</bean>
</beans>
??测试:
package com.atguigu.sprint5;
import com.atguigu.spring5.dependencyInjection.BookConstructorInjection;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BookTest {
@Test
public void testBookSpecialCharactersInjection() {
ApplicationContext context = new ClassPathXmlApplicationContext("bookSpecialCharactersInjection.xml");
BookSpecialCharactersInjection book = context.getBean("book", BookSpecialCharactersInjection.class);
System.out.println(book);
}
}
?注入属性-外部bean
创建两个类service类和dao类
package com.atguigu.spring5.dependencyInjection.externalBean.dao;
public interface CourseDao {
public void update();
}
package com.atguigu.spring5.dependencyInjection.externalBean.dao;
public class CourseDaoImpl implements CourseDao {
public void update() {
System.out.println("CourseDaoImpl.update().......");
}
}
在service调用dao里面的方法
package com.atguigu.spring5.dependencyInjection.externalBean.service;
import com.atguigu.spring5.dependencyInjection.externalBean.dao.CourseDao;
public class CourseService {
private CourseDao courseDao;
public void setCourseDao(CourseDao courseDao) {
this.courseDao = courseDao;
}
public void add() {
System.out.println("CourseService.add().....");
courseDao.update();
}
}
?在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"
xsi:schemaLocation="http:
https:
<!--service和dao对象创建-->
<bean id="courseService" class="com.atguigu.spring5.dependencyInjection.externalBean.service.CourseService">
<!--注入CourseDao对象
name:类里面的属性名称
ref: 外部bean的id
-->
<property name="courseDao" ref="courseDaoImpl"/>
</bean>
<!--这里dao的class使用的是实现类,告诉spring反射对应实现类从而能创建实现类对象-->
<bean id="courseDaoImpl" class="com.atguigu.spring5.dependencyInjection.externalBean.dao.CourseDaoImpl"></bean>
</beans>
?测试
package com.atguigu.sprint5;
import com.atguigu.spring5.dependencyInjection.externalBean.service.CourseService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CourseTest {
@Test
public void testCourseExternalBean() {
ApplicationContext context = new ClassPathXmlApplicationContext("courseExternalBean.xml");
CourseService courseService = context.getBean("courseService", CourseService.class);
courseService.add();
}
}
?注入属性-内部bean
一对多关系:部门和员工 ??一个部门有多个员工,一个员工属于一个部门,部门是一,员工是多 ??在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示
package com.atguigu.spring5.dependencyInjection.internalBean.entity;
public class Employee {
private String employeeName;
private String gender;
private Department department;
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public void setGender(String gender) {
this.gender = gender;
}
public void setDepartment(Department department) {
this.department = department;
}
public Department getDepartment() {
return department;
}
@Override
public String toString() {
return "Employee{" +
"employeeName='" + employeeName + '\'' +
", gender='" + gender + '\'' +
", department=" + department +
'}';
}
}
package com.atguigu.spring5.dependencyInjection.internalBean.entity;
public class Employee {
private String employeeName;
private String gender;
private Department department;
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public void setGender(String gender) {
this.gender = gender;
}
public void setDepartment(Department department) {
this.department = department;
}
public Department getDepartment() {
return department;
}
@Override
public String toString() {
return "Employee{" +
"employeeName='" + employeeName + '\'' +
", gender='" + gender + '\'' +
", department=" + department +
'}';
}
}
在 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"
xsi:schemaLocation="http:
https:
<!--内部bean-->
<!--Employee和Department对象创建-->
<bean id="employee" class="com.atguigu.spring5.dependencyInjection.internalBean.entity.Employee">
<property name="employeeName" value="张三"/>
<property name="gender" value="男"/>
<!--设置内部bean属性-->
<property name="department">
<bean id="department" class="com.atguigu.spring5.dependencyInjection.internalBean.entity.Department">
<property name="departmentName" value="java开发部门"/>
</bean>
</property>
</bean>
</beans>
测试
package com.atguigu.sprint5;
import com.atguigu.spring5.dependencyInjection.internalBean.entity.Employee;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CompanyTest {
@Test
public void testCompanyInternalBean() {
ApplicationContext context = new ClassPathXmlApplicationContext("companyInternalBean.xml");
Employee employee = context.getBean("employee", Employee.class);
System.out.println(employee);
}
}
?注入属性-级联赋值
<?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:
https:
<!--级联赋值: 第一种写法-->
<bean id="employee" class="com.atguigu.spring5.dependencyInjection.internalBean.entity.Employee">
<property name="employeeName" value="李四"/>
<property name="gender" value="男"/>
<!--级联赋值写法1,使用ref-->
<property name="department" ref="department"/>
</bean>
<bean id="department" class="com.atguigu.spring5.dependencyInjection.internalBean.entity.Department">
<property name="departmentName" value="级联1:软件部门"/>
</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"
xsi:schemaLocation="http:
https:
<!--级联赋值: 第二种写法-->
<bean id="employee" class="com.atguigu.spring5.dependencyInjection.internalBean.entity.Employee">
<property name="employeeName" value="李四"/>
<property name="gender" value="男"/>
<!--级联赋值写法2,使用.链式写法
注意,类需要生成getter方法才能使用
-->
<property name="department" ref="department"></property>
<property name="department.departmentName" value="级联2:技术部"></property>
</bean>
<bean id="department" class="com.atguigu.spring5.dependencyInjection.internalBean.entity.Department">
<property name="departmentName" value="软件部门"></property>
</bean>
</beans>
|