• 第六章 Spring(IOC/DI)依赖注入(配置文件)


    1. Spring

           Spring | Home

            Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

    2. 控制反转(IoC)和依赖注入(DI)

    2.1 工厂模式创建对象

    实体类:

    1. @Data
    2. public abstract class Pet {
    3. protected String name;
    4. protected String color;
    5. public abstract void eat();
    6. }
    1. public class Dog extends Pet{
    2. @Override
    3. public void eat() {
    4. System.out.println(this.color+this.name+"吃骨头!");
    5. }
    6. }
    1. public class Cat extends Pet{
    2. @Override
    3. public void eat() {
    4. System.out.println(this.color+this.name+"吃小鱼!");
    5. }
    6. }

    对象工厂:

    1. public class PetFactory {
    2. public static Pet createInstance(String type,String name,String color) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    3. Pet pet = null;
    4. Class aClass = Class.forName("com.entity."+type);
    5. pet =(Pet)aClass.newInstance();
    6. pet.setName(name);
    7. pet.setColor(color);
    8. return pet;
    9. }
    10. }

    测试:

    1. @Test
    2. public void petTest() throws IllegalAccessException, InstantiationException, ClassNotFoundException {
    3. Scanner scanner = new Scanner(System.in);
    4. System.out.println("宠物的类型:");
    5. String clsName = scanner.next();
    6. System.out.println("宠物名:");
    7. String name = scanner.next();
    8. System.out.println("宠物颜色:");
    9. String color = scanner.next();
    10. Pet pet = PetFactory.createInstance(clsName,name,color);
    11. pet.eat();
    12. }

    2.2 Spring IoC(Inversion of Control)

    IoC:使用spring框架帮我们进行对象管理(对象的创建,维护对象之间的关系)的模式;侧重于说明对象创建方式的改变;原来写程序需要对象了就 new 一个,控制权在程序,现在我们创建对象交给spring容器来管理,由spring帮我们创建。

    2.2.1 spring的IoC操作 

    ①把对象的创建交给spring进行管理;

    ②IoC操作的两种方式:

            a. xml配置文件方式

    <bean class="com.entity.Dog"/>
    

            b.IoC注解方式

    @Component , @Service , @Repository , @Controller

    2.2.2 IoC底层实现技术

    a.xml配置文件;

    b.dom4j解决xml;

    c.设计模式(工厂,模板,单例...)

    d.反射

    2.2.3 使用spring的步骤 

    ①导入jar包

    1. <dependency>
    2. <groupId>org.springframeworkgroupId>
    3. <artifactId>spring-contextartifactId>
    4. <version>5.3.18version>
    5. dependency>

    ②创建类

    1. public class Student {
    2. public void introduce(){
    3. System.out.println("我是一名学生!");
    4. }
    5. }

    ③创建spring配置文件,配置bean

             spring核心配置文件的名称和位置不固定,建议放在src下,建议名字 applicationContext.xml

    1. "1.0" encoding="UTF-8"?>
    2. "http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. "com.entity.Student"/>

    ④测试

    1. @Test
    2. public void stuTest(){
    3. //创建spring容器对象
    4. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    5. //通过spring容器获取在其中定义过的bean对象,由此实现了控制反转
    6. Student student = ac.getBean(Student.class);
    7. student.introduce();
    8. }

    2.2.4 spring的bean管理(xml方式)

    Bean实例化的方式:

    ①spring中通过配置文件创建对象;

    ②bean实例化的三种方式:

            a.使用类中的无参构造创建(没有无参构造hui)

    1. <bean class="com.entity.Student"/>
    2. <bean id="stu" class="com.entity.Student"/>
    3. <bean name="stu1 stu2" class="com.entity.Student"/>
    1. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    2. Student stu2 = (Student)ac.getBean("stu");
    3. System.out.println(stu2);
    4. Student stu3 = (Student) ac.getBean("stu1");
    5. System.out.println(stu3);
    6. Student stu4 = ac.getBean("stu2",Student.class);
    7. System.out.println(stu4);

     

    stu1,stu2 是同一个对象

            b. 使用静态工厂创建

                    在类中先创建静态方法,返回对象

    静态工厂类:

    1. public class StudentFactory {
    2. public static Student createStu(){
    3. return new Student();
    4. }
    5. }

    xml配置静态工厂:

    <bean id="staticFac" class="com.factory.StudentFactory" factory-method="createStu"/>

    测试:

    Student stu5 = (Student) ac.getBean("staticFac");

            c.使用实例工厂创建

    工厂:

    1. public class Factory {
    2. public Student createStu(){
    3. return new Student();
    4. }
    5. }

    配置:

    1. <bean id="fac" class="com.factory.Factory"/>
    2. <bean id="s" factory-bean="fac" factory-method="createStu"/>

    测试:

    1. Student stu6 = (Student) ac.getBean("s");
    2. System.out.println(stu6);

    2.2.5 Bean标签常用属性

    ①id:给对象起名称,任意,必须唯一;

    ②class属性:创建对象所在类的全路径,使用构造创建对象,必不可少;

    ③name:别名,和id作用一样,可以起多个,空格分割;

    ④scope:取值 singleton(单例),prototype(多例),request,session,global-session;

    ⑤lazy-init:懒加载(可以配置全局的懒加载 default-lazy-init = ”true“ );

    ⑥生命周期: init-method(初始化) 和 destory-method(销毁)

    ④scope 测试:

    1. @Test
    2. public void facTest(){
    3. ApplicationContext ac = new ClassPathXmlApplicationContext("spring-2.xml");
    4. Student stu1 = ac.getBean(Student.class);
    5. System.out.println(stu1);
    6. Student stu2 = ac.getBean(Student.class);
    7. System.out.println(stu2);
    8. Student stu3 = ac.getBean(Student.class);
    9. System.out.println(stu3);
    10. Student stu4 = ac.getBean(Student.class);
    11. System.out.println(stu4);
    12. Student stu5 = ac.getBean(Student.class);
    13. System.out.println(stu5);
    14. }

    多例:

    <bean class="com.entity.Student" scope="prototype"/>

     单例(不写默认也是单例):

    <bean class="com.entity.Student" scope="singleton"/>

     自己实现单例模式:

    1. public class Student {
    2. private static Student student;
    3. private Student(){}
    4. public static Student createStudent(){
    5. if(student==null){
    6. student = new Student();
    7. }
    8. return student;
    9. }
    10. public void introduce(){
    11. System.out.println("我是一名学生!");
    12. }
    13. }

    ⑤懒加载:

            默认情况下,只针对单例模式,在创建 ApplicationContext 时,就创建了其中的对象;配置后,在使用该对象时才创建。

    ⑥生命周期:

    <bean class="com.entity.Student" scope="singleton" init-method="introduce" destroy-method="close"/>
    1. public class Student {
    2. public Student(){
    3. System.out.println("创建了一名学生!");
    4. }
    5. public void introduce(){
    6. System.out.println("我是一名学生!");
    7. }
    8. public void close(){
    9. System.out.println("再见了!");
    10. }
    11. }
    1. @Test
    2. public void Test(){
    3. ApplicationContext ac = new ClassPathXmlApplicationContext("spring-2.xml");
    4. ((ClassPathXmlApplicationContext)ac).close();
    5. }

            在多例模式下,destory-method 不会调用。

    2.2.6 BeanFactory和ApplicationContext

     

     BeanFactory是一个接口,是IOC容器的核心,负责实例化,配置和管理bean的生命周期;

    ApplicationContext是BeanFactory的子接口,提供更多面向实际应用的功能。

    使用 BeanFactory 获取对象:

    1. @Test
    2. public void BeanFactoryTest(){
    3. Resource re = new ClassPathResource("spring-2.xml");
    4. BeanFactory bf = new XmlBeanFactory(re);
    5. Student stu = bf.getBean(Student.class);
    6. System.out.println(stu);
    7. }

    2.3 spring DI(Dependency Injection)

            依赖注入,侧重于说明维护对象之间的关系;

    2.3.1 使用setter设置值(最常用)

    1. @Data
    2. public class Student {
    3. private String name;
    4. private String sex;
    5. private Integer age;
    6. private Double tall;
    7. private List hobbies;
    8. }
    1. <bean id="stu" class="com.wen.Student">
    2. <property name="name" value="张三"/>
    3. <property name="sex" value="男"/>
    4. <property name="age" value="20"/>
    5. <property name="tall" value="1.7"/>
    6. <property name="hobbies">
    7. <list>
    8. <value>篮球value>
    9. <value>钢琴value>
    10. <value>学习value>
    11. list>
    12. property>
    13. bean>

    2.3.2 使用构造方法设置值

    1. @Data
    2. public class Student {
    3. private String name;
    4. private String sex;
    5. private Integer age;
    6. private Double tall;
    7. private List hobbies;
    8. public Student() {
    9. }
    10. public Student(String name, String sex, Integer age, Double tall, List hobbies) {
    11. this.name = name;
    12. this.sex = sex;
    13. this.age = age;
    14. this.tall = tall;
    15. this.hobbies = hobbies;
    16. }
    17. }
    1. <bean id="stu" class="com.wen.Student">
    2. <constructor-arg name="name" value="张三"/>
    3. <constructor-arg name="sex" value="男"/>
    4. <constructor-arg name="age" value="20"/>
    5. <constructor-arg name="tall" value="1.7"/>
    6. <constructor-arg name="hobbies">
    7. <list>
    8. <value>篮球value>
    9. <value>钢琴value>
    10. <value>学习value>
    11. list>
    12. constructor-arg>
    13. bean>

    2.3.3 使用接口注入(spring 4.0 以后不支持)

    为属性赋值两个关键字(配合setter和构造使用):

    ①value:用于设置普通属性的数据(基本类型,字符串);

    ②ref :  用于设置对象类型的数据。

    司机:

    1. @Data
    2. public class Driver {
    3. private String name;
    4. private CarB car;
    5. }

    车:

    1. @Data
    2. public class CarB {
    3. private String brand;
    4. private Integer price;
    5. private Double speed;
    6. }

    spring:

    1. <bean id="driver" class="com.entity.Driver">
    2. <property name="name" value="张三"/>
    3. <property name="car" ref="car"/>
    4. bean>
    5. <bean id="car" class="com.entity.CarB">
    6. <property name="brand" value="宝马"/>
    7. <property name="price" value="300000"/>
    8. <property name="speed" value="75.0"/>
    9. bean>

  • 相关阅读:
    <react求和案例>react-redux基本使用与优化——Provider/mapDispatch
    相关分析——皮尔森相关系数、t显著性检验及Python实现
    157条超实用Python代码实例。问题+实例解答+原理解析+补充知识
    数据结构之索引查找(分块查找)
    获取泛型对应的类
    使用 BeanUtils.copyProperties属性拷贝
    量化交易是不是用机器预测股票涨跌?这靠谱吗?
    Win11笔记本耗电太快怎么办?
    鸿蒙开发接口定制管理:【@ohos.enterpriseDeviceManager (企业设备管理)】
    办理出境签证时间
  • 原文地址:https://blog.csdn.net/m0_71674778/article/details/126440268