Spring5学习:IOC容器-Bean管理-1


前言

跟随尚硅谷学习Spring5
IOC容器

一、原理讲解

 IOC(概念和原理)

  • 什么是 IOC
    • 控制反转,把对象创建和对象之间的调用过程,交给 Spring 进行管理
    • 使用 IOC 目的:为了耦合度降低
  • IOC 底层原理
    • xml 解析、工厂模式、反射
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 管理操作有两种方式
    • 基于 xml 配置文件方式实现
    • 基于注解方式实现

二、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://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置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;
    // 2 - 有参数构造注入
    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://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置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://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置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://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--配置User对象创建-->
    <bean id="book" class="com.atguigu.spring5.dependencyInjection.BookSpecialCharactersInjection">
        <property name="bookName" value="易筋经"></property>

        <!--属性值包含特殊符号,如"<<广州>>"
            方式1:把<>特殊符号进行转义
            方式2:把特殊符号内容写到CDATA
        -->
        <!--方式1-->
<!--        <property name="address" value="&lt;&lt;广州&gt;&gt;"></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 {

    // 声明外部对象属性CourseDao(接口),生成setter方法
    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://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--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;
    }
    // 生成getter方法:主要作用于第二种级联的写法需要getter
    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;
    }

    // 生成getter方法:主要作用于第二种级联的写法需要getter
    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://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--内部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://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--级联赋值: 第一种写法-->
    <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>
  • 级联赋值写法二(需要生成get方法)
<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--级联赋值: 第二种写法-->
    <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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值