第6章-初识Spring框架

1 Java EE与Jakarta EE

Java EE是Java Enterprise Edition的缩写,它是甲骨文提出的一套完整的开发规范。Java平台最早由sun公司开发,后来甲骨文兼并了Sun。

Java EE以前一直由甲骨文维护,直到2018年3月,Java EE被Jakarta EE,以后由开源组织Eclipse基金会来维护。

在这里插入图片描述

2022年11月,VMware发布了Spring Framework 6.0,它的依赖环境是JDK17+、Jakarta EE 9+(Tomcat 10/Jetty 11)。JDK17是甲骨文2021年9月14日发布的一个LTS(长期支持)版。Jakarta EE已经发布到10版本,正在提议11版本。

在这里插入图片描述

1.1 Jakarta EE是什么

网址:https://jakarta.ee/release/10/

Jakarta EE是Eclipse基金在Java EE基础上发布的一套Java开发规范。

规范是什么?比如说,冯·诺依曼定义了计算机架构,由输入设备、输出设备、运算器、控制器、内存、外存组成,这就可以看成一套high-level(高级)的规范。规范就是一组约定,其他人按照约定实现。它相当于工业标准,协议也可以看成某种具体的规范。

Jakarta EE的大量规范性文档是由一系列的JSR组成的。JSR是Java Specification Requests的缩写,意思是Java规范提案。

在这里插入图片描述

1.2 Jakarta EE文档

下载地址:https://jakarta.ee/learn/docs/jakartaee-tutorial/current/web/webapp/webapp.html
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. Spring介绍

2.1 相关网站

2.2 Spring概述

  • Spring Framework是Java平台的明星框架,Spring Framework必须依赖Jakarta EE(Java EE)。

  • Spring是第三方框架,Jakarta EE是规范,Spring的所有开发者必须满足Jakarta EE平台的要求。

  • Spring是轻量级框架,Jakarta EE中的EJB(Enterprise Java Bean)是重量级框架。

  • Spring最为核心的理念的是控制反转(Inversion of Control,IoC)和面向切面编程(Aspect Oriented Programming,AOP)。

  • IoC是Spring的基础,它支撑着Spring对JavaBean的管理功能;AOP是Spring 的重要特性,AOP是通过预编译方式和运行期间动态代理实现程序功能,也就是说可以在不修改源代码的情况下,给程序统一添加功能。

  • Spring贯穿于表现层(Web层)、业务逻辑层(Service层)和持久层(Dao层)。

    • 在表现层提供了Spring MVC框架,并且Spring还可以与Struts框架整合。
    • 业务逻辑层可以管理事务、记录日志等。
    • 持久层可以整合MyBatis、Hibernate、JdbcTemplate等技术。

2.3 Spring的体系结构

在这里插入图片描述

3. Spring入门程序

环境说明:

  • JDK 21
  • Maven 3.9.6
  • Spring 6.1.5
  • IDEA 2024.1

3.1 环境搭建

  • 导入相关依赖

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.1.5</version>
        </dependency>
    
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>
    
    </dependencies>
    
  • 创建名称为HelloSpring的类

    public class HelloSpring {
        private String userName;
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public void show() {
            System.out.println(userName + ":欢迎来到Spring");
        }
    }
    
  • 编写Spring的配置文件

    参考文档:https://docs.spring.io/spring-framework/reference/core/beans/basics.html

    1. 配置文件的放置位置:任意位置

    2. 配置文件的命名:没有要求,建议applicationContext.xml

在这里插入图片描述

<bean id="helloSpring" class="com.jxzz.HelloSpring">
    <property name="userName" value="张三"></property>
</bean>
  • 测试

    public class MyTest {
    
    @Test
    public void TestNew() {
        HelloSpring helloSpring = new HelloSpring();
        helloSpring.setUserName("张三");
        helloSpring.show();
    	}
    
    @Test
    public void TestHelloSpring() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
    //        HelloSpring helloSpring = (HelloSpring)applicationContext.getBean("helloSpring");
    //        HelloSpring helloSpring = applicationContext.getBean("helloSpring", HelloSpring.class);  //推荐
        HelloSpring helloSpring = applicationContext.getBean(HelloSpring.class);
        helloSpring.show();
    	}
    }
    

4. 控制反转(IoC)

控制:对于成员变量赋值的控制权
反转控制:把对于成员变量赋值的控制权,从应用代码中反转(转移)到Spring容器中完成
好处:降低程序代码之间的耦合度(解耦合)
底层实现:工厂设计模式

传统面向对象编程中,获取对象的方式是用关键字“new”主动创建对象,即应用程序掌握着对象的控制权。

在这里插入图片描述
在这里插入图片描述

Spring框架:对象的实例不再由调用者创建,而是由Spring的IoC容器来创建,IoC容器负责控制程序之间的关系,而不是由调用者的程序代码直接控制。

在这里插入图片描述
在这里插入图片描述

控制权由应用代码转移到了IoC容器,控制发生了反转,这就是Spring的控制反转。

由Spring容器创建对象特称为Bean或者组件(Componet)。

5. 依赖注入(DI)

注入:通过Spring容器,为对象(bean,组件)的成员变量赋值

依赖注入:当一个类需要另一个类时,就意味着依赖,一旦出现依赖,就可以把另一个类作为本类的成员变量,最终通过Spring容器进行注入(赋值)。
好处:解耦合

5.1 构造方法注入

Spring容器调用构造方法为实例的成员变量赋值。

Spring在读取配置信息后,会通过反射方式调用实例的构造方法。

5.1.1 开发步骤
  • 编写用户类

    public class User1 {
        private int id;
        private String name;
        private String password;
        
        public User1(int id, String name, String password) {
            this.id = id;
            this.name = name;
            this.password = password;
        }
    
        @Override
        public String toString() {
            return "User1{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }
    }
    
  • 编写applicationContext.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="user1" class="com.jxzz.User1">
            <constructor-arg name="id" value="1"></constructor-arg>
            <constructor-arg name="name" value="张三"></constructor-arg>
            <constructor-arg name="password" value="123"></constructor-arg>
        </bean>
    </beans>
    
  • 测试

    @Test
    public void TestUser1() {
    //     User1 user1 = new User1(1, "张三", "123");
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext-User.xml");
        User1 user1 = applicationContext.getBean("user1", User1.class);
        System.out.println(user1);
    
    }
    
5.1.2 <constructor-arg>元素属性
  • 一个<constructor-arg>元素表示构造方法的一个参数,且定义时不区分顺序。

  • 构造方法可以重载

在这里插入图片描述

  • 确定参数的:

    • index:通过参数的索引确定参数。

    • name:通过参数的名字确定参数。推荐

    • type:通过参数的类型确定参数

  • 给属性赋值的:

    • ref:给引用类型赋值

    • value:给基本类型赋值

5.2 属性setter方法注入(推荐)

8种基本类型

String类型

集合类型:数组、List、Set、Map、ProPerties

用户自定义类型

5.2.1 JDK内置类型开发步骤
  • 编写用户类

    @Data
    @NoArgsConstructor
    public class User2 {
        private int id;
        private String name;
        private String password;
    
        private String[] emails;
    
        private Set<String> tels;
    
        private List<String> addresses;
    
        private Map<String,String> qqs;
    
        private Properties pros;
    }
    
  • 编写applicationContext.xml配置文件

    <bean id="user2" class="com.jxzz.User2">
        <property name="id" value="2"></property>
        <property name="name" value="李四"></property>
        <property name="password" value="456"></property>
    
        <property name="emails">
            <list>
                <value>lisi@qq.com</value>
                <value>zhangsan@qq.com</value>
                <value>wanger@qq.com</value>
            </list>
        </property>
    
        <property name="addresses">
            <list>
                <value>jxzz</value>
                <value>nanchang</value>
                <value>jiujiang</value>
                <value>ganzhou</value>
            </list>
        </property>
    
        <property name="tels">
            <set>
                <value>12345678900</value>
                <value>12345678901</value>
                <value>12345678902</value>
                <value>12345678903</value>
                <value>12345678903</value>
            </set>
        </property>
    
        <property name="qqs">
            <map>
                <entry>
                    <key><value>lisi</value></key>
                    <value>6666666</value>
                </entry>
                <entry>
                    <key><value>zhangsan</value></key>
                    <value>7777777</value>
                </entry>
                <entry>
                    <key><value>wanger</value></key>
                    <value>8888888</value>
                </entry>
            </map>
        </property>
        <property name="pros">
            <props>
                <prop key="key1">value1</prop>
                <prop key="key2">value2</prop>
            </props>
        </property>
    </bean>
    
  • 测试

    @Test
    public void TestUser2() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext-User.xml");
        User2 user2 = applicationContext.getBean("user2", User2.class);
    
    //      System.out.println(user2);
    
        // 测试8种基本类型+String类型
        System.out.println("id=" + user2.getId());
        System.out.println("name=" + user2.getName());
        System.out.println("password=" + user2.getPassword());
    
        //测试数组类型
        for (String email : user2.getEmails()) {
            System.out.println("email=" + email);
        }
    
        //测试List类型
        for (String address : user2.getAddresses()) {
            System.out.println("address=" + address);
        }
    
        //测试Set类型
        for (String tel : user2.getTels()) {
            System.out.println("tel=" + tel);
        }
    
        //测试Map类型
        Map<String, String> qqs = user2.getQqs();
        for (String key : qqs.keySet()) {
            System.out.println("key=" + key + ", value=" + qqs.get(key));
        }
    
        //测试ProPerties类型
        Properties pros = user2.getPros();
        System.out.println(pros.getProperty("key1"));
        System.out.println(pros.getProperty("key2"));
    }
    
5.2.2 用户自定义类型开发步骤
  • 编写Mapper层

    UserMapper接口

    public interface UserMapper {
        public boolean login(String name, String password);
    }
    

    UserMapper接口实现类

    public class UserMapperImpl implements UserMapper {
    
        @Override
        public boolean login(String name, String password) {
            if (name.equals("张三") && password.equals("123")) {
                return true;
            }
            return false;
        }
    }
    
  • 编写Server层

    UserService接口

    public interface UserService {
        public boolean login(String name, String password);
    }
    

    UserService接口实现类

    public class UserServiceImpl implements UserService {
        UserMapper userMapper;
        public void setUserMapper(UserMapper userMapper) {
            this.userMapper = userMapper;
        }
        @Override
        public boolean login(String name, String password) {
            return userMapper.login(name, password);
        }
    }
    
  • 编写applicationContext.xml配置文件

    <!--<bean id="userService" class="com.jxzz.service.impl.UserServiceImpl">
        <property name="userMapper">
            <bean class="com.jxzz.mapper.impl.UserMapperImpl"></bean>
        </property>
    </bean>-->
    
    <bean id="userMapper" class="com.jxzz.mapper.impl.UserMapperImpl"></bean>
    <bean id="userService" class="com.jxzz.service.impl.UserServiceImpl">
        <property name="userMapper" ref="userMapper"></property>
    </bean>
    

    name属性的值可以通过ref属性或者value属性指定。当使用ref属性时,表示对Spring IoC容器中某个Bean实例的引用。这里引用了前一个<bean>元素中创建的UserMapperImpl类的实例userMapper,并将该实例赋值给UserServiceImpl类型中userMapper属性,从而实现了依赖关系的注入。

  • 编写测试类

    @Test
    public void TestSpring() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
        UserService userService = applicationContext.getBean("userService", UserService.class);
        boolean flag = userService.login("张三", "123");
        if (flag) {
            System.out.println("登陆成功");
        } else {
            System.out.println("登陆失败");
        }
    
    }
    

参考

  1. 教材:《Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)(第2版)》
  2. https://www.bilibili.com/video/BV185411477k/?spm_id_from=333.999.0.0&vd_source=c68309cbc3b530cccc4946c705035b62
  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大杯七分糖.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值