当前位置 博文首页 > 一只胡说八道的猴子:五万字长文带你学会Spring

    一只胡说八道的猴子:五万字长文带你学会Spring

    作者:一只胡说八道的猴子 时间:2021-02-01 00:21

    Sping

    在这里插入图片描述

    Spring概念介绍

    spring是啥呢,你在斗地主的时候把别人打爆了那叫spring,

    在这里插入图片描述

    你成功的追到了你爱慕已久的女神,人生中的春天来了,那也叫sping
    在这里插入图片描述
    在这里插入图片描述

    好了别看我老婆了,咱来讲讲啥是Spring

    Sping:Spring是分层的javaEE/SE应用full-stack轻量级开源框架,他以AOP( 面向切面编程 aspect oriented programming)和IOC(控制反转 invers of control)为内核,这个框架之所以叫spring是因为他给软件行业的发展带来的春天,看吧和你的春天一样,不过这个是程序员的春天,这个框架的到来极大的方便的程序的开发

    Spring 体系结构介绍

    Spring体系结构图

    在这里插入图片描述

    Spring四大模块简介

    Core核心模块。负责管理组件的Bean对象
    spring-beans-4.0.0.RELEASE.jar
    spring-context-4.0.0.RELEASE.jar
    spring-core-4.0.0.RELEASE.jar
    spring-expression-4.0.0.RELEASE.jar
    面向切面编程
    spring-aop-4.0.0.RELEASE.jar
    spring-aspects-4.0.0.RELEASE.jar
    数据库操作
    spring-jdbc-4.0.0.RELEASE.jar
    spring-orm-4.0.0.RELEASE.jar
    spring-oxm-4.0.0.RELEASE.jar
    spring-tx-4.0.0.RELEASE.jar
    spring-jms-4.0.0.RELEASE.jar
    Web模块
    spring-web-4.0.0.RELEASE.jar
    spring-webmvc-4.0.0.RELEASE.jar
    spring-websocket-4.0.0.RELEASE.jar
    spring-webmvc-portlet-4.0.0.RELEASE.jar

    Spring的优势

    以下优势我都将在下文一一介绍

    1. 方便解耦,简化开发
    2. AOP 编程的支持
    3. 声明式事务的支持
    4. 方便程序的测试
    5. 方便集成各种优秀框架
    6. 降低 JavaEE API 的使用难度
    7. Java 源码是经典学习范例

    下面我们来介绍介绍Spring的两个核心IOC与AOP

    IOC(控制反转 invers of control)

    基本概念

    IOC -Inversion of Control ,即控制反转,这不一种具体的技术,而是一种设计思想,以前我们的java开发都是自己的new一个对象,这样十分麻烦,而且每new一个对象,就会占用一个内存空间,消耗资源。而IOC技术就是为了解决这个问题,把,这个思想的本质就是将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
    你现在是不是还是一脸懵逼,下面我们再来理解理解两个思想,即
    1.谁控制谁控制了什么
    2.为何是反转,那方面反转了

    1.谁控制谁控制了什么

    传统JAVA SE 程序设计,是我们直接在对象内部通过new 来创建对象,也即程序主动的去创建依赖对象,而IOC有一个专门的控制容器来创建对象,即对象的管理权全交给了IOC容器,即由IOC控制对象,这里不仅仅是对象,还有一些外部资源的获取,比如文件等等

    2.为何是反转,那方面反转了

    在讲反转之前我们先来讲讲什么是正转,传统对象中是我们自己在对象中主动控制去获取依赖对象,这就是正转,而反转则是由IOC容器去控制依赖注入,因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

    IOC的优点以及他可以做什么

    IOC不是一种技术,只是一种思想,一个重要的面向对象编程设计的发则,它能指导我们如何设计出松耦合,更优良的程序,传统应用程序都是我们在类的内部主动的去创建依赖对象,导致 了类与类之间的高度融合,很难测试,有了IOC容器之后,把创建和查找依赖对象的控制器交给了容器,由容器进行注入组合对象,对象和对象之间的松散耦合的,这样方便测试也利于重复利用,使整个程序的体系结构变的十分灵活,其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。
    IOC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IOC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。

    在这里插入图片描述

    IOC和DI(控制反转和依赖注入)

    DI—Dependency Injection,即“依赖注入”:是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

    理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:

    谁依赖于谁:当然是应用程序依赖于IOC容器;
    为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;
    谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;

    ●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。

    IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。
    **
    怎么在spring中实现依赖注入我后面再来讲解,这里大家先理解理解这个概念
    **
    注:如果想要更加深入的了解IOC和DI,请参考大师级人物Martin Fowler的一篇经典文章《Inversion of Control Containers and the Dependency Injection pattern》,原文地址:http://www.martinfowler.com/articles/injection.html。

    AOP思想介绍(面向切面编程aspect oriented programming)

    AOP概念

    AOP为Aspect Oriented Programming 的缩写,意为面向切面编程,通过预处理和运行期动态代理的方式实现程序功能的统一和维护的一种技术
    AOP是OOP(Object Oriented Programmin 面向对象编程)的延续,是软件开发的一个热点,又是框架中的一个重要内容,是函数式编程的一种衍生范型,利用AOP可以对业务逻辑中的各个部分进行隔离,使业务逻辑之间的耦合度降低,提高程序的可重用性,同时提高了程序的开发效率

    一个案例带你理解切面

    在这里插入图片描述

    切面:
    把一块蛋糕切成两块,这个切口就是切面,;炒饭的时候,锅和锅铲就是切面;web层级设计中,web层->网关层->服务层->数据层,每一层之间也是一个切面。编程中,对与对象之间,方法与方法之间,模块与模块之间都是一个个切面。

    以一个银行案例为例:
    **
    如图银行的取款业务和查询余额业务有交叉的业务逻辑(所谓交叉业务逻辑是与主业务无关的代码,比如安全检查,事务,日志等等),这里指的是验证用户的业务。这会导致代码纠缠,交叉业务逻辑与主业务逻辑混合在一起,这会导致业务逻辑的混合不清,这时候就要用到AOP
    在这里插入图片描述

    使用AOP可以帮助我们简化代码,我们在写代码的时候可不写这个验证用户的业务,可以在另一个地方写好验证用户的代码,然后告诉Spring那几个地方需要这些代码,让Spring加过去即可,如果有多个控制流的话,会大大的减少时间,而AOP不会把代码加入到源文件中但是他会正确的影响最后的机器代码
    上面那个 验证用户 的方框,我们可以把它当成一块板子,在这块板子上插入一些控制流程,这块板子就可以当成是 AOP 中的一个切面。所以 AOP 的本质是在一系列的纵向的控制流程中,把那些相同的子流程提取成一个横向的面,把纵向流程画成一条直线,而 AOP 相当于把相同的地方连起来了(这幅图是真的形象,好好体会一下应该不难),这个验证用户的子流程 就成了一条直线,也可以理解成一个切面,这里只插了三个流程,如果其他流程也需要这个子流程,也可以插到其他地方去。
    在这里插入图片描述

    AOP的优势与作用
    **
    作用:在不修改源码的情况下对方法进行增强
    优势:提高代码的可复用性,提高开发效率,便于维护

    Spring中AOP思想的实现我在后面就有讲解,不在这里讲是因为讲Spring在AOP中的实现要有一定的基础,会的的同学可以点击链接跳转:链接

    构建一个简单的案例

    创建Spring工程的方法我放在附录2了:点击这里跳转

    在写Spring的案例之前我们再来理理使用Spring与不使用Spring的区别

    没有spring之前:

    在没有spring之前,一个对象调用另一个对象的方法,需要通过之间new一个对象的方式来实现,比如对象A调用对象BImp,需要在对象A内部new一个对象B,再来调用B的方法Methdo,其中BImp实现自接口B

    在使用了Spring之后:
    在有了Spring之后直接向Spring要就好了,不需要再自己来创建
    **
    在这里插入图片描述

    从这两个图就可以看出Spring 的一个优点,即实现了解耦操作,
    比如将来你想用另一个对象来代替Bimp,直接更改配置文件即可而不用修改文件源码,配置文件是不会被编译的,而且因为BImp实现了接口B,其他实现自接口B的类就可以替换BImp,继承也是一样的道理

    进入案例

    步骤
    1.导入相关的jar包
    2.编写Dao接口与实现类
    3.创建Spring核心配置文件
    4.在Spring配置文件中配置UserDaoImp
    5.使用Spring的API获取Bean实例
    **
    **
    1.导入相关的jar包

    <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.0.5.RELEASE</version>
            </dependency>
        </dependencies>
    

    2.编写Dao接口与实现类
    接口

    package com.pjh.Dao;
    
    public  interface  userDao {
        void save();
    }
    
    

    实现类

    package com.pjh.Dao.Imp;
    import com.pjh.Dao.userDao;
    public class userDaoImp implements userDao {
        public void save() {
            System.out.println("save.......");
        }
    }
    
    

    3.创建Spring核心配置文件
    **
    在这里插入图片描述

    4.在Spring配置文件中配置UserDaoImp

    <?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  />
    </beans>
    

    5.使用Spring的API获取Bean实例

    package com.pjh.Test;
    import com.pjh.Dao.userDao;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public class test {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationCotext.xml");
            userDao userDao =(com.pjh.Dao.userDao) classPathXmlApplicationContext.getBean("userDao");
            userDao.save();
        }
    }
    
    

    运行结果

    在这里插入图片描述

    Spring配置文件基本属性介绍(ID Class Scope)

    基本概述

    id
    Bean实例在Spring容器中的唯一标识,不允许重复

    class
    Bean的全限定名称,即这个类存在的路径

    scope:
    这个Bean对象的作用范围
    1.singleton:默认值,单例
    2.prototpye:多例的
    3.request: WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中 4.session:WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中 5.global session: WEB 项目中,应用在 Portlet 环境,如果没有Portlet境那 globalSession相当于 session

    singleton和prototype的区别

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

    证明步骤我放在附录2里了:点击这里跳转

    bean的初始化构造方法与消耗方法配置

    init-method:指定类中的初始化方法名称 ,即在构造方法执行完毕后自动执行的方法
    destroy-method:指定类中销毁方法名称 ,在对象销毁之前执行的方法

    applicationContesxt.xml中配置文件的配置
    **格式: **init-method="所指定的类中的初始化方法名"
    destroy-method="所指定的类中的销毁化方法名"

    <?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   scope="prototype" 
        init-method="initmethod" destroy-method="destroymethod"/>
    </beans>
    

    Bean实例化的三种方式

    1.无参构造方法实例化(重点掌握,使用最多)
    2.工厂静态方法实例化
    3.工厂动态方法实例化

    1.无参构造方法实例化(重点掌握,使用最多)

    即直接通过类的无参构造方法来创建对象

    applicationContext配置文件中所需的配置 ,默认使用无参构造的方式

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

    2.工厂静态方法实例化

    静态工厂类中的代码

    package com.pjh.Factory;
    import com.pjh.Dao.Imp.userDaoImp;
    import com.pjh.Dao.userDao;
    public class staticFactory {
        public static userDao getUserDao(){
            return  new userDaoImp();
        }
    }
    

    applicationContext中的代码

    <?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   factory-method="getUserDao"/>
    
    </beans>
    

    3.工厂动态方法实例化

    动态工厂类中的代码

    package com.pjh.Factory;
    import com.pjh.Dao.Imp.userDaoImp;
    import com.pjh.Dao.userDao;
    public class dynamicFactory {
        public userDao getUserDao(){
            return new userDaoImp();
        }
    }
    

    applicationContext中的配置文件代码

    <?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  ></bean>
    <bean  factory-bean="dynamicFactory" factory-method="getUserDao"/>
    </beans>
    

    以上三种只有着重掌握前面两种即可

    Spring中依赖注入的实现

    因为前面已经讲过什么是IOC(控制反转)和ID(依赖注入)了,这里就不在叙述了,如果不懂,可以点击链接到前面看看:链接

    注入对象

    Spring中依赖注入的实现:
    比如有两个类,类A和类B,类A中需要引用类B中的某个方法,故需要将类B注入到类A中,类A才可以调用类B中的方法。故因该将类A和类B都交给spring容器来创建Bean对象,再让spring容器将类B的bean对象注入到类A的bean对象内部。实现注入需要在类B中设置一个setB()的方法来实现注入。

    光说不练假把式

    下面来实现以下,这里以一个userDaoImp类的Bean注入userServiceImp类的Bea为例
    userDaoImp类继承自userDao类,userServiceImp类继承自userService类。这里对应接口的代码就不写了,直接写对应实现类的代码。

    userDaoImp类代码

    package com.pjh.Dao.Imp;
    import com.pjh.Dao.userDao;
    public class userDaoImp implements userDao {
        public userDaoImp(){
            System.out.println("这是无参构造..");
        }
        public void save() {
            System.out.println("save.......");
        }
        
    }
    
    

    **
    userService类代码
    **

    package com.pjh.Service.Imp;
    import com.pjh.Service.userService;
    public class userServiceImp implements userService {
        private com.pjh.Dao.userDao userDao;
        public void setUserDao(com.pjh.Dao.userDao userDao) {
            this.userDao = userDao;
        }
        public void save(){
            userDao.save();
        }
    }
    
    

    applicationContext配置文件代码

    方法1普通注入方式

    <?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  />
        <bean  >
            <property name="userDao" ref="userDao"/>
        </bean>
    </beans>
    

    方法2使用P命名空间简化注入

    1.引入p命名空间 :
    **

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

    2.修改注入方式
    **

    <bean   p:userDao-ref="userDao"/>
    
    <?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  />
        <bean   p:userDao-ref="userDao"/>
    </beans>
    

    **
    使用有参构造的方式注入UserDaoImp对象
    1.userServiceImp中需要增加有参构造方法

    package com.pjh.Service.Imp;
    import com.pjh.Dao.userDao;
    import com.pjh.Service.userService;
    public class userServiceImp implements userService {
        private com.pjh.Dao.userDao userDao;
        public userServiceImp(com.pjh.Dao.userDao userDao) {
            this.userDao = userDao;
        }
        public void save(){
            userDao.save();
        }
    }
    
    

    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"
           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  />
       <bean  >
           <constructor-arg name="userDao" ref="userDao"/>
       </bean>
    
    </beans>
    

    测试类
    **

    package com.pjh.Test;
    
    import com.pjh.Service.userService;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class test3 {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationCotext.xml");
            userService userService = (com.pjh.Service.userService)app.getBean("userService");
            userService.save();
        }
    }
    
    

    控制台输出

    在这里插入图片描述

    注入普通数据类型

    比如一个user类要注入一个age和一个name

    user类代码

    package com.pjh.Dao;
    
    public class user {
        private int age;
        private  String name;
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        
        
    }
    
    

    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"
           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  >
        <property name="age" value="18"/>
        <property name="name" value="zhangsan"/>
     </bean>
    </beans>
    

    **
    这下面的我就不演示了操作和上面一样

    集合数据类型(List)的注入

    **集合数据类型( Map<String,User> )的注入 **

    集合数据类型(Properties)的注入


    配置多个Spring配置文件解决项目庞大的问题

    在实际的开发中Spring的配置内容非常多,这导致Spring配置很繁杂且体积很大,所以,可以将一个项目拆分为若干个模块,将不同模块的配置文件写到不同的配置文件中,在一个主Spring配置文件中通过import标签进行加载

    如图有两个配置文件,applicationContext为主配置文件,application-product是拆分出的配置文件,被applicationContext配置文件使用import引入
    在这里插入图片描述

    applicationContext中的配置文件代码

    <?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">
        <import resource="application-product.xml"/>
    </beans>
    

    **
    application-product.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  />
        <bean  >
            <constructor-arg name="userDao" ref="userDao"/>
        </bean>
    </beans>
    

    测试类测试
    **

    package com.pjh.Test;
    
    import com.pjh.Service.userService;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class test3 {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationCotext.xml");
            userService userService = (com.pjh.Service.userService)app.getBean("userService");
            userService.save();
        }
    }
    
    

    控制台输出

    在这里插入图片描述

    说明配置文件配置成功,成功注入并在bean容器中获取对象

    Spring相应的API

    applicationContext:

    接口类型,代表应用上下文,可以通过其实例获得 Spring 容器中的 Bean 对象 ApplicationContext的实现类
    1)ClassPathXmlApplicationContext
    它是从类的根路径下加载配置文件 推荐使用这种
    2)FileSystemXmlApplicationContext **
    它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
    ** 3)AnnotationConfigApplicationContext

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

    getBean()方法使用

    1.使用对应的id属性值来从spring容器中获取对象
    这个我就不叙述了,因为上面用的就是这种
    2.使用对应的class字节码文件来获取对应对象

    从spring容器中获取对应对象的代码

    package com.pjh.Test;
    import com.pjh.Service.userService;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public class test3 {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationCotext.xml");
            userService userService = app.getBean(com.pjh.Service.userService.class);
            userService.save();
        }
    }
    

    **
    使用这种方式获取代码,要注意当spring容器中配置了两个相同类的bean对象的时候,使用这种方式会报错,因为spring容器不知道你要获取的是哪个对象

    Spring配置数据源

    数据源介绍以及数据源,连接池,数据库三者的区别

    连接池:这个应该都学习过,比如c3p0,druid等等,连接池的作用是为了提高程序的效率,因为频繁的去创建,关闭数据库连接,会对性能有很大的消耗,所以就有了连接池,连接池顾名思义是存储多个连接的池子,池子中的连接都是创建好的,我们只要拿来使用即可,不用的时候就归还给连接池,这就大大减少了关闭创建连接的时间,提高了效率
    数据库:存储数据的地方
    数据源:数据源顾名思义是数据的来源,存储了连接数据库所需要的信息,也可以说是用于管理数据库连接池,并不存储真正的数据,仅仅记录了连接哪个数据库,怎么连接。如果把数据库比作一个文件的话,那么数据源存储的就是文件的名称,可以通过文件名称来找到对应的文件,算是一个抽象的映射,一个数据库对应一个数据源,数据源可能是一个连接,也可能是一个连接池。在J2EE里,数据源是代表物理数据存储系统的实际Java对象。通过这些对象,J2EE应用可以获取到数据库的JDBC连接。
    如果你是玫瑰,他就是牛粪
    在这里插入图片描述

    呸呸呸,说错了
    如果数据是水,数据库就是水库,数据源就是管道,终端用户看到的数据集是管道里流出来的水。
    在这里插入图片描述

    当然啦,Spring功能这么强大,怎么可能少的了数据源呢

    Spring配置数据源的步骤

    **
    1.所需的jar包

    junit

    <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
    

    druid

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.0.9</version>
    </dependency>
    

    c3p0

    <dependency>
        <groupId>c3p0</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.1.2</version>
    </dependency>
    
    

    spring—context

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.3.RELEASE</version>
    </dependency>
    

    mysql

    <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.32</version>
        </dependency>
    

    **
    2.我先手动配置一下数据园,等一下再用Spring容器经行配置,大家就能看到二者的巨大差别了

    手动配置数据源
    配置druid

     public void druid() throws SQLException {
            //创建数据源
            DruidDataSource druidDataSource = new DruidDataSource();
            //设置连接参数
            druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
            druidDataSource.setPassword("1234");
            druidDataSource.setUsername("root");
            druidDataSource.setUrl("jdbc:mysql://localhost:3309/one");
            //获取连接
            DruidPooledConnection connection = druidDataSource.getConnection();
            System.out.println(connection);
        }
    

    配置c3p0数据源

     public void getc3p0() throws PropertyVetoException, SQLException {
            //创建连接池
            ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
            //设置参数
            comboPooledDataSource.setDriverClass("com.mysql.jdbc.Driver");
            comboPooledDataSource.setPassword("1234");
            comboPooledDataSource.setUser("root");
            comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3309/one");
            //获取连接
            Connection connection = comboPooledDataSource.getConnection();
            System.out.println(connection);
        }
    

    为了降低代码的耦合度,我们可以使用读取配置文件的方式来获取需要设置的参数
    这里我也演示一下
    在resource下新建文件jdbc.properties
    jdbc.properties中的配置如下

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3309/one
    jdbc.username=root
    jdbc.password=1234
    
    

    测试方法如下

    public void getProperties() throws PropertyVetoException, SQLException {
            ResourceBundle jdbc = ResourceBundle.getBundle("jdbc");
            ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
            comboPooledDataSource.setJdbcUrl(jdbc.getString("jdbc.url"));
            comboPooledDataSource.setUser(jdbc.getString("jdbc.username"));
            comboPooledDataSource.setPassword(jdbc.getString("jdbc.password"));
            comboPooledDataSource.setDriverClass(jdbc.getString("jdbc.driver"));
            Connection connection = comboPooledDataSource.getConnection();
            System.out.println(connection);
        }
    

    使用Spring容器来创建数据源

    1.步骤1
    在前面导入相关数据库jar包的基础上再导入springcontext包

    <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.0.5.RELEASE</version>
            </dependency>
    
    
    下一篇:没有了