zl程序教程

您现在的位置是:首页 >  后端

当前栏目

JavaEE——Spring学习笔记01【Ioc开发的模式】

2023-09-14 09:14:08 时间

 JavaEE——Spring学习笔记01【Ioc开发的模式】

 JavaEE——Spring学习笔记02【Spring和Mybatis的整合】

JavaEE——Spring学习笔记03【AOP开发】

JavaEE——Spring学习笔记04【Spring的事务管理】

JavaEE——Spring学习笔记05【Mybatis的逆行工程】

JavaEE——Spring学习笔记06【Maven创建Web工程】

目录

一、配置idea中maven的本地仓库

二、Spring框架

1. 什么是Spring?

1. 数据处理层:dao层       

2. 业务管理层:service层

3. 控制层:界面层:Controller层

2.为什么要学习Spring?

三、Spring两大核心之 Ioc

1. Ioc(Inversion Of Control)控制反转

2. Ioc开发

2.1 添加Spring的核心jar包

 3. Spring的两种容器文件的加载方式

 四、Ioc开发的模式

1.Ioc的xml开发模式

  1.1设置容器中bean为单例或多例

  1.2 Spring管理对象的创建

1.3 给对象的属性赋值(注入)三种方式

 1.4 自定义对象的自动注入

 2. Ioc的注解开发模式

2.1 创建对象的注解(放入类型)

2.2 赋值的注解(取出类型)

3. Ioc的注解开发和Xml开发的配合使用

 3.1 注解开发

3.2 xml开发

3.2 xml开发和注解开发的配合使用


一、配置idea中maven的本地仓库

配置该设置可以创建Maven工程的时候速度更快,不会自动下载一些无用的组件

 -DarchetypeCatalog=internal

二、Spring框架

1. 什么是Spring?

     Spring意在春天,一切生命的开始。

     Spring在我们Java学子中它是一个面向分层的一站式轻量级框架,优势在于任意分层可以使用任意组件,它能使JavaEE开发变得更简单。Spring中的两大核心是Ioc(控制反转)AOP(面向切面编程)

     一站式开发的分层结构:

  1. 数据访问(处理)层:dao层,完成数据库的一系列操作
  2. 业务逻辑层:service层,业务处理和事务管理
  3. 界面层(控制层):controller层,springmvc,给出访问的页面

1. 数据处理层:dao层       

        操作数据库的过程

        1) mybatis的动态代理

        2) mybatis的全局配置文件(操作数据库的文件)

        3) 实体类、数据库

2. 业务管理层:service层

        调用dao层

        业务的接口和实现类

3. 控制层:界面层:Controller层

       调用的service层

       客户端浏览器的界面层(实现了前端后后端的数据交换)

2.为什么要学习Spring?

1. 方便解耦合,简化开发

    耦合性就是模块与模块之间的依赖的关系,调用关系、数据传递。

    硬编码:就是将数据直接写入到代码中进行编译开发的,比如在没有学习mybatis的时候,我们会将sql语句直接写在Java源码中。

2. AOP编程的支持

    在不改变源码可以对程序进行增强,比如在一个程序中有保存和删除的功能,我们可以利用AOP编程对这两个功能提供校验、日志信息,在后期使用中主要用于事务管理!

3. 方便程序的测试

    可以用非容器依赖的编程进行几乎所有的测试工作,测试不在是昂贵的操作!

4. 方便集成各种优秀的框架

    SSM框架的整合:Spring+SpringMVC+Mybatis

5. 降低了JavaEE开发使的难度

    Spring库框架对很多难用的JavaEE中API,如JDBC,远程调用等提供了统一的分子官方,通过Spring的简易封装这些JavaEE的API开发难度大大降低。

6. 对JavaEE开发的每一层架构都有解决的方案

7. 。。。。。。。。

三、Spring两大核心之 Ioc

     Spring框架的两大重要核心分别为Ioc(控制反转)和AOP(面向切面)

1. Ioc(Inversion Of Control)控制反转

     Ioc就是控制反转的意思,在Spring框架中它是一个比较重要的核心内容,意图是将对象的创建和管理的权力交给Spring框架(Spring容器)进行操作。

2. Ioc开发

    Ioc容器是用来放所有的被反转的对象的,也就我们通过Spring创建的对象都是放在这个Ioc容器,它只是一个思想或概念,所以Ioc控制反转是由DI依赖注入来具体实现。

Ioc的两个概念:一个是Ioc容器的概念,一个是依赖注入DI。

DI依赖注入:

    依赖:缺少这个依赖玩不了

    注入:往里面放

    依赖注入:从Ioc容器拿一个放进去,否则就不能玩

2.1 添加Spring的核心jar包

<!--添加Spring的核心jar包-->

<dependency>

        <groupId>org.springframework</groupId>

        <artifactId>spring-context</artifactId>

        <version>5.2.7.RELEASE</version>

</dependency>

 3. Spring的两种容器文件的加载方式

       ApplicationContext是用于加载Spring配置文件的,在程序中充当”容器”角色,其实它是有两个实现类,一个是ClassPathXmlApplicationContext类,另外一个是FileSystemXmlApplicationContext类。两个类有什么区别?

ClassPathXmlApplicationContext类默认回去到classPath中去找容器文件,classPath指定的编译后的classes目录下的容器文件。

FileSystemXmlApplicationContext类默认是区项目路径下加载,可以是相对路径,也可以是绝对路径,如果是相对路径必须在spring容器文件前面加上classpath:

@Test
    public void test01() {
        //1、创建一个Spring容器对象,加载Spring容器的配置文件
        //一旦Spring的容器对象被创建,在Spring容器中所有的对象就已经被创建了
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        ApplicationContext applicationContext = new FileSystemXmlApplicationContext("classpath:applicationContext.xml");
        //2.从Spring容器中获取Date对象
        Date date = (Date) applicationContext.getBean("myDate");
        System.out.println("date = " + date);
    }

 绝对路径的方式:

ApplicationContext applicationContext =
    new FileSystemXmlApplicationContext("D:\\IT\\Java\\IdeaProjects\\Suke2\\04-SSM\\01-spring-ioc\\src\\main\\resources\\applicationContext.xml");

 四、Ioc开发的模式

      Ioc控制反转是通过DI依赖注入来进行实现,其主要方式有两种,一种的xml开发方式,一种注解开发方式。

1.Ioc的xml开发模式

      单纯的配置Spring的容器文件,使用bean管理对象。

bean标签: 用来定义一个对象的,class属性的值必须是一个类的权限定名称,不能是接口
    id属性: bean标签的唯一标识,可以自定义,Spring是通过这个id值来获取对象的
    class属性:指类的全限定名称,指定某个类来构建对象的

property标签: 一般情况下是给对象的属性赋值
    name属性: 对象对应的属性名
    value: 给普通的属性进行赋值,比如String,int。。。
    ref属性: 给自定义类型的对象进行赋值(引用类型)

  1.1设置容器中bean为单例或多例

        1)设置bean标签中scope属性的值有两种

                 -- scope=”singleton“:单例(默认的方式)

                 -- scope=”prototype“:多例

        2)多例和单例的区别

                 Spring管理的单例创建出来的是同一个对象,多例不是同一个对象。

        3)单例的案例演示

<!--使用bean标签创建Cat对象:默认采用单例模式创建对象,scope="singleton"默认省略-->
    <bean id="cat" class="com.suke.Cat" scope="singleton"/>
/*
 * 猫咪测试类
 * */
public class CatTest {
    @Test
    public void test01() {
        //1.创建Spring容器对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        //2.从Spring容器中获取对象
        Cat cat = (Cat) applicationContext.getBean("cat");
        Cat cat2 = (Cat) applicationContext.getBean("cat");

        System.out.println(cat == cat2);

        cat.show();
        cat2.show();
    }
}

           4)多例的案例演示

<!--多例-->
    <bean id="cat" class="com.suke.Cat" scope="prototype"/>

  1.2 Spring管理对象的创建

     1.2.1 无参构造函数的方式

          推荐大家使用的方式。

<!--创建user对象1:无参构造创建-->
    <bean id="user" class="com.suke.User"/>
/*
     * 测试无参构造创建对象
     * */
    @Test
    public void testUser01() {
        //1.创建Spring的容器对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-user.xml");

        //2.获取Spring容器中的管理对象
        User user = (User) applicationContext.getBean("user");
    }

     1.2.2有参构造函数的方式

          不推荐使用

<!--创建user对象2:有参构造创建-->
    <bean id="user2" class="com.suke.User">
        <constructor-arg name="username" index="0" type="java.lang.String" value="李四"/>
        <constructor-arg name="password" index="1" type="java.lang.String" value="1234"/>
    </bean>

    <!--创建user对象3:有参构造创建-->
    <bean id="user3" class="com.suke.User">
        <constructor-arg index="0" type="java.lang.String" value="王五"/>
        <constructor-arg index="1" type="java.lang.String" value="12345"/>
    </bean>

    <!--创建user对象4:有参构造创建-->
    <bean id="user4" class="com.suke.User">
        <constructor-arg name="username" value="赵六"/>
        <constructor-arg name="password" value="123456"/>
    </bean>
/*
     * 测试有参构造创建对象
     * */
    @Test
    public void testUser02() {
        //1.创建Spring的容器对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-user.xml");

        //2.获取Spring容器中的管理对象
        User user2 = (User) applicationContext.getBean("user2");
        System.out.println(user2.getUsername() + ":" + user2.getPassword());
        User user3 = (User) applicationContext.getBean("user3");
        System.out.println(user3.getUsername() + ":" + user3.getPassword());
        User user4 = (User) applicationContext.getBean("user4");
        System.out.println(user4.getUsername() + ":" + user4.getPassword());
    }

  1.2.3静态工厂化方法创建对象(不常见了解即可)

     有时候对象的创建对象可以使用工厂来完成,例如王者荣耀英雄界面点击某一个英雄头像确定后会根据用户选择不同编号来创建英雄对象。

 1)创建一个英雄的父类

/*
 * 英雄的类
 * */
public class Hero {
    String name;
    Integer human;

    public Hero(String name, Integer human) {
        this.name = name;
        this.human = human;
    }

    public Hero() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getHuman() {
        return human;
    }

    public void setHuman(Integer human) {
        this.human = human;
    }

    @Override
    public String toString() {
        return "Hero{" +
                "name='" + name + '\'' +
                ", human=" + human +
                '}';
    }
}

2)创建三个角色类继承英雄类

   吕布类

/*
 * 吕布英雄类
 * */
public class LvBu extends Hero {

    public LvBu() {

        this.human = 1;
        this.name = "吕布";
    }
}

   貂蝉类

/*
 * 貂蝉英雄类
 * */
public class DiaoChan extends Hero {

    public DiaoChan() {

        this.human = 2;
        this.name = "貂蝉";
    }
}

   董卓类

/*
 * 董卓英雄类
 * */
public class DongZhuo extends Hero {

    public DongZhuo() {

        this.human = 3;
        this.name = "董卓";
    }
}

 3)构建一个英雄的静态工厂化类

/*
 * 英雄的工厂类
 * */
public class HeroFactory {
    public static Hero createHero(int num) {

        Hero hero;//要创建的英雄

        if (num == 1) {
            //创建吕布
            hero = new LvBu();
        } else if (num == 2) {
            //创建貂蝉
            hero = new DiaoChan();
        } else {
            //创建貂蝉
            hero = new DongZhuo();
        }

        return hero;
    }
}

 4)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
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--bean标签:用来定义一个对象的,class属性的值必须是一个类的权限定名称,不能是接口
        id属性:bean标签的唯一标识,可以自定义,Spring是通过这个id值来获取对象的
        class属性:指类的全限定名称,指定某个类来构建对象的-->

    <!--property标签:一般情况下是给对象的属性赋值
        name属性:对象对应的属性名
        value:给普通的属性进行赋值,比如String,int。。。
        ref属性:给自定义类型的对象进行赋值(引用类型)-->

    <!--Spring管理的单例创建出来的是同一个对象,多例不是一个对象-->

    <!--使用bean标签创建对象:默认采用单例模式创建对象,scope="singleton"默认省略-->

    <!--创建Hero对象:静态工厂-->                    //静态工厂方法
    <bean id="hero" class="com.suke.HeroFactory" factory-method="createHero">
        <constructor-arg value="2"/> //利用构造器创建出具体对象
    </bean>
</beans>

 5)测试类

/*
 * 英雄的测试类
 * */
public class HeroTest {

    @Test
    public void testHero() {
        //1.创建Spring的容器对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-hero.xml");

        //2.获取英雄的工厂化对象:根据编号获取具体生成的英雄的角色
        Hero hero = (Hero) applicationContext.getBean("hero");
        System.out.println("hero = " + hero);
    }
}

1.3 给对象的属性赋值(注入)三种方式

     对象我们使用的是bean标签进行创建的,那么对象创建好以后要对对象的成员变量进行赋值,那又该怎么办呢?我们先给大家推荐3种方式。

1.3.1setter方法的方式注入属性值(掌握)

 条件:对象中必须要有成员变量对应的setter方法

1)给普通的成员变量赋值

 2)给自定类型对象赋值:在Student类中传入School对象作为成员变量

    ​​​​1.3.2 构造器的方式注入属性值(了解)

    1.3.3 内部装配注入属性值(了解)

    1.3.4 p名称空间方式属性注入

      这种方式不建议搭建使用,她其实就是setter方式变向的一种写法。

  1.3.5 属性文件的方式进行赋值

1) stu属性文件

2) Spring的容器文件:首先要加载属性文件

3) 测试方法

 1.3.6 对List集合进行赋值

 1)SH2105班级类

 2)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
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--使用bean标签管理SH2105对象-->
    <bean id="sh2105" class="com.bjpowernode.pojo.SH2105">
        <!--给List集合属性赋值:简单类型-->
        <property name="names">
            <list>
                <value>张三</value>
                <value>李四</value>
                <value>王五</value>
                <value>赵六</value>
            </list>
        </property>

        <!--给List集合属性赋值:自定义对象类型-->
        <property name="students">
            <list>
                <bean class="com.bjpowernode.pojo.Student">
                    <property name="name" value="刘德华"/>
                    <property name="age" value="60"/>
                    <property name="school" ref="school"/>
                </bean>

                <bean class="com.bjpowernode.pojo.Student">
                    <property name="name" value="张学友"/>
                    <property name="age" value="60"/>
                    <property name="school" ref="school"/>
                </bean>

                <bean class="com.bjpowernode.pojo.Student">
                    <property name="name" value="郭富城"/>
                    <property name="age" value="60"/>
                    <property name="school" ref="school"/>
                </bean>

                <bean class="com.bjpowernode.pojo.Student">
                    <property name="name" value="黎明"/>
                    <property name="age" value="60"/>
                    <property name="school" ref="school"/>
                </bean>


            </list>
        </property>
    </bean>

    <bean id="school" class="com.bjpowernode.pojo.School">
        <property name="name" value="香港大学"/>
        <property name="address" value="香港九龙"/>
    </bean>
</beans>

使用ref标签给自定义对象赋值

 3)测试类

    1.3.7 对Set集合进行赋值

1)SH210502班级类

 2)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
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--使用bean标签管理SH2105对象-->
    <bean id="sh210502" class="com.bjpowernode.pojo.SH210502">
        <!--给Set集合属性赋值:简单类型-->
        <property name="names">
            <set>
                <value>张三</value>
                <value>李四</value>
                <value>王五</value>
                <value>赵六</value>
            </set>
        </property>

        <!--给Set集合属性赋值:自定义对象类型-->
        <property name="schools">
            <set>
                <bean class="com.bjpowernode.pojo.School">
                    <property name="name" value="香港学院"/>
                    <property name="address" value="香港彭罗湾"/>
                </bean>

                <bean class="com.bjpowernode.pojo.School">
                    <property name="name" value="香港家里蹲"/>
                    <property name="address" value="香港九龙"/>
                </bean>

                <ref bean="school"/><!--代表集合中的一个元素-->
            </set>
        </property>
    </bean>

    <bean id="school" class="com.bjpowernode.pojo.School">
        <property name="name" value="香港大学"/>
        <property name="address" value="香港九龙"/>
    </bean>
</beans>

  3)测试类

 1.3.8 对Map集合进行赋值

1)SH2105Map班级类

/**
 * 班级类
 */
public class SH2105Map {

    /*传入Map集合*/
    private Map<String,String> names;
    private Map<Integer,School> schools;

    //传入属性对象
    private Properties properties;

    public Map<String, String> getNames() {
        return names;
    }

    public void setNames(Map<String, String> names) {
        this.names = names;
    }

    public Map<Integer, School> getSchools() {
        return schools;
    }

    public void setSchools(Map<Integer, School> schools) {
        this.schools = schools;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "SH2105Map{" +
                "names=" + names +
                ", schools=" + schools +
                ", properties=" + properties +
                '}';
    }
}

 2)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
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--使用bean标签管理SH2105对象-->
    <bean id="sh2105Map" class="com.bjpowernode.pojo.SH2105Map">

        <property name="names">
            <map>
                <entry key="及时雨" value="宋江"/>
                <entry key="智多星" value="吴用"/>
                <entry key="小娘子" value="潘金莲"/>
            </map>
        </property>


        <property name="schools">
            <map>
                <entry key="1001">
                    <bean class="com.bjpowernode.pojo.School">
                        <property name="name" value="梁山学院"/>
                        <property name="address" value="山东梁山泊"/>
                    </bean>
                </entry>

                <entry key="1002">
                    <bean class="com.bjpowernode.pojo.School">
                        <property name="name" value="西门府"/>
                        <property name="address" value="西门路"/>
                    </bean>
                </entry>

                <entry key="1003">
                        <ref bean="school"></ref>
                </entry>
            </map>
        </property>

        <property name="properties">
            <map>
                <entry key="2001" value="李逵"/>
                <entry key="2002" value="武松"/>
            </map>
        </property>

    </bean>

    <!--外部创建一个School对象-->
    <bean id="school" class="com.bjpowernode.pojo.School">
        <property name="name" value="景阳冈"/>
        <property name="address" value="深山老林"/>
    </bean>
</beans>

 3)测试方法

 1.4 自定义对象的自动注入

       所谓的自动注入,其实就是一个半自动,它只能自动那个装配bean当中的属性。将自定义对象赋值可以通过名称或类型的方式自动注入,简化了我们ref属性的使用。

1.4.1 byName(通过名称)        

      根据自定义对象的属性名称进行自动注入,当配置文件中被调用者bean的id值与代码中调用者bean类的属性名相同,那我们就可以直接使用byName的方式直接给自定义对象进行自动注入赋值。

autowire="byName"

1)学校类

 2)学生类

 3)Spring的容器文件中配置

  第一种写法

 第二种写法

 4)测试方法

 1.4.2 byType(通过类型)

      使用通过类型自动注入,配置文件中被调用者bean的class属性指定的类要与代码中调用者bean类的自定义对象类型的属性同源,既可以 实现属性的自动注入,与名称无关。同源目录是指:子父类,一个包中,上下包。

autowire="byType"

1)学生类和学校类同上

2)Spring容器的配置文件

   第一种方式

    第二种方式

 3)测试方法​​​​​​​

 2. Ioc的注解开发模式

      注解的开发分为两种情况,一种是从Ioc容器中放入,一种是从Ioc容器取出。注解开发的前提在spring容器文件中配置注解的包扫描器。

2.1 创建对象的注解(放入类型)

        2.1.1 @Component(在不知道用哪个注解的时候用它即可)

        2.1.2 @Repository(dao层创建)

        2.1.3 @Service(service层创建)

        2.1.3 @Controller(controller层创建)

2.2 赋值的注解(取出类型)

        2.2.1 @Value(“普通数据数据”)

                 @Value注解可以用在属性上面,也可以用在setter方法

        2.2.2 @Autowired(“自定义对象自动注入”)

         1)通过名称

                @Autowired和@Qualifier(value值必须是bean的id值)必须联合使用。

                可以使用JDK中 @Resource注解来替换这两个注解,通过名称直接@Resource(name值bean的id值保持一致)

        2)通过类型

                跟名称没有任何关系,只需要在同源目录下。

        2.2.3 @Resource(“自定义对象自动注入”)

        该注解不是Spring框架中,是JDK中,可以和Spring融合使用,导入它的依赖包,直接可以通过名称给对象赋值,@Resource(name = "mySchool"代替 @Autowired
                                                                                                 @Qualifier(value = "mySchool")

当然也可以通过类型

3. Ioc的注解开发和Xml开发的配合使用

 3.1 注解开发

         1)优点

             -- 方便

             -- 直观

             -- 高效(配置文少,代码量少)

         2)缺点

              硬编码会存在java源码中,修改源码是需要重新编译。

3.2 xml开发

         1)优点:

            -- 配置和代码都是分离的

            -- 在xml中修改数据,java文件无需重新编译,需要重新启动服务器加载。

         2)缺点:

           Spring的配置文件过于繁琐,不适合应用在大型的项目

3.2 xml开发和注解开发的配合使用

           自定义对象成员变量的赋值交给注解

           像实体类的赋值交给xml完成