1.Maven的简单介绍

1.1 maven的介绍

image.png

1.2 maven的安装

  1. maven官网:[https://maven.apache.org/](https://maven.apache.org/)<br /> maven仓库:[https://mvnrepository.com/](https://mvnrepository.com/)<br /> 安装步骤:<br />1、安装jdk<br />2、从官网中下载对应的版本<br />3、解压安装,然后配置环境变量,需要配置MAVEN_HOME,并且将bin目录添加到path路径下'<br />4、在命令行中输入mvn -v,看到版本信息表示安装成功

1.3 maven的基本常识

maven如何获取jar包
maven通过坐标的方式来获取 jar包,坐标组成为:公司/组织(groupId)+项目名(artifactId)+版本(version)组成,可以从互联网,本地等多种仓库源获取jar包
maven仓库的分类
本地仓库:本地仓库就是开发者本地已经下载下来的或者自己打包所有jar包的依赖仓库,本地仓库路径配置在maven对应的conf/settings.xml配置文件。
设置本地仓库:
C:\repmvn
私有仓库:私有仓库可以理解为自己公司的仓库,也叫Nexus私服
中央仓库:中央仓库即maven默认下载的仓库地址,是maven维护的
maven的常用仓库
由于网络访问的原因,在国内如果需要下载国外jar包的时候会受限,因此一般在使用过程中需要修改maven的配置文件,将下载jar包的仓库地址修改为国内的源,常用的是阿里云的mvn仓库,修改配置如下:
maven目录/conf/setting.xml

设置镜像:

 <mirror>
        <id>nexus-aliyun</id>
        <name>Nexus aliyun</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public</url>
        <mirrorOf>central</mirrorOf>
    </mirror> 
    <mirror>
        <id>central</id>
        <name>Maven Repository Switchboard</name>
        <url>http://repo.maven.org/maven2/</url>
        <mirrorOf>central</mirrorOf>
    </mirror>
    <mirror>
        <id>central</id>
        <name>Maven Repository Switchboard</name>
        <url>http://repo2.maven.org/maven2/</url>
        <mirrorOf>central</mirrorOf>
    </mirror>
<br />**设置默认jdk版本:**
<!--修改默认jdk编译版本,默认jdk1.5-->
    <profile>
    <id>jdk-1.8</id>
     <activation>
          <activeByDefault>true</activeByDefault>
          <jdk>1.8</jdk>
      </activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>

1.4、maven常用命令

  • clean:清理编译后的目录
  • compile:编译,只编译main目录,不编译test中的代码
  • test-compile:编译test目录下的代码
  • test:运行test中的代码
  • package:打包,将项目打包成jar包或者war包
  • install:发布项目到本地仓库,用在打jar包上,打成的jar包可以被其他项目使用
  • deploy:打包后将其安装到pom文件中配置的远程仓库
  • site:生成站点目录

2.SpringIoc的入门

2.1新建maven项目,在pom.xml文件中引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>spring_ioc</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
    </dependencies>


</project>

2.2 新建配置文件spring-ioc.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="user" class="com.xixi.User">
    </bean>

</beans>

2.3 编写测试类

public class IocTest {

    @Test
    public void test01(){
        ApplicationContext app = new ClassPathXmlApplicationContext("spring-ioc.xml");
        User user = (User) app.getBean("user");
        System.out.println(user);
    }
}

3.IOC的使用

3.1 容器概述

ApplicationContext是Spring IoC容器实现的代表,它负责实例化,配置和组装Bean。容器通过读取配置元数据获取有关实例化、配置和组装哪些对象的说明 。配置元数据可以使用XML、Java注解或Java代码来呈现。它允许你处理应用程序的对象与其他对象之间的互相依赖关系。

3.2 配置元数据

  • 使用xml的配置

简单、直观 适合入门

Spring 2.5 支持基于注解的元数据配置. SSM框架开发中的使用

从 Spring 3.0开始, 由Spring JavaConfig项目提供的功能已经成为Spring核心框架的一部分。因此,你可以使用Java配置来代替XML配置定义外部bean .
从spring4.0开始支持springboot1.0 之后 springboot完全采用javaConfig的方式进行开发。
1.2.2. 容器的实例化
对象在Spring容器创建完成的时候就已经创建完成,不是需要用的时候才创建。

3.3 Bean的概述

3.3.1 设置别名

  <!-- 设置Bean的别名-->
    <alias name="user" alias="user2" />

    <!-- name也可以设置别名 使用空格 逗号 分号设置多个别名-->
    <bean id="user" class="com.xixi.User" name="user3 user4,user5;user6">
    </bean>

3.3.2 实例化Bean

3.3.2.1 使用静态工厂方法实例化

    <bean id="userService" class="com.xixi.service.UserServiceImpl" factory-method="createBean" />

class类中:


    public static UserServiceImpl createBean(){
        return new UserServiceImpl();
    }

3.3.2.2 使用实例工厂方法实例化

    <bean id="userService2" class="com.xixi.service.UserServiceImpl" 
    factory-method="createBean2" factory-bean="userService"/>

类中方法:

 public UserServiceImpl createBean2() {
        return new UserServiceImpl();
    }

4.依赖

4.1 注入的方式

4.1.1 setter方法注入

<!--基于setter方法的依赖注入
    1. 属性必须声明了set方法
    2. name是根据set方法的名字来的  比如方法名字是: setIdxx   ->  name="idxx"
-->
<bean class="cn.xixi.beans.User" id="user2">
    <property name="id" value="1"></property>
    <property name="username" value="zhangsan"></property>
    <property name="realname" value="张三"></property>
</bean>

4.1.2 构造器注入

<!--基于构造函数的依赖注入
    1. 将会调用自定义构造函数来实例化对象,就不会调用默认的无参构造函数
    2. name是根据构造函数的参数名来的,  比如:User(String idxx) -> name="idxx"
    3. name属性可以省略 但是要注意参数的位置 
    4. 如果非要把位置错开 可以使用 name 或者 index 或者 type
    5. index 是下标  从0开始
    6. type 在位置错开情况下只能在类型不一样的时候指定才有明显效果
-->
<bean class="cn.xixi.beans.User" id="user3">
    <constructor-arg name="username"  value="lisi"></constructor-arg>
    <constructor-arg name="id"  value="1"></constructor-arg>
    <constructor-arg name="realname" value="李四"></constructor-arg>
</bean>

4.2 依赖和配置的细节

  <!-- 复杂类型 -->
    <bean id="person" class="com.xixi.Person">
        <property name="id" value="1" />
        <!-- null值设置-->
        <property name="name">
            <null></null>
        </property>
        <!-- 外部bean引用 -->
<!--        <property name="wife" ref="wife" />-->


        <!--使用内部bean引用 -->
        <property name="wife">
            <bean class="com.xixi.Wife">
                <property name="id" value="24"></property>
                <property name="name" value="xiaolan"></property>
            </bean>
        </property>

        <!-- list注入:
        如果泛型是基础类型使用value标签
        如果泛型是别的类型就使用bean标签
        -->
        <property name="hobbies">
            <list>
                <value>唱歌</value>
                <value>跳舞</value>
            </list>
        </property>

        <!-- map注入
        如果value是基础类型是<entry key="1" value="java"></entry>
        如果value是其他类型,就使用bean   -->
        <property name="course">
            <map>
                <entry key="1" value="java"></entry>
                <entry key="2" value="php"></entry>
            </map>
        </property>
        <property name="birthday" value="2020/08/09"></property>
    </bean>


    <bean id="wife" class="com.xixi.Wife" >
        <property name="id" value="23"></property>
        <property name="name" value="binbin"></property>
    </bean>


    <!--可以使用p命名空间来简化基于setter属性注入   它不支持集合-->
<bean id="wife2" class="com.xixi.Wife" p:name="ddd" p:id="12"></bean>

<!-- 可以使用c命名空间来简化基于构造函数属性注入   它不支持集合-->
<bean id="wife3" class="com.xixi.Wife" c:id="23" c:name="fff"></bean>

4.3 使用depends-on属性

<!--使用depends-on可以设置先加载的Bean   也就是控制bean的加载顺序-->
    <bean class="com.xixi.Person" id="person" depends-on="wife">
        <property name="wife" ref="wife"></property>
    </bean>

4.4 懒加载

<!--使用lazy-init设置懒加载
默认为false: 在spring容器创建的时候加载(实例化)
      true: 在使用的时候(getBean)才会去加载(实例化)-->
<bean class="com.xixi.Person" id="person" lazy-init="true">
</bean>

4.5 Bean的作用域

<!--作用域scope
singleton 默认:单例  只会在Ioc容器种创建一次
prototype 多例(原型bean) 每次获取都会new一次新的bean-->

<bean class="cn.xixi.beans.Person" id="person3" scope="prototype">
    <property name="id" value="1"></property>
    <property name="realName" value="吴彦祖"></property>
    <property name="name" value="徐庶"></property>
</bean>

image.png

5.自动注入

当一个对象中需要引用另外一个对象的时候,在之前的配置中我们都是通过property标签来进行手动配置的,其实在spring中还提供了一个非常强大的功能就是自动装配,可以按照我们指定的规则进行配置,配置的方式有以下几种:
default/no:不自动装配
byName:按照名字进行装配,以属性名作为id去容器中查找组件,进行赋值,如果找不到则装配null
byType:按照类型进行装配,以属性的类型作为查找依据去容器中找到这个组件,如果有多个类型相同的bean对象,那么会报异常,如果找不到则装配null
constructor:按照构造器进行装配,先按照有参构造器参数的类型进行装配,没有就直接装配null;如果按照类型找到了多个,那么就使用参数名作为id继续匹配,找到就装配,找不到就装配null

  • 通过将autowire-candidate 属性设置为false,避免对bean定义进行自动装配。
  • 通过将其 元素的primary属性设置为 true,将单个bean定义指定为主要候选项。
<!--**************************************基于xml自动注入 begin**************************************************-->

<!--自动注入:
1. bytype 根据类型自动注入(spring会根据bean里面的所有对象属性的类型,只要它匹配到bean里面某一个类型跟属性类型吻合就会自动注入
2. byname 会根据属性setxxx的名字来自动匹配 (spring会根据bean里面的所有对象属性的set的名字,只要它匹配到bean里面某一个名字跟属性名字吻合就会自动注入
3. constructor 优先根据名字来找, 如果名字没有匹配到根据类型来匹配,  如果类型匹配到多个则不会自动注入
注意:bytype  如果匹配到两个同样的类型会出现错误,所以一定要保证ioc容器里面只有一个对应类型的bean
      byname  最能匹配到唯一的那个bean
      constructor 保证构造函数不能包含多余的其他参数
 default:不会进行自动注入

<bean class="cn.xixi.beans.Person" id="person6" autowire="constructor" >
    <property name="id" value="1"></property>
    <property name="realName" value="吴彦祖"></property>
    <property name="name" value="徐庶"></property>
 </bean>

<bean class="cn.xixi.beans.Wife" id="wife" p:age="18" p:name="迪丽热巴"  >
</bean>
<bean class="cn.xixi.beans.Wife" id="QBL" p:age="60" p:name="乔碧螺"  >
</bean>
 **************************************基于xml自动注入 end**************************************************-->

6.生命周期回调

生命周期回调
初始化方法回调
销毁方法回调
在非Web应用中优雅地关闭Spring IoC容器

/**
 * 生命周期回调
 * 1. 使用接口实现的方式来实现生命周期的回调:
 *      1.1   初始化方法: 实现接口: InitializingBean  重写afterPropertiesSet方法   初始化会自动调用的方法
 *      1.1   销毁的方法: 实现接口: DisposableBean  重写destroy 方法   销毁的时候自动调用方法
 *      什么时候销毁:在spring容器关闭的时候  close()
 *                   或者 使用ConfigurableApplicationContext.registerShutdownHook方法优雅的关闭
 *
 * 2. 使用指定具体方法的方式实现生命周期的回调:
 *    在对应的bean里面创建对应的两个方法
 *   init-method="init" destroy-method="destroy"
 */

7.spring创建第三方bean对象

在Spring中,很多对象都是单实例的,在日常的开发中,我们经常需要使用某些外部的单实例对象,例如数据库连接池,下面我们来讲解下如何在spring中创建第三方bean实例。
1、导入数据库连接池的pom文件

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid</artifactId>
   <version>1.1.21</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.47</version>
</dependency>

2、编写配置文件

<?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="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
       <property name="username" value="root"></property>
       <property name="password" value="123456"></property>
       <property name="url" value="jdbc:mysql://localhost:3306/demo"></property>
       <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
   </bean>
</beans>

3、编写测试文件

public class MyTest {
   public static void main(String[] args) throws SQLException {
       ApplicationContext context = new ClassPathXmlApplicationContext("ioc3.xml");
       DruidDataSource dataSource = context.getBean("dataSource", DruidDataSource.class);
       System.out.println(dataSource);
       System.out.println(dataSource.getConnection());
  }
}

spring引用外部配置文件

在resource中添加dbconfig.properties

username=root
password=123456
url=jdbc:mysql://localhost:3306/demo
driverClassName=com.mysql.jdbc.Driver
<?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:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">
<!--加载外部配置文件
在加载外部依赖文件的时候需要context命名空间
-->
   <context:property-placeholder location="classpath:dbconfig.properties"/>
   <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
       <property name="username" value="${username}"></property>
       <property name="password" value="${password}"></property>
       <property name="url" value="${url}"></property>
       <property name="driverClassName" value="${driverClassName}"></property>
   </bean>
</beans>

9 SpEL的使用

SpEL:Spring Expression Language,spring的表达式语言,支持运行时查询操作对象使用#{…}作为语法规则,所有的大括号中的字符都认为是SpEL.

<bean id="user" class="cn.xixi.entity.User">
       <!--支持任何运算符-->
       <property name="id" value="#{12*2}"></property>
       <!--可以引用其他bean的某个属性值-->
       <property name="name" value="#{address.province}"></property>
       <!--引用其他bean-->
       <property name="role" value="#{address}"></property>
       <!--调用静态方法-->
       <property name="hobbies" value="#{T(java.util.UUID).randomUUID().toString().substring(0,4)}"></property>
       <!--调用非静态方法-->
       <property name="gender" value="#{address.getCity()}"></property>
</bean>