spring框架(spring全家桶)

spring FrameWork

springBoot+springCloud+springCloud Data Flow

一:spring的两大核心机制:

  • IoC :工厂模式
  • AOP:代理模式

1:Ioc

Ioc是Spring是框架的灵魂,控制反转。

Student student = new Student();

lombok 可以帮助开发这者自动生成get set 方法..

在idea中使用必须安装插件

@Data注解

@AllArgsConstructor注解全参的构造

@NoArgsConstructor注解构造无参

设置mavend的版本太低:

  1. file - projectStructure.. - Modules - Language Level:jdk8以上
  2. File --> Settings --> Build,Execution,Deployment --> Compiler --> java Compiler

开发过程:


  1. 创建Maven工程,pom.xml导入依赖。


    xml</p></li> </ol> ¨K40K

    ¨K87K

    1. 在resources路径下创建spring.xml

      xml <?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="student" class="com.southwind.entity.Student"></bean> </beans>

      3.IoC容器通过读取spring.xml配置文件,加载bean标签来创建对象

      4.调用API来获取IoC中的已经创建的对象

      java //传统的开发方式是手动开发对象 // Student a = new Student(); // System.out.println(a); //IoC容器自动创建对线,开发者只需要取出对象即可 ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring.xml"); Student student = (Student)applicationContext.getBean("student"); System.out.println(student); }

    IoC容器创建Bean的两种方式:

    • 无参构造

      <bean id="student" class="com.southwind.entity.Student"></bean>

      给成员变量赋值(原理是利用set 方法修改的)

       <bean id="student" class="com.southwind.entity.Student">
            <property name="id" value="1"></property>
            <property name="name" value="张三"></property>
            <property name="age"value="20"></property>
        </bean>

      IoC取对象:

    • id取

            Student student = (Student)applicationContext.getBean("student");
    • 实体类的实例类取

            Student student = (Student)applicationContext.getBean(Student.class);

      实体类有多个抛异常

    • 有参构造

    <bean id="student1" class="com.southwind.entity.Student">
        <constructor-arg name="id" value="3"></constructor-arg>
        <constructor-arg name="name" value="王五"></constructor-arg>
        <constructor-arg name="age" value="18"></constructor-arg>
    </bean>
    <bean id="student1" class="com.southwind.entity.Student">
        <constructor-arg index="1" value="3"></constructor-arg>
        <constructor-arg index="0" value="王五"></constructor-arg>
        <constructor-arg index="2" value="18"></constructor-arg>
    </bean>

    取对象:

     ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring.xml");
            Student student = (Student)applicationContext.getBean("student1");
    //        Student student = (Student)applicationContext.getBean(Student.class);
            System.out.println(student);

    bean中包含特殊字符可以:**]]> **

    <bean id ="classes" class="com.southwind.entity.Classes">
        <property name="id" value="1"></property>
        <property name="name">
           <value><![CDATA[<一班>]]></value> 
        </property>
    </bean>

    IoC Di

    Di 指的是bean之间的依赖注入,设置对象之间的级联关系

    Classes:

    package com.southwind.entity;

    import lombok.Data;

    @Data
    public class Classes {
        private Integer id;
        private  String name;

    }

    Student:

    package com.southwind.entity;

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Student {
        private Integer id;
        private  String name;
        private Integer age;
        private Classes classes;
    }

    spring-di.xml:

    <?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"
    >

        <!--Classes-->
        <bean id ="classes" class="com.southwind.entity.Classes">
            <property name="id" value="1"></property>
            <property name="name" value="1班"></property>
        </bean>
        <!--    Student-->
        <bean id ="student" class="com.southwind.entity.Student">
            <property name="id" value="1"></property>
            <property name="name" value="张三"></property>
            <property name="age" value="18"></property>
            <property name="classes" ref="classes"></property>
        </bean>
    </beans>

    Test2:

    package com.southwind.test;

    import com.southwind.entity.Classes;
    import com.southwind.entity.Student;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class Test2 {
        public static void main(String[] args) {
            //IoC容器自动创建对线,开发者只需要取出对象即可
            ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring-di.xml");
    //        String[] names = applicationContext.getBeanDefinitionNames();
    //        for (String name:names){
    //            System.out.println(name);
    //        }
            Student student = (Student)applicationContext.getBean("student");
            Classes classes =(Classes)applicationContext.getBean("classes");
            System.out.println(student);
        }
    }

    Bean对象的级联学要使用ref属性来完成映射,而不能直接使用value否值会抛出类型转化异常:

    Classes:

    package com.southwind.entity;

    import lombok.Data;

    import javax.swing.*;
    import java.util.List;

    @Data
    public class Classes {
        private Integer id;
        private  String name;
        private List<Student> studentList;

    }

    spring-di.xml:

    <!--Classes-->
    <bean id ="classes" class="com.southwind.entity.Classes">
        <property name="id" value="1"></property>
        <property name="name">
           <value><![CDATA[<一班>]]></value>
        </property>
        <property name="studentList">
            <list>
                <ref bean="student" ></ref>
                <ref bean="student1" ></ref>
            </list>
        </property>
    </bean>

    但是要注意不能闭环

    spring中的Bean

    bean 是根据scope 来生成的,表示bean的作用域,scope有4种“

    1. singleton ,单例,表示通过Spring容器获取对象的唯一性 默认

      (无论取不取,只要加载IoC容器,就创建对象)

    2. prototype, 原型,表示通过Spring容器获取的对象是不同的

      (如果不取Bean就不创建对象,取几个就创建几个对象)

    3. request ,请求,表示在一次HTTP请求内有效

    4. session ,会话,表示在一个用户内有效

      requestion、session仅在web中有效

    Spring的继承

    ​ Spring的继承不同于Java ,区别:java中的继承是真对类的,SPring中的继承是针对对象的(Bean)

    ​ Spring的继承中,子Bean可以以继承父Bean中的值

    通过parent设置继承关系,同时值bean的值来继承和覆盖

    <bean id="user1" class="com.southwind.entity.User" scope="prototype" >
        <property name="id" value="1"></property>
        <property name="name" value="张三"></property>
    </bean>
    <bean id="user" class="com.southwind.entity.User" scope="prototype" parent="user1">
        <property name="name" value="李四"></property>
    </bean>

    即使是两个不同的类,只是赋值。(属性名一样必须,不一样抛异常)(只要成员变量一样就行)

    Spring的依赖:

    用来设置两个Bean的顺序

    IoC容器默认情况是通过spring.xml中bean的配置顺序来决定创建的顺序

    在不修改spring.xml来depends-on=""修改

    <bean id="user" class="com.southwind.entity.User" depends-on="student">

    </bean>
    <bean id="student" class="com.southwind.entity.Student"></bean>

    Spring读取外部资源

    实际开发中,数据库的资源一般会单独保存起来。一般会保存到后缀为properties的文件中,方便维护和修改,如果Spring加载资源,就需要在spring.xml中读取properties中的资源

    xxx.properties

    user=root
    password=root
    url = jdbc:mysql://localhost:3306/library
    driverName=com.mysql.cj.jdbc.Driver

    spring-xx.xml:

    <?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 https://www.springframework.org/schema/context/spring-context.xsd"
    >

    <!--    导入外部资源-->
        <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <!--SpringEL-->
        <bean id="dataSource" class="com.southwind.entity.DataSouse ">
            <property name="user" value="${user}"></property>
            <property name="password" value="${password}"></property>
            <property name="url" value="${url}"></property>
            <property name="driverName" value="${driverName}"></property>
        </bean>
    </beans>

    DataSource:

    package com.southwind.entity;

    import lombok.Data;

    @Data
    public class DataSouse {
        private String user;
        private String password;
        private String url;
        private String driverName;
    }

    测试类:

    package com.southwind.test;

    import com.southwind.entity.DataSouse;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class Test4 {
        public static void main(String[] args) {
            ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring-property.xml");
            DataSouse dataSouse = (DataSouse)applicationContext.getBean("dataSource");
            System.out.println(dataSouse);
        }
    }

    Spring p 命名空间

    p 命名空间简化Bean的配置

    Spring-p.xml:

    <?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"
           xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd"
    >

        <bean id="student" class="com.southwind.entity.Student" p:id="1" p:name="张三"></bean>
    </beans>

    测试类:

    package com.southwind.test;

    import com.southwind.entity.Student;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class Test5 {
        public static void main(String[] args) {
            ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring-p.xml");
            Student student = (Student)applicationContext.getBean("student");
            System.out.println(student);
        }
    }

    如果和级联一样:也是p:age-ref=""写类

    同时也要引入:

    xmlns:p="http://www.springframework.org/schema/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"
    >

    Spring的工厂方法:

    IoC通过工厂模式创建bean对线有两种方式:

    • 静态工厂模式

    • 实例工厂模式

      区别在与:静态工厂不需要实例化,实例工厂需要实例化

    1.静态工厂
    1. 实体类Car

      package com.southwind.entity;

      import lombok.AllArgsConstructor;
      import lombok.Data;

      @Data
      @AllArgsConstructor
      public class Car {
         private Integer num;
         private  String brand;
      }
    2. 创建静态工厂,使用静态工厂方法:

      package com.southwind.factory;

      import com.southwind.entity.Car;

      import java.util.HashMap;
      import java.util.Map;

      public class StaticCarFactory {
         private static Map<Integer, Car> carMap;
         static {
             carMap=new HashMap<>();
             carMap.put(1,new Car(1,"奥迪"));
             carMap.put(1,new Car(1,"奥拓"));
         }
         public  static  Car getCar(Integer num){
             return carMap.get(num);
         }
      }

    3.Spring-xx.xml

    <?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="car1" class="com.southwind.factory.StaticCarFactory" factory-method="getCar">
            <constructor-arg value="1"></constructor-arg>
        </bean>
    </beans>

    factory-method 是指向静态方法

    constructor-arg value="1” 是指向传入的参数

    测试类:

    package com.southwind.test;

    import com.southwind.entity.Car;
    import com.southwind.factory.StaticCarFactory;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class Test6 {
        public static void main(String[] args) {
    //        Car car = StaticCarFactory.getCar(1);
            ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring-factory.xml");
            Car car = (Car)applicationContext.getBean("car1");
            System.out.println(car);
        }
    }
    2.实例工厂方法:

    1.创建实例工厂类、工厂方法

    package com.southwind.factory;

    import com.southwind.entity.Car;

    import java.util.HashMap;
    import java.util.Map;

    public class InstanceCarFactory {
        private Map<Integer, Car> carMap;
        public InstanceCarFactory(){
            carMap= new HashMap<>();
            carMap.put(1,new Car(1,"奥迪"));
            carMap.put(1,new Car(1,"奥托"));

        }
        public  Car getCar(Integer num){
            return carMap.get(num);
        }
    }

    2.spring-xx.xml

    <!--    实例工厂-->
        <bean id="instanceCarFactory" class="com.southwind.factory.InstanceCarFactory"></bean>
    <!--    通过实例工厂获取Car-->
        <bean id="car2" factory-bean="instanceCarFactory" factory-method="getCar">
            <constructor-arg value="1"></constructor-arg>
        </bean>

    测试类:

    package com.southwind.test;

    import com.southwind.entity.Car;
    import com.southwind.factory.StaticCarFactory;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class Test6 {
        public static void main(String[] args) {
    //        Car car = StaticCarFactory.getCar(1);
    //        ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring-factory.xml");
    //        Car car = (Car)applicationContext.getBean("car1");
    //        System.out.println(car);
    //    }
    //        实例工厂
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-factory.xml");
            Car car = (Car) applicationContext.getBean("car2");
            System.out.println(car);
        }
    }

    区别

    1. 静态工厂方法创建Car对象,不需要创建Car对象,因为静态工厂的静态方法,不需要通过创建对象即可调用。spring-xx.xml中只需要配置一个Bean,即最终的Car即可。
    2. 实例工厂方法创建Car对象,需要实例化工厂对象,因为getCar()方法是非静态的,就必须通过实例化的对象才能调用,所以就必须创建工厂对象,spring。xml中,要配置两个Bean一个是工厂对象,一个是Car 对象。

    Spring IoC 自动装载 autowire:

    自动装载是Spring提供的一种更加简单的方式,来完成DI,不需要手动配置property ,IoC容器会自动选择Bean玩成注入。

    自动装载俩种:

    • byName ,通过属性名完成自动装载

    • byType,通过属性对应的数据类型完成自动装载

      byName

      1.创建实体类

      package com.southwind.entity;

      import lombok.Data;

      @Data
      public class Presson {
        private  Integer Id;
        private String name;
        private Car car;

      }

    2.在spring.xml中配置Car和Person的Bean,通过自动装载完成依赖注入

    <bean id="person" class="com.southwind.entity.Presson" autowire="byName">
        <property name="id" value="1"></property>
        <property name="name" value="张三"></property>
    </bean>
    <bean id="car" class="com.southwind.entity.Car">
        <constructor-arg name="num" value="1"> </constructor-arg>
        <constructor-arg name="brand" value="奥迪"></constructor-arg>
    </bean>

    测试:

    package com.southwind.test;

    import com.southwind.entity.Presson;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class Test7 {
        public static void main(String[] args) {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-autowire.xml");
            Presson preson =(Presson)applicationContext.getBean("person");
            System.out.println(preson);
        }
    }

    byType:

    1.实体类

    2.在spring.xml中配置Car和Person的Bean,通过自动装载完成依赖注入

    <bean id="person" class="com.southwind.entity.Presson" autowire="byType">
        <property name="id" value="1"></property>
        <property name="name" value="张三"></property>
    </bean>
    <bean id="car" class="com.southwind.entity.Car">
        <constructor-arg name="num" value="1"> </constructor-arg>
        <constructor-arg name="brand" value="奥迪"></constructor-arg>
    </bean>

    注意:

    使用byType进行自动装载时,多个会有异常。

    Spring IoC基于注解的开发

    SpingIoC的作用帮助开发者创建项目中所需要的Bean,同时完成Bean之间的依赖注入关系。DI

    实现功能有两种方式:

    • 基于xml

    • 基于注解

      基于注解的配置有两部:

    1. 配置自动扫包

      xml <!-- 自动扫包--> <context:component-scan base-package="com.southwind.entity"></context:component-scan>

    2. 添加注解: @Component (默认首字母类第一个字母小写为名字)

      java package com.southwind.entity;

      import lombok.Data;
      import org.springframework.stereotype.Component;

      @Data
      @Component
      public class Repository {
      private DataSouse dataSouse;
      }

      改名字:@Component(value = "myrepo")

      java package com.southwind.entity;

      import lombok.Data;
      import org.springframework.stereotype.Component;

      @Data
      @Component(value = "myrepo")
      public class Repository {
      private DataSouse dataSouse;
      }

      分析注入得到类:

      String[] s= applicationContext.getBeanDefinitionNames();
      for(String name :s){
        System.out.println(name);
      }

    DI:

    package com.southwind.entity;

    import lombok.Data;
    import org.springframework.stereotype.Component;

    @Data
    @Component
    public class DataSouse {
        private String user;
        private String password;
        private String url;
        private String driverName;
    }

    自动装载:@Autowired(默认时byType)

    package com.southwind.entity;

    import lombok.Data;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;

    @Data
    @Component
    public class Repository {
        @Autowired
        private  DataSouse dataSouse;
    }

    要改变为byName()配合 @Qualifier(value="DS")

    @Data
    @Component
    public class Repository {
        @Autowired
        @Qualifier(value="DS")
        private  DataSouse dataSouse;
    }

    实体类中的普通的成员变量可以通过@Value进行赋值

    @Data
    @Component(value = "DS")
    public class DataSouse {
        @Value("root")
        private String user;
        @Value("root")
        private String password;
        @Value("jdbc:mysql://localhost:3306/library")
        private String url;
        @Value("com.mysql.cj.jdbc.Driver")
        private String driverName;
    }

    实际开发的使用

    实际开发中会将程序分为3层:

    1. Controller
    2. Servlet
    3. Repository(DAO)

    关系Controller 调运Servlet 调运 Repository(DAO)

    @Component 注解是将标注的类加载到IoC容器中,实际开发中可以分别根据

    @Controller 控制层

    @Service 业务层

    @Repository 持久层

    代码:

    1.

    package com.southwind.Repository;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;


    public interface myRepository {
        public  String domyRepository(Double score);
    }
    package com.southwind.Repository.impl;

    import com.southwind.Repository.myRepository;
    import org.springframework.stereotype.Repository;

    @Repository
    public class mymyRepositoryImpl  implements myRepository {
        @Override
        public String domyRepository(Double score) {
            String result="";
            if(score<60){
                result="不及格";
            }else if(score>=60&&score<80){
                result="合格";
            }else {
                result="优秀";
            }
            return result;
        }
    }

    2.

    package com.southwind.Service;

    import org.springframework.stereotype.Component;


    public interface myService {
        public String doSrvice(Double score);
    }
    package com.southwind.Service.impl;

    import com.southwind.Repository.myRepository;
    import com.southwind.Service.myService;
    import lombok.Setter;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;


    @Setter
    @Service
    public class myServiceImpl implements myService {
        @Autowired
        private myRepository  myRepository;
        @Override
        public String doSrvice( Double score) {
            return myRepository.domyRepository(score);
        }
    }

    3.

    package com.southwind.Controller;

    import com.southwind.Service.myService;
    import lombok.Data;
    import lombok.Setter;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;

    @Controller(value = "a")
    @Data
    public class myControlller {
    //客户端请求
        @Autowired
        private com.southwind.Service.myService myService;
    ;    public String service(Double score){
            return myService.doSrvice(score);
        }
    }

    配置:

    <?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 https://www.springframework.org/schema/context/spring-context.xsd"
    >


    <!--    <bean id="repository" class="com.southwind.entity.Repository"></bean>-->
    <!--    自动扫包-->
        <context:component-scan base-package="com.southwind"></context:component-scan>
    <!--    <bean id="controller" class="com.southwind.Controller.myControlller">-->
    <!--        <property name="myService" ref="service"></property>-->
    <!--    </bean>-->
    <!--    <bean id="service" class="com.southwind.Service.impl.myServiceImpl">-->
    <!--        <property name="myRepository" ref="repository"></property>-->
    <!--    </bean>-->
    <!--    <bean id="repository" class="com.southwind.Repository.impl.mymyRepositoryImpl"></bean>-->
    </beans>

    测试类:

    package com.southwind.test;

    import com.southwind.Controller.myControlller;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class Test9 {
        public static void main(String[] args) {
            ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring-annotation.xml");
    //        String[] s= applicationContext.getBeanDefinitionNames();
    //        for(String name :s){
    //            System.out.println(name);
    //        }
    //        客户端请求
            myControlller myControlller =(myControlller) applicationContext.getBean("a") ;
            String result = myControlller.service(new Double(77));
            System.out.println(result);
        }
    }

    Spring IoC的底层实现:

    核心技术: XML解析+反射

    具体思路:

    1. 根据需求编写XML文件,配置需要的创建的Bean.
    2. 编写程序需要的XML文件,获取Bean的相关信息,类,属性,id
    3. 根据第二步骤获得到的信息,结合反射机制动态的创建对象,同时完成属性的赋值
    4. 将创建好的bean存入Map集合中,设置key就是bean的id的值,value就是bean的对象
    5. 提供方法从Map中获得对应的value
posted on 2022-04-08 09:01  Steam残酷  阅读(50)  评论(0)    收藏  举报