javaee之spring1

什么是Spring

一、Spring的优势

二、Spring的体系结构

先说一下从什么位置去下载Spring的源码

进入Spring官网,找到Spring Framework框架

 

点进去之后,找到如下位置,继续点击

 

 进去之后,继续下拉,找到下面这个位置点进去

 

进去之后继续点击 

 

 找到上面这个位置之后,就按照层级目录,继续点下去

 

然后你就可以下载你想要的版本了

 具体的体系结构 

 Ioc的概念和作用

一、分析一下程序之间的耦合性

首先我们来创建一个maven项目,然后里面写一个Jdbc的连接程序,它需要一个mysql的连接jar包

导入到pom.xml里面

pom.xml

 

上面程序的运行成功依赖于com.mysql.jdbc.Driver()这个对象 ,这个就是耦合,上面如果没有引入mysql的jar包,就会编译期给我们报错

耦合:程序间的依赖关系,这里面就包括了类之间的依赖与方法之间的依赖

解耦:降低程序之间的依赖关系

在实际开发中:编译期不依赖,运行时才依赖

上面代码我们就可以做出一些修改

那么解耦的思路:

        第一步:使用户反射来创建对象,而避免使用new关键字

        第二步:通过读取配置文件来获取要创建的对象全限定类名

 二、曾经代码中的问题分析

首先我们来看一个模拟的账户查询业务代码

先来看一下dao层

做了一很简单的事儿,就死调用了数据库保存了账户信息

 下面进入到service层里面看一下

 下面在进入到业务层里面

上面这种各个文件的依赖关系啊,会让程序的耦合性非常差,其实就是太依赖了嘛

先来看一下依赖的这两个对象

 

你说这两个对象是不是都可以通过工厂模式来创建

所以我们来创建一个工厂来产生这两个对象的,我们都知道,工厂模式,是利用反射来创建对象的,下面来具体说一下如何创建

先来说一下实现原理

先来做这个配置文件

 

下面就是在工厂里面引入配置文件,然后把对象封装到集合里面,然后每次根据传入的key,来获取响应的对象

BeanFactory.java

package com.pxx.factory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 一个创建Bean对象的工厂
 * Bean:在计算机里面就是组件的意思
 * JavaBean: 用java写的可重用组件 一般理解为一个实体类
 * 但是JavaBean的概念大于了实体类
 *
 * 下面说一下创建servicea对象和dao对象的核心步骤
 * 1.需要一个配置文件来配置service和dao的全限定类名,这里也就是说不要写死
 * 2.通过读取配置文件的配置内容,反射创建对象
 *
 */
public class BeanFactory {
    //这个后面引入配置文件信息
    private static Properties prop;

    //把对象引入到一个map集合里面
    private static Map<String,Object> objectMap;

    static {
        try {
            //上面两个属性必须new出来
            prop = new Properties();
            objectMap = new HashMap<String, Object>();
            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            //信息加载到Properties类里面
            prop.load(in);
            //下面就是循环拿到key,利用value进行newInstance
            Enumeration e = prop.keys();
            while (e.hasMoreElements()) {
                String key = (String) e.nextElement();//这个会拿到key
                String value = prop.getProperty(key);//根据key来得到值
                Object o = Class.forName(value).newInstance();
                //然后把对象添加到集合里面
                objectMap.put(key, o);
            }
        } catch (Exception e) {
            //如果出错,直接error,程序失败
            throw new ExceptionInInitializerError("初始化失败");
        }
    }

    //需要根据配置文件的参数来获得相应对象
    //name-》{accountService,accountDao}
    public Object getObject(String name) {
        //集合里面封装了两个对象
        return objectMap.get(name);
    }
}

现在我们去修改业务层的调用

 然后去修改表现层的代码

运行结果:

 

  分析一下上面的代码,一定是单例设计

 

 一张图来直接说明

 单例设计的有点就在于,内存不会开辟那么多的对象,提高效率

下面来说一下Ioc的概念与作用

根据上面的代码,之前我们是这样来生产一个对象

 

也就是说应用层与对象直接打交道。但是它现在放弃了这种方式,按照如下方式来创建了一个对象

 

 把创建对象的工作交给了框架

这种被动接收的方式获取对象的思想就是控制反转,它是Spring框架的核心之一

使用Spring的IOC解决程序耦合 

先来说一下Spring的开发包

 进入到dist里面

 特别说明:

我们用的是Spring5.0的版本

可以从这个位置去查询一些相关信息

  

下面我们来实现Account账户的解耦。

1.导入需要的spring的jar包,然后整一个xml文档,这个名字只要是英文就行

 这个spring的相关jar包就做出来了,看一下右边

 

这个xml文档约束,就可以去

 

点进去这个位置去找

 

直接复制引入

 

 然后去到表现层里面

运行结果:

 

 下面来说一下ApplicationContext这个类

看一下结构

 右键选择它的实现类

 我们用到的就是下面这个实现类

我们直接拿一张图放过来

 

 BeanFactory 和 和 ApplicationContext 的区别

 ApplicationContext接口实现类:

spring中利用BeanFactory来实现对象的创建:

这个对象的创建内部需要传入一个资源文件对象

 

 IOC中bean 标签和管理对象细节

一、创建Bean的三种方式

第一种:通过默认构造函数创建对象

第二种: 使用普通工厂的方法创建对象(使用某个类中的方法创建对象,存入spring容器)

也就是调用下面类中的方法创建一个对象

其实得到IAccountService的对象方法没有做啥改动 ,只是内部获取对象的方式发生了变化

第三种使用工厂当中的某个静态方法获取对象(使用某个类中的静态方法创建对象)

先来创建这个类与方法

 

 

三、bean的作用范围与生命周期

这里主要来演示一下单例和多例

说一下先在AccountServiceImpl里面做一个默认的构造函数,创建对象的时候会被调用,默认调用无参构造

 这里说一下我这配置的域是单例的,单例在什么时候创建对象

 我们在下面设置一个断点

 debug一运行,你看对象无参构造已经被调用了

 所以单例是在加载配置文件的时候就会被调用起来

Spring依赖注入

一、什么是依赖注入

 

二、依赖 注入的方式

 

构造函数注入

 

 把AccountDaoImpl.java做一些修改,这只是一个模拟过程,不代表实际业务

 上面就展示了通过构造函数需要封装的数据,下面是一个封装结果

上面就通过构造函数注入好了,下面来测试一下,很明显就是被调起来了嘛

 set注入

这里必须说一下set注入原理

然后在说一下它的使用方法 

 在使用set方法注入之前,一定要生成set方法

假如说这里我们把无参构造给注释起来

然后再去看一下 bean.xml里面的set配置

 客户端也看一下

然后调一下

 

报一堆错,这个其实就是说,没有去实例化一个AccountDaoImpl.java的一个对象,因为你把无参给注释掉了

现在打开

 

 

下面就来说复杂类型的注入与集合类型的注入

 

先来看一下AccountDaoImpl1.java

package com.pxx.dao.impl;

import com.pxx.dao.IAccountDao;

import java.util.*;

public class AccountDaoImpl1 implements IAccountDao {

    private String[] myStrs;
    private List<String> myList;
    private Set<String> mySet;
    private Map<String,String> myMap;
    private Properties myProps;

    public void setMyStrs(String[] myStrs) {
        this.myStrs = myStrs;
    }

    public void setMyList(List<String> myList) {
        this.myList = myList;
    }

    public void setMySet(Set<String> mySet) {
        this.mySet = mySet;
    }

    public void setMyMap(Map<String, String> myMap) {
        this.myMap = myMap;
    }

    public void setMyProps(Properties myProps) {
        this.myProps = myProps;
    }

    public void saveAccount() {
        System.out.println(Arrays.toString(myStrs));
        System.out.println(myList);
        System.out.println(mySet);
        System.out.println(myMap);
        System.out.println(myProps);
    }
}

去bean.xml里面配置一下

 运行结果:

 这里上一下bean.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">

    <!-- spring中的依赖注入
        依赖注入:
            Dependency Injection
        IOC的作用:
            降低程序间的耦合(依赖关系)
        依赖关系的管理:
            以后都交给spring来维护
        在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明
        依赖关系的维护:
            就称之为依赖注入。
         依赖注入:
            能注入的数据:有三类
                基本类型和String
                其他bean类型(在配置文件中或者注解配置过的bean)
                复杂类型/集合类型
             注入的方式:有三种
                第一种:使用构造函数提供
                第二种:使用set方法提供
                第三种:使用注解提供(明天的内容)
     -->


    <!--构造函数注入:
        使用的标签:constructor-arg
        标签出现的位置:bean标签的内部
        标签中的属性
            type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
            index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
            name:用于指定给构造函数中指定名称的参数赋值                                        常用的
            =============以上三个用于指定给构造函数中哪个参数赋值===============================
            value:用于提供基本类型和String类型的数据
            ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象

        优势:
            在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
        弊端:
            改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
    -->
    <bean id="now" class="java.util.Date"></bean>
  <bean id="accountDao" class="com.pxx.dao.impl.AccountDaoImpl">
         <constructor-arg name="name" value="张三"></constructor-arg>
        <constructor-arg name="age" value="25"></constructor-arg>
        <constructor-arg name="birthday" ref="now"></constructor-arg>
  </bean>

    <!--
        采用set方法注入
    -->
    <bean id="accountDao1" class="com.pxx.dao.impl.AccountDaoImpl">
        <property name="name" value="纠结伦"></property>
        <property name="age" value="21"></property>
        <property name="birthday" ref="now"></property>
    </bean>

    <!--
        复杂类型的注入、集合类型注入
    -->
    <bean id="accountDao2" class="com.pxx.dao.impl.AccountDaoImpl1">
        <property name="myStrs">
            <set>
                <value>张三</value>
                <value>王五</value>
                <value>李四</value>
            </set>
        </property>

        <property name="myList">
            <array>
                <value>list1</value>
                <value>list2</value>
                <value>list3</value>
            </array>
        </property>

        <property name="mySet">
            <list>
                <value>set1</value>
                <value>set2</value>
                <value>set3</value>
            </list>
        </property>

        <!--下面
        是map集合和Properties的对象自动注入
        -->
        <property name="myMap">
            <props>
                <prop key="map1">map1</prop>
                <prop key="map2">map2</prop>
            </props>
        </property>

        <property name="myProps">
            <map>
               <entry key="myProps1" value="张三"></entry>
               <entry key="myProps2" value="李四"></entry>
            </map>
        </property>
    </bean>


</beans>

这里的代码在spring1_copy_normal。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值