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

SSM框架之Spring——Spirng简介和配置

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

SSM框架之Spring——Spirng简介和配置

目录

一、Spring简介

1.1Spring的优点

1.2Spring体系结构

二、Spring快速入门

2.1Spring程序开发步骤

2.2Spring快速入门

2.2.1创建Maven项目并导入Spring包

2.2.2编写Dao接口和实现类

2.2.3创建Spring核心配置文件并配置DaoImpl

2.2.4获取Bean实例

三、Spring配置文件

3.1Bean标签基本配置

3.2Bean标签范围配置

3.3Bean生命周期配置

 3.4Bean实例化的三种方式

3.5Bean的依赖注入

3.5.1Set方法实现依赖注入

3.5.2构造方法实现依赖注入

3.5.3Bean的依赖注入的数据类型

3.6引入其他配置文件

四、Spring相关API

4.1ApplicationContext继承体系

4.2ApplicationContext的实现类

4.3getBean()方法使用


一、Spring简介

Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核。

提供了展现层 SpringMVC 和持久层 Spring JDBCTemplate 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE 企业应用开源框架。

1.1Spring的优点

Spring框架具有以下几个优势:

1、方便解耦,简化开发

通过 Spring 提供的 IoC 容器,可以将对象间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度耦合。(简单来说就是通过IoC统一创建对象)

用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

2、支持AOP编程

通过 Spring的 AOP 功能,方便进行面向切面编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松实现。

3、支持声明式事务

可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务管理,提高开发效率和质量。

4、方便程序的测试

可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。

5、方便继承各种优秀框架

Spring对各种优秀框架(Struts、Hibernate、Mybatis、Hessian、Quartz等)的支持

6、降低JavaEE API的使用难度

Spring对 JavaEE API(如 JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的使用难度大为降低。

7、Java源码是经典学习范例

Spring的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对Java 设计模式灵活运用以及对 Java技术的高深造诣。它的源代码无意是 Java 技术的最佳实践的范例。
 

1.2Spring体系结构

Spring的体系结构可以用下图表示:

 我们在学习过程中是从下往上学习,先学底层,然后是上层应用。所以我们先要学习核心容器Core Container。

二、Spring快速入门

2.1Spring程序开发步骤

传统的项目开发是先写Dao层的方法,然后在业务逻辑层Service里创建Dao对象,调用相关方法。

UserDao userDao = new UserDaoImpl();

但是Spring将对象的创建权限放在了框架内,如果想要获得对象,不用自己new,其步骤是:

  1. 实现Dao层的对象中的具体方法
  2. 在xml配置文件中把Dao对象关联到一个id标识上
  3. Spring读取xml配置文件,根据id标识获得Bean全限定名称
  4. Spring通过反射机制创建对象,然后将对象返回

 从上图可知,Spring开发的基本步骤如下:

  1. 导入Spring开发的基本包坐标
  2. 编写 Dao 接口和实现类
  3. 创建 Spring 核心配置文件
  4. 在 Spring 配置文件中配置 UserDaoImpl
  5. 使用 Spring 的 API 获得 Bean 实例

2.2Spring快速入门

2.2.1创建Maven项目并导入Spring包

我们首先创建一个Spring文件夹,用IDEA打开该文件夹,打开后右键Spring新建一个Module,

左边选择maven项目,不点击使用模板创建,直接点击next,设置好公司和项目名,

 然后后面直接点击next和finish创建好项目。现在创建的项目没有webapp,我们要进入项目设置Project Structure,设置SDK的一些参数,

 然后我们左边选择Facets项,点击+号,找到Web点击,选择spring_ioc进行添加,

 然后修改web模块的路径,

然后我们在pom.xml中导入spring框架用的jar包,


    
        org.springframework
        spring-context
        5.0.5.RELEASE
    

至此项目创建完成。

2.2.2编写Dao接口和实现类

我们创建一个Dao的接口和简单实现类,

interface UserDao {
    public void save();
}

public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("saving.........");
    }
}

2.2.3创建Spring核心配置文件并配置DaoImpl

我们在srcmainresources目录下创建一个xml文件applicationContext.xml,

 我们在xml中配置dao的实现类id,



    

2.2.4获取Bean实例

我们新建一个Demo类,用来获取UserDao对象,

package Demo;

import Dao.UserDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserDaoDemo {
    public static void main(String[] args) {
        ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");//获取ApplicationContext对象
        UserDao userDao = (UserDao) app.getBean("userDao");//获取UserDao的实例化对象
        userDao.save();
    }
}

运行结果:

三、Spring配置文件

3.1Bean标签基本配置

我们可以通过反射来获取对象,而反射是通过类的无参构造来获取对象,所以我们实现的类必须要存在无参构造。

基本属性包括:

  • id:Bean实例在Spring容器中的唯一标识
  • class:Bean的全限定名称

3.2Bean标签范围配置

我们还可以通过scope属性配置bean对象的作用范围:

取值范围说明
singleton默认值,单例的
prototype多例的
requestWEB项目中,Spring创建一个Bean对象,并将对象存储到request域中
sessionWEB项目中,Spring创建一个Bean对象,并将对象存储到session域中
global session

WEB项目中,应用在Portlet环境

如果没有Portlet环境那么globalSession相当于session

我们将scope分别设置为singleton和prototype,查看得到的两个对象地址是否相同,

public void test1(){
    ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");//获取ApplicationContext对象
    UserDao userDao1 = (UserDao) app.getBean("userDao");//获取UserDao的实例化对象
    UserDao userDao2 = (UserDao) app.getBean("userDao");//获取UserDao的实例化对象
    System.out.println(userDao1==userDao2);//查看两个对象是否为同一个地址,即是否为单例模式
}

下图左边是singleton的输出,右边是prototype的输出, 

我们可以得到以下结论:

  • 当scope的取值为singleton时:
    • Bean的实例化个数为1个
    • Bean的实例化时机为:当Spring核心配置文件加载时,就实例化了配置的Bean对象
    • Bean的生命周期:
      • 对象创建:当应用加载,创建容器时,对象就被创建了
      • 对象运行:只要容器在,对象就一直存活
      • 对象销毁:当应用卸载,销毁容器时,对象就被销毁了
  • 当scope的取值为prototype时:
    • Bean的实例化个数为多个
    • Bean的实例化时机为:当调用getBean()方法时实例化Bean
    • Bean的生命周期:
      • 对象创建:当使用对象时,创建新的对象实例
      • 对象运行:只要对象在使用中,就一直存活
      • 对象销毁:当对象长时间不用时,被Java的垃圾回收器回收

3.3Bean生命周期配置

我们可以指定Bean对象的初始化和销毁方法,

  • init-method:指定类中的初始化名称
  • destory-method:指定类中的销毁方法名称

我们在UserDaoImpl对象中定义初始化和销毁的方法:

public void init(){ System.out.println("UserDaoImpl对象初始化"); }
public void destory(){ System.out.println("UserDaoImpl对象销毁"); }

然后在applicationContext.xml中配置好对应关系:

public void test2(){
    ClassPathXmlApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");//获取ApplicationContext对象
    UserDao userDao = (UserDao) app.getBean("userDao");//获取UserDao的实例化对象
    app.close();//关闭容器对象,此时会执行对象中销毁的方法
}

结果如下:

 3.4Bean实例化的三种方式
  • 无参构造方法实例化:默认的方法(重要)
  • 工厂静态方法实例化
  • 工厂实例方法实例化

这里我们演示一下后面两种方法,首先我们要新建一个工厂类StaticFactory,里面定义一个静态方法获取UserDaoImpl对象,

public class StaticFactory {
    public static UserDao getUserDao(){
        return new UserDaoImpl();
    }
}

然后我们修改一下Spring的配置文件,告诉Spring我们要走工厂静态方法实例化对象,

后面就和无参构造的方法一样,通过应用容器中查找id获取Bean对象。

接下来我们看看工厂实例方法如何实例化,还是新建一个工厂类DynamicFactory,定义一个非静态方法,获取UserDaoImpl对象,

public class DynamicFactory {
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}

修改配置文件,


同样地利用id获取Bean对象。

3.5Bean的依赖注入

假设我们现在要在Service类中调用dao层的方法,我们同样要写一个UserService的接口和UserServiceImpl的实现类,在UserServiceImpl中调用dao层的方法。

package Service;

import Dao.UserDao;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceImpl implements UserService{
    public void save() {
        ClassPathXmlApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");//获取ApplicationContext对象
        UserDao userDao = (UserDao) app.getBean("userDao");//获取UserDao的实例化对象
        userDao.save();//调用dao层的方法
    }
}

那我们如何创建UserService类呢,我们同样可以在Spring的配置文件中给UserService类配置id。


然后同样通过id获取Bean对象,

package Demo;

import Service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceDemo {
    public static void main(String[] args) {
        ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");//获取应用
        UserService userService = (UserService) app.getBean("userService");//获取UserService对象
        userService.save();//调用方法
    }
}

启动可以正常运行。但是我们发现UserService和UserDao对象都封装到了Spring容器中。

程序调用时,首先为了获取UserSerice对象,根据id找到UserService对象,但是其中save方法中用到了UserDao对象,程序又去找Spring要UserDao对象,找到了后将UserDao对象返回给UserService进行使用。这样无疑是比较繁琐的,实现一个方法找Spring容器要了两次对象。

 所以我们希望的是在Spring容器内部,将UserDao就设导入给UserService对象(可以通过构造方法或者set方法),

这里就可以引入我们的依赖注入的概念,它是 Spring 框架核心 IOC 的具体实现。

在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。

那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。

3.5.1Set方法实现依赖注入

我们先用set方法将UserDao导入给UserService对象,完成依赖注入,

package Service;
import Dao.UserDao;

public class UserServiceImpl implements UserService{
    private UserDao userDao;//定义一个私有UserDao对象

    public void setUserDao(UserDao userDao) {//通过set方法对该对象进行赋值
        this.userDao = userDao;
    }

    public void save() {
        userDao.save();//调用dao层的方法
    }
}

然后在Spring配置文件中对set方法进行配置,将UserDao设置为传入的参数(注意这里property中的name属性填的是set方法后面的字符串,并且将第一个字符改为小写,即serUserDao->userDao)



    

我们还可以引入命名空间P,直接在bean标签内设置,

xmlns:p="http://www.springframework.org/schema/p"


3.5.2构造方法实现依赖注入

首先我们在UserServiceImpl类中添加一个有参构造函数,

package Service;
import Dao.UserDao;

public class UserServiceImpl implements UserService{
    private UserDao userDao;//定义一个私有UserDao对象

    public UserServiceImpl(UserDao userDao) {
        this.userDao=userDao;//通过有参构造进行赋值
    }

    public void save() {
        userDao.save();//调用dao层的方法
    }
}

同样我们对Spring配置文件进行配置,设定构造方法传入的参数值,



    

3.5.3Bean的依赖注入的数据类型

上述操作都是注入了引用Bean,除了对象的引用可以注入,普通数据类型、集合等都可以在容器中进行注入。主要包括:

  • 普通数据类型
  • 引用数据类型
  • 集合数据类型

接下来我们看看普通数据类型和集合数据类型如何进行注入,同样地还是使用set和构造的方法。


首先看看普通数据类型,我们在UserDaoImpl中写入两个普通数据类型数据,生成set方法,并在save方法中对两个数据进行打印。

package Dao;

public class UserDaoImpl implements UserDao {
    private String username;
    private int age;

    public void setUsername(String username) {
        this.username = username;
    }

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

    public void save() {
        System.out.println(username+"="+age);//打印用户名和年龄
        System.out.println("saving.........");
    }
}

我们在Spring配置文件中对这两个数据进行赋值,


    
    

然后调用UserDaoImpl的save方法,输出结果为:


 然后是集合数据类型,我们在UserDaoImpl中创建几个集合数据,设置好set方法,

import Domain.User;

import java.util.List;
import java.util.Map;
import java.util.Properties;

public class UserDaoImpl implements UserDao {
    private List strList;
    private Map userMap;
    private Properties properties;

    public void setStrList(List strList) {
        this.strList = strList;
    }

    public void setUserMap(Map userMap) {
        this.userMap = userMap;
    }

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

    public void save() {
        System.out.println(strList);
        System.out.println(userMap);
        System.out.println(properties);
        System.out.println("saving.........");
    }
}

我们同样要在Spring配置文件中对这些集合进行赋值,


    
        
            aaa
            bbb
            ccc
        
    
    
        
            
            
        
    
    
        
            wuhan
            cs
        
    



    
    


    
    

然后调用UserDaoImpl的save方法对这些集合进行打印,

3.6引入其他配置文件

实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将部分配置拆解到其他配置文件中,而在Spring主配置文件通过import标签进行加载。

我们将user的对象配置到applicationContext-user.xml中,


    
    


    
    

然后在主配置文件中导入,

这样就做到了分模块开发,主配置文件就比较精简。
 

四、Spring相关API

4.1ApplicationContext继承体系

ApplicationContext:接口类型,代表应用上下文,可以通过其实例获得 Spring 容器中的 Bean 对象

 紫色的为接口,浅绿色的为抽象类,深绿色的为实现类,所以我们一般创建实现类对象。

4.2ApplicationContext的实现类

1、ClassPathXmlApplicationContext

它是从类的根路径下(相对路径)加载配置文件(推荐使用)

ClassPathXmlApplicationContext app=new ClassPathXmlApplicationContext("XXXX.xml");
app.getBean("");//输入id标识获取Bean对象

2、FileSystemXmlApplicationContext

它是从磁盘路径上(绝对路径)加载配置文件,配置文件可以在磁盘的任意位置。

FileSystemXmlApplicationContext app=new FileSystemXmlApplicationContext("");//输入xml文件的磁盘地址即绝对路径
app.getBean("");//输入id标识获取Bean对象

3、AnnotationConfigApplicationContext

当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。

4.3getBean()方法使用

getBean有两种方式获取Bean对象,一个是传入id标识,还有一种是传入字节码对象,

public Object getBean(String name) throws BeansException {
    this.assertBeanFactoryActive();
    return this.getBeanFactory().getBean(name);
}

public  T getBean(Class requiredType) throws BeansException {
    this.assertBeanFactoryActive();
    return this.getBeanFactory().getBean(requiredType);
}

前面我们使用的都是id标识的方法,我们看看如何传入字节码对象来获取Bean对象,

public void test4(){
    ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");//获取ApplicationContext对象
    UserDao userDao = app.getBean(UserDao.class);//获取UserDao的实例化对象
    userDao.save();
}

两种方法都可以获取到Bean对象,但是两者主要有以下几点不同:

  • id标识:可以区分同类的多个对象,即可以在配置文件中创建该类的多个对象,设置不同的属性,分别指定不同标识
  • 字节码:不能区分多个对象,如果只需要类的一个对象时可以使用该方法

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/489130.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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