栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

14.Java- Spring

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

14.Java- Spring

一、Spring 1. 简介
  • Spring:春天 ------->给软件行业带来了春天
  • 2002,首次推出了Spring框架的雏形:interface21框架
  • Spring框架即是以interface21框架为基础经过重新设计,并不断丰富其内涵,于2004年3月24日发布了1.0正式版
  • Rod Johnson ,Spring framework创始人,著名作者。很难想象Rod Johnson的学历,真的让好多人大吃一惊,他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。
  • Spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架!
  • SSH :Struct2 + Spring + Hibernate
  • SSM:SpringMVC + SPring +Mybatis(现在学的)
  • 官网:https://spring.io/
  • 官方下载地址:http://repo.spring.io/release/org/springframework/spring
  • GitHub:https://github.com/spring-projects/spring-framework
  • Spring核心技术地址:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-annotation-config
  • mvn-spring依赖地址:https://mvnrepository.com/artifact/org.springframework/spring-webmvc

    org.springframework
    spring-webmvc
    5.3.12


  • mvn-spring-jdbc依赖地址:https://mvnrepository.com/artifact/org.springframework/spring-jdbc

    org.springframework
    spring-jdbc
    5.3.12


2. 优点
  • Spring是一个开源的免费的框架(容器)!
  • Spring是一个轻量级的,非入侵式的框架
  • 控制反转(IOC),面向切面编程(AOP)
  • 支持事务的处理,对框架整合的支持!

总结: Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架!

3. 组成

Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式 .

组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:

核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。

Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。

Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理任何支持 AOP的对象。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中。

Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

4. 扩展

在spring的官网有这个介绍:现代化的Java开发,说白就是基于Spring的开发

Spring Boot

  • 一个快速开发的脚手架
  • 基于SpringBoot可以快速开发的单个微服务
  • 预定大于配置!

Spring Cloud

  • Spring Cloud 是基于SpringBoot实现的。

因为现在大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提,需要完全掌握Spring及SpringMvc!承上启下的作用!
弊端:发展了太久之后,违背了原来的理念!配置十分繁琐,人称:“配置地狱!”

二、IOC 1. 搭建环境 1. 创建项目 1. 创建spring-study空项目

创建一个spring-study空项目,删除src

2. 导入spring-webmvc依赖

spring-study父类的pom.xml 里面导入spring-webmvc依赖



    4.0.0

    com.xxx
    spring-study
    1.0-SNAPSHOT

    
        17
        17
    

    
    
        
        
            org.springframework
            spring-webmvc
            5.3.12
        
    


2. 创建空模块

创建空模块spring-01-ioc1

2. 分析实现 1. 原来的方式

1.UserDao接口

地址:src/main/java/com/xxx/dao/UserDao.java
代码:

package com.xxx.dao;

public interface UserDao {
    void getUser();
}

2.UserDao的实现类

地址:src/main/java/com/xxx/dao/UserDaoImpl.java
代码:

package com.xxx.dao;

public class UserDaoImpl  implements UserDao{
    public void getUser(){
        System.out.println("获取用户的数据");
    }
}

3.UserService接口

地址:src/main/java/com/xxx/service/UserService.java
代码:

package com.xxx.service;

public interface UserService {
    void getUser();
}

4.UserService实现类

地址:src/main/java/com/xxx/service/UserServiceImpl.java
代码:

package com.xxx.service;

import com.xxx.dao.UserDao;
import com.xxx.dao.UserDaoImpl;

public class UserServiceImpl implements UserService {

 private UserDao userDao = new UserDaoImpl();

    public void getUser() {
        userDao.getUser();

    }
}


5. 测试
import com.xxx.service.UserServiceImpl;

public class MyTest {

    public static void main(String[] args) {
        //用户实际调用的是业务层,dao层他们不需要接触
        UserServiceImpl service = new UserServiceImpl();
        service.getUser();
    }
}

结果:

获取用户的数据

进程已结束,退出代码为 0
  • 这是我们原来的方式 , 开始大家也都是这么去写的对吧 . 那我们现在修改一下 .

  • 把Userdao的实现类增加一个 .

6.添加Userdao实现类

地址:src/main/java/com/xxx/dao/UserDaoMysqlImpl.java
代码:

package com.xxx.dao;

public class UserDaoMysqlImpl implements UserDao{
    public void getUser(){
        System.out.println("获取mysql的数据");
    }
}

  • 紧接着我们要去使用MySql的话 , 我们就需要去service实现类里面修改对应的实现
  • 修改地址:src/main/java/com/xxx/service/UserServiceImpl.java
package com.xxx.service;

import com.xxx.dao.UserDao;
import com.xxx.dao.UserDaoImpl;
import com.xxx.dao.UserDaoMysqlImpl;

public class UserServiceImpl implements UserService {

 private UserDao userDao = new UserDaoMysqlImpl();


    public void getUser() {
        userDao.getUser();

    }
}

  • 测试及结果

  • 以此类推,假设我们的这种需求非常大 , 这种方式就根本不适用了, 甚至反人类对吧 , 每次变动 , 都需要修改大量代码 . 这种设计的耦合性太高了, 牵一发而动全身 .

  • 那我们如何去解决呢 ?

  • 我们可以在需要用到他的地方 , 不去实现它 , 而是留出一个接口 , 利用set , 我们去代码里修改下 .

2. 将UserService使用Set接口实现 1. 修改UserService实现类

地址:src/main/java/com/xxx/service/UserServiceImpl.java
代码:

package com.xxx.service;

import com.xxx.dao.UserDao;
import com.xxx.dao.UserDaoImpl;
import com.xxx.dao.UserDaoMysqlImpl;

public class UserServiceImpl implements UserService {

 //private UserDao userDao = new UserDaoMysqlImpl();
  private UserDao userDao;
    //利用set进行动态实现值得注入
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void getUser() {
        userDao.getUser();

    }
}

2. 测试

代码:

import com.xxx.dao.UserDaoImpl;
import com.xxx.dao.UserDaoMysqlImpl;
import com.xxx.dao.UserDaoOracleImpl;
import com.xxx.service.UserService;
import com.xxx.service.UserServiceImpl;

public class MyTest {

    public static void main(String[] args) {
        //用户实际调用的是业务层,dao层他们不需要接触
        UserServiceImpl service = new UserServiceImpl();
        service.setUserDao( new UserDaoMysqlImpl() );
        service.getUser();
        //那我们现在又想用Oracle去实现呢
        service.setUserDao( new UserDaoOracleImpl() );
        service.getUser();
    }
}

结果:

获取mysql的数据
获取Oracle的数据

进程已结束,退出代码为 0
  • 之前,程序通过new主动创建对象!控制权在程序猿手上
  • 使用set注入后,程序不再具有主动性,而是变成了被动的接受对象!
  • 这种思想,从本质上解决了问题,程序员不用再去管理对象的创建了,降低了耦合性!
3. IOC本质

控制反转IOC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IOC的一种方法, 也有人认为DI只是IOC的另一种说法。没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓的控制反转就是:获得依赖的方式反转了。


IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。

Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

4.HelloSpring

新建一个空模块spring-02-hellospring

1. 编写一个实体类

地址:src/main/java/com/hello/pojo/Hello.java
代码:

package com.hello.pojo;

public class Hello {
    private  String str;

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + ''' +
                '}';
    }
}

2. 编写我们的spring文件 , 这里我们命名为beans.xml

地址:src/main/resources/beans.xml
代码:




    
    
        
    


3.测试
import com.hello.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        //获取spring上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //我们的对象现在都在spring中管理了,我们要使用,直接去里面取出来就可以
        Hello hello = (Hello) context.getBean("hello");
        System.out.println(hello.toString());

    }
}

结果:

Hello{str='Spring'}

进程已结束,退出代码为 0

会发现,已经不需要手动new对象,对象是在xml文件中配置。或者通俗来讲,不需要改底层代码,而xml文件不算底层代码。

控制反转

  • 控制: 谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的
  • 反转: 程序本身不创建对象,而变成被动的接收对象。
  • 依赖注入: 就是利用set方法来进行注入的
  • IOC是一种编程思想,由主动的编程变为被动的接收,所谓的IOC,即对象由Spring来创建,管理,装配
5. 修改spring-01-ioc1的实现方式 1. 添加beans.xml

路径:src/main/resources/beans.xml
代码:




    
    

    
         
        
    


2. 测试

代码:

import com.xxx.service.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTestBean {
    public static void main(String[] args) {
        //获取ApplicationContext;拿到spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //需要什么就直接get
        UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean("UserServiceImpl");
        userServiceImpl.getUser();

    }
}

结果:

获取mysql的数据

进程已结束,退出代码为 0

OK , 到了现在 , 我们彻底不用再程序中去改动了 , 要实现不同的操作 , 只需要在xml配置文件中进行修改 , 所谓的IoC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配 !

6. IOC创建对象的方式

新建一个空模块spring-03-ioc2

  1. 使用无参构造创建对象,默认
  2. 假设使用有参构造创建对象
1. 使用无参构造创建对象 1. 新建实体类

地址:src/main/java/com/two/pojo/User.java
代码:

package com.two.pojo;

public class User {
    private String name;
    public User(){
        System.out.println("USER 的无参构造");
    }

    public String getName() {
        return name;
    }

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

    public void show() {
        System.out.println("name = " + name);
    }
}

2. 创建beans.xml

地址:src/main/resources/beans.xml
代码:



    
        
    



3. 测试
import com.two.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        User user = (User) context.getBean("user");
        user.show();
    }
}

结果:

USER 的无参构造
name = jva

进程已结束,退出代码为 0
2. 使用有参构造创建对象 1. 下标赋值 Constructor argument index


    
   
    
    
        
     
 

2. 变量类型赋值 Constructor argument type matching 不建议使用
  
    
        
    
3.变量名称赋值 Constructor argument name
  
    
        
    

总结:在配置文件加载的时候,容器中管理的对象就已经初始化了

三、Spring的基础配置 1. 别名 1. 配置别名
  
    
        
    
    
    
2. 使用别名
import com.two.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        User user = (User) context.getBean("userNew");
        user.show();
    }
}

运行结果

name = ss

进程已结束,退出代码为 0
2. Bean的配置 1. 新建实体类

地址:src/main/java/com/two/pojo/UserT.java
代码:

package com.two.pojo;

public class UserT {
    private String name;

    public UserT() {
        System.out.println("UserT 的无参构造");
    }

    public UserT(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    public void show() {
        System.out.println("name = " + name);
    }
}

2.写beans.xml配置

地址:src/main/resources/beans.xml
代码:




    
    
        
    
    
    

    
    
        
    


3.测试
import com.two.pojo.User;
import com.two.pojo.UserT;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserT user = (UserT) context.getBean("u2");
        user.show();
    }
}

结果:

UserT 的无参构造
name = 黑心白莲

进程已结束,退出代码为 0
3.import

这个import。一般用于团队开发使用,它可以将多个配置文件,导入合并为一个。
假设,现在项目中有多个人开发,这三个人负责不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的!
张三
李四
王五
applicationContext.xml

1. 导入代码

地址:src/main/resources/applicationContext.xml
代码:



      


使用的时候,直接使用总的配置就可以了。

四、DI依赖注入 1.构造器注入

前面已经介绍过,参考 2.6 IOC创建对象的方式

2.Set方式注入【重点】

依赖注入:Set注入
依赖:bean对象的创建依赖于容器!
注入:bean对象中的所有属性,由容器来注入!

1. 环境搭建 1. 实体类创建 1. Address创建

复杂类型
地址:src/main/java/com/di/pojo/Address.java
代码:

package com.di.pojo;

public class Address {
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

1. Student创建

真实测试对象
地址:src/main/java/com/di/pojo/Student.java
代码:

package com.di.pojo;

import java.util.*;

public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List hobbys;
    private Map card;
    private Set games;
    private String wife;
    private Properties info;

    public String getName() {
        return name;
    }

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

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public String[] getBooks() {
        return books;
    }

    public void setBooks(String[] books) {
        this.books = books;
    }

    public List getHobbys() {
        return hobbys;
    }

    public void setHobbys(List hobbys) {
        this.hobbys = hobbys;
    }

    public Map getCard() {
        return card;
    }

    public void setCard(Map card) {
        this.card = card;
    }

    public Set getGames() {
        return games;
    }

    public void setGames(Set games) {
        this.games = games;
    }

    public String getWife() {
        return wife;
    }

    public void setWife(String wife) {
        this.wife = wife;
    }

    public Properties getInfo() {
        return info;
    }

    public void setInfo(Properties info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + ''' +
                ", address=" + address.getAddress() +
                ", books=" + Arrays.toString(books) +
                ", hobbys=" + hobbys +
                ", card=" + card +
                ", games=" + games +
                ", wife='" + wife + ''' +
                ", info=" + info +
                '}';
    }
}

2. bean配置文件创建

beans.xml
地址:src/main/resources/beans.xml
代码:



   
       
   


3.测试类创建

地址:src/test/java/MyTest.java
代码:

import com.di.pojo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) context.getBean("student");
        System.out.println(student.getName());
    }
}

测试结果:

lili

进程已结束,退出代码为 0
2.完善注入信息

完善注入信息
代码:




    
    
        
    

    
        
        
        
        

        
        
            
                红楼梦
                西游记
                水浒传
                三国演义
            
        
        
        
            
                听歌
                看电影
                旅游
                睡觉
            
        
        
        
            
                
                
            
        
        
        
            
                LOL
                COC
                BOB
            
        
        
        
            
        
        
        
            
                2012456
                
                小明
            
        
    



测试:

import com.di.pojo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) context.getBean("student");
        System.out.println(student.toString());
        
    }
}

3.拓展方式注入 1. p命名注入

命名空间注入,可以直接注入属性的值。无需构造器

1. 新建实体类

User.java :【注意:这里没有有参构造器!】
地址:src/main/java/com/di/pojo/User.java
代码:

package com.di.pojo;

public class User {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }
}

2. 新建userbean.xml

引入p注入:xmlns:p="http://www.springframework.org/schema/p"
地址:src/main/resources/userbeans.xml
代码:




    
    




3. 测试

代码:test2

import com.di.pojo.Student;
import com.di.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) context.getBean("student");
        System.out.println(student.toString());
        
    }
    @Test
    public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        //指定class,就不用转换了
        User user = context.getBean("user", User.class);
        System.out.println(user);


    }
}

结果:

User{name='zhangsan', age=18}

进程已结束,退出代码为 0
2. c命名注入

通过构造器注入,必须有构造器

1. 修改实体类

User.java :通过构造器注入,必须有构造器
地址:src/main/java/com/di/pojo/User.java
代码:

package com.di.pojo;

public class User {
    private String name;
    private int age;

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }


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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }
}

2.userbean.xml添加

添加c注入代码:xmlns:c="http://www.springframework.org/schema/c"
地址:src/main/resources/userbeans.xml
代码:




    
    
    
    


3.测试

代码:test3

import com.di.pojo.Student;
import com.di.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) context.getBean("student");
        System.out.println(student.toString());
        
    }
    @Test
    public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        User user = context.getBean("user", User.class);
        System.out.println(user);


    }
    @Test
    public void test3(){
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        User user = context.getBean("user2", User.class);
        System.out.println(user);


    }
}

结果:

User{name='kk', age=18}

进程已结束,退出代码为 0
4.bean的作用域 五、Bean的自动装配 六、代理模式 七、AOP 八、整合Mybatis 九、Spring配置声明事务注入
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/348976.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号