Spring全方位整理,内附源代码

Spring

1.本章主要内容

1.Spring框架概要

2.IOC容器

3.AOP

4.JdbcTemplate

5.事务管理

6.Spring5新特性

2.Spring概要

概述

它是一个轻量级的开源的JavaEE框架

轻量级:体积小,依赖的jar包少,并且不需要依赖额外的组件

开源:免费提供源代码

框架:可以简化我们构建框架的过程

目的

为了解决企业级应用的复杂性

核心

IOC:控制反转-把创建对象的过程交给Spring进行管理

AOP:面向切面编程-不修改源码进行功能增强

优点

  • 方便解耦,简化开发

  • 对AOP编程支持

  • 方便程序的测试

  • 方便集成整合其他各种的框架

  • 方便进行事务操作

  • 降低API的开发

3.Spring入门案例

  • 先再pojo里创建User实体类
package com.wdzl.pojo;

public class User {


    public void showInfo(){
        System.out.println("我是User的对象");
    }
}

  • 再在resource中创建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">
    <!--    创建user对象 -->
        <bean id="user" class="com.wdzl.pojo.User"></bean>
    </beans>
    
    • 最后在test里进行测试

      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      
      public class UserTest {
          @Test
          public void test(){
              //1.加载Spring配置文件
              ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
              //2.通过获取User对象
              User user = context.getBean("user",User.class);
              user.showInfo();
      
          }
      }
      

Spring入门案例2

1.创建图书类

public class Book {
   private String name;
   private String author;
   }

2.创建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">
<!--    创建book对象方式有两种 -->
<!--    <bean id="book" class="com.wdzl.pojo.Book">-->
<!--        <property name="name" value="Java从入门到入土"></property>-->
<!--        <property name="author" value="布莱恩特"></property>-->
<!--    </bean>-->
    <bean id="book" class="com.wdzl.pojo.Book">
        <!--方式有两种-->
<!--         <constructor-arg name="name" value="Java葵花宝典"></constructor-arg>-->
<!--         <constructor-arg name="author" value="啊giao"></constructor-arg>-->
         <constructor-arg index="0" value="Java葵花宝典"></constructor-arg>
         <constructor-arg index="1" value="啊giao"></constructor-arg>
    </bean>
</beans>

3.test

import com.wdzl.pojo.Book;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BookTest {
    @Test
    public void test(){
        //1.加载配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("beans2.xml");
        //2.获取对象
        Book book = context.getBean("book", Book.class);
        System.out.println(book);
    }
}

4.IOC容器

概述

控制反转
控制反转就是把创建对象,和对象间的调用的过程交给Spring来管理。目的是为了降低类与类之间的耦合性
底层原理

  • XML解析
  • 工厂模式
  • 反射

原理图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FAVq9xSK-1617436140529)(C:\Users\dell\Pictures\java截图\IOC底层原理.jpg)]

几个重要的概念

1.IOC容器:IOC的实现,依赖于IOC容器,而IOC容器的本质就是对象工厂
2.IOC容器的实现
BeanFactory:

  • 是最底层的接口,他只提供了最简单的容器功能:加载配置文件 和 创建对象

    当加载配置文件时,不会创建被配置的对象,只有在使用时,对象才会创建

    • 好处:节省内存

    • 坏处:因为在服务器运行的时候去创建对象,会影响执行效率

      ApplicationContext:

  • 应用上下文,他是继承了BeanFactory,它是Spring更高级的一个容器接口,它提供了更多有用的功能

    当加载配置文件的时候,会同时创建被配置的 对象

    • 好处:效率高,将复杂的创建过程在服务器启动时完成
    • 坏处:耗费资源
      • ApplicationContext的三个实现类
        查看:选中ApplicationContext —》按Ctrl 点击 —》右上角download source(如果有)-----》Ctrl H—》即可查看继承体系结构
        ClassPathXmlApplicationContext:从项目中的Sources文件中加载配置文件你
        FileSystemXmlApplicationContext:从文件系统读取配置文件(需要访问权限)
        AnnotationConfigApplicationContext:读取注解配置

5.IOC操作-Bean管理

概念

IOC 操作-Bean管理是指两个操作:

​ 1.Spring创建对象

​ 2.Spring注入属性(属性赋值)

实现方式

1.XML方式
2.注解方式

5.1.基于XML方式—创建对象

该方式与入门案例方式相同
bean标签的常用属性
id:唯一标识,通过该属性可以找到对应的Bean标签
class:类的全限定类名
注意事项
创建对象时,默认执行无参构造方法来完成对象的创建(反射)

5.2.基于XML—注入属性(属性赋值)

**DI:**依赖注入,它是IOC的一个具体操作
分类
1.使用set方法进行注入
2.使用构造器 进行注入
演示
属性注入通过
name:实体类属性名
value:属性类

p命名空间注入

1.在配置文件中添加一个约束

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

2.注入Bean

<bean id="book" class="com.wdzl.pojo.Book" p:name = "Java入门宝典" p:author="aaa">
    </bean>
外部Bean

新建modul,在pom,xml中添加相关依赖

按照三层架构:1.Dao,Service,Web,pojo   2.resource  3.test

定义两个接口

package com.wdzl.service;

public interface UserService {
    void addUser();
}
package com.wdzl.dao;

public interface UserDao {
    void addUser();
}

在类的同一级定义两个impl下的类

package com.wdzl.dao.impl;

import com.wdzl.dao.UserDao;

public class UserDaoImpl implements UserDao {

    @Override
    public void addUser() {
        System.out.println("我是帅哥");
    }
}

import com.wdzl.dao.UserDao;
import com.wdzl.service.UserService;

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    @Override
    public void addUser() {
        userDao.addUser();
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

在xml中添加外部bean

<!--    创建userDao对象 -->
    <bean id="userDao" class="com.wdzl.dao.impl.UserDaoImpl"></bean>
<!--        配置userservice对象-->
    <bean id="userService" class="com.wdzl.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"></property>
    </bean>

test

 @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserService service = context.getBean("userService", UserService.class);
        service.addUser();
    }
内部Bean

创建两个实体类在pojo中

package com.wdzl.pojo;

public class Dept {
    private String deptName;
}
package com.wdzl.pojo;

public class Emp {
    private String name;
    private String gender;
    private Dept dept;
}
<!--内部bean-->
    <bean id="emp" class="com.wdzl.pojo.Emp">
        <!--基本数据-->
        <property name="name" value="周杰伦"></property>
        <property name="gender" value="男"></property>
        <!--引用数据类型-->
        <property name="dept">
            <bean id="dept" class="com.wdzl.pojo.Dept">
                <property name="deptName" value="研发部"></property>
            </bean>
        </property>
     </bean>

test

  @Test
    public void innerBeanTest(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans2.xml");
        Emp emp = context.getBean("emp", Emp.class);
        System.out.println(emp);
    }

级联操作

级联操作方式1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CFnudQMY-1617436140531)(C:\Users\dell\Pictures\java截图\级联操作_LI.jpg)]

级联操作方式2:

<!--将Bean里面的东西,如下,添加到引用数据类型下-->  

<property name="dept.deptName" value="研发部"></property>

注意:

针对方式2:

1.一定要在相应的类中添加get,set方法,否则会爆红。

2.同时给两个对象的属性同时赋值。

属性注入

创建实体类

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

public class Demo {
    private String[] strings;
    private List<String> list;
    private Map<String,String> map;
}

xml中完成

<bean id="demo" class="com.wdzl.pojo.Demo">
    <!--字符串数组-->
    <property name="strings">
        <array>
            <value>你好</value>
            <value>Hello</value>
        </array>
    </property>
    <!--list集合-->
    <property name="list">
        <list>
            <value>Hello</value>
            <value>Spring</value>
        </list>
    </property>
    <!--map-->
    <property name="map">
        <map>
            <entry key="Hello" value="你好"></entry>
            <entry key="Spring" value="春天"></entry>
        </map>
    </property>
</bean>

test

 @Test
    public void arrayMapTest(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans4.xml");
        Demo demo = context.getBean("demo", Demo.class);
        System.out.println(demo);
    }
引用数据类型

创建实体类

package com.wdzl.pojo;

public class City {
    private String cityname;
    }
package com.wdzl.pojo;

import java.util.List;

public class Province {
    private List<City> cities;
}

配置对象信息

方法一

<!--<bean id="province" class="com.wdzl.pojo.Province">-->
<!--    <property name="cities" >-->
<!--        <list>-->
<!--            <ref bean="city1"></ref>-->
<!--            <ref bean="city2"></ref>-->
<!--        </list>-->
<!--    </property>-->
<!--</bean>-->
<!--    <bean id="city1" class="com.wdzl.pojo.City">-->
<!--        <property name="cityname" value="西安"></property>-->
<!--    </bean>-->
<!--    <bean id="city2" class="com.wdzl.pojo.City">-->
<!--        <property name="cityname" value="延安"></property>-->
<!--    </bean>-->

方法二

<?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:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/util
                           http://www.springframework.org/schema/util/spring-util.xsd">
<util:list id="cityList">
    <value>西安</value>
    <value>延安</value>
    <value>宝鸡</value>
</util:list>
    <bean id="province" class="com.wdzl.pojo.Province">
        <property name="cities" ref="cityList"></property>
    </bean>
</beans>

test

    @Test
    public void arrayMapTest(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans5.xml");
        Province province = context.getBean("province", Province.class);
        System.out.println(province);}
FactoryBean

概述

Spring 中有两种类型的Bean,一种是普通的Bean,一种是工厂Bean

  • 普通Bean
  • 工厂Bean

创建实体类

package com.wdzl.pojo;

import org.springframework.beans.factory.FactoryBean;

public class MyBean implements FactoryBean<String> {
    /**
     * 返回对象,此方法中真正注入MyBean时返回的对象
     * @return
     * @throws Exception
     */
    @Override
    public String getObject() throws Exception {
        return "我是字符串";
    }

    /**
     * 返回对象类型
     * @return
     */
    @Override
    public Class<?> getObjectType() {
        return null;
    }

    /**
     * 是否是单例
     * @return
     */
    @Override
    public boolean isSingleton() {
        return false;
    }
}

配置文件

<bean id="myBean" class="com.wdzl.pojo.MyBean"></bean>

test

   @Test
    public void factoryBeanTest(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans6.xml");
        String myBean = (String)context.getBean("myBean");
        System.out.println(myBean);
    }

5.3Bean的作用域

概述

在Spring中设置并创建Bean实例是单例还是多例

注意

Singleton和prototype的区别:

1.Singleton:加载配置文件时对象便会创建,并且值创建一个对象

2.prototype:在加载配置文件时并部创建对象,在调用getBean方法时才会创建对象,并且每次调用都会创建。

5.4Bean的生命周期

概述:

一个对象从创建到销毁的过程

过程:

1.通过构造器创建Bean实例

2.为Bean的属性设置值或引用其他Bean(调用set方法)

执行后置处理

3.调用Bean的初始化方法

执行后置处理

4.Bean的对象获取

5.容器关闭,调用Bean的销毁方法

演示

创建实体类

package com.wdzl.pojo;

public class User {
    private String name;
    }
package com.wdzl.pojo;


import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * 后置处理类
 */
public class MyBeanLast implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第三步,执行后置处理postProcessBeforeInitialization");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第五步,执行后置处理postProcessAfterInitialization");
        return bean;
    }
}

beans.xml

<bean id="user" class="com.wdzl.pojo.User" init-method="init" destroy-method="destroy">
    <property name="name" value="周杰伦"></property>
</bean>
    <bean id="MyBeanLast" class="com.wdzl.pojo.MyBeanLast"></bean>

test

    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        User user = context.getBean("user", User.class);
        System.out.println("第六步,获取对象");
        ((ClassPathXmlApplicationContext)context).close();
    }

输出结果:

第一步,通过构造器创建对象
第二步,为Bean的属性设置值
第三步,执行后置处理postProcessBeforeInitialization
第四步,调用初始化方法
第五步,执行后置处理postProcessAfterInitialization
第六步,获取对象
第七步,调用销毁的方法

5.5XML自动装配

概述:

根据指定的装配规则(属性名称,属性类型),Spring自动将匹配的属性注入

实现

借助标签里的autowire属性来实现自动装配,该属性有两个值:

  • byName:根据属性名注入

  • byType:根据属性类注入

    如果有多个属性相同的Bean标签,自动装配会报错

    5.6引入外部配置文件

        <!--引入外部配置文件-->
    <context:property-placeholder location="jdbc.properties"/>
            <bean id="dateSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${druid.driverClassName}"></property>
            <property name="url" value="${druid.url}"></property>
            <property name="username" value="${druid.username}"></property>
            <property name="password" value="${druid.password}"></property>
        </bean>
    

5.7基于注解方式创建对象

**注解概述:**注解时代码的贴特殊标记

注解格式:@注解名称(属性名=)

**注解应用:**它可以简化XML的配置,注解可以用在类上,属性,方式上

Spring针对创建对象提供了四个注解

  • @Component:普通类使用

  • @Service:Service层使用

  • @Controller:Web层使用

  • @Repository:Dao层使用

    这四个注解功能时相同的,都可以用来创建Bean对象

步骤:

导依赖

创建实体类

package com.wdzl.dao;

import org.springframework.stereotype.Repository;
@Repository(value = "userDao")//相当于id属性,括号里的可以写可不写
public class UserDao {
    public void addUser(){
        System.out.println("UserDao:addUser...");
    }
}

配置文件

<!--    开启组件扫描-->
<context:component-scan base-package="com.wdzl.dao"></context:component-scan>

test

  @Test
    public void test (){
        ApplicationContext context  = new ClassPathXmlApplicationContext("beans.xml");
        UserDao userDao = context.getBean("userDao", UserDao.class);
        userDao.addUser();
    }

5.8基于注解方式-属性注入

常用注解

1.@AutoWired:根据属性类型进行注解方式的属性注入

2.@Quailifier

要与AutoWired同时使用

同时使用时为了

6.AOP

概述:

面向切面编程,在不改变源码的情况下对现有程序进行维护

6.1AOP底层原理

**概述:**底层使用了动态代理技术

**分类:**两种情况的动态代理

  • 没有接口的情况,使用了CGLIB动态代理

    • 通过创建子类对象,在子类中重写方法,并通过super.方法名()调用被代理类中的方法
  • 有接口的情况:使用JDK的动态代理

    • 代理对象与被代理对象实现相同的接口

6.2AOP相关术语

  • 连接点(JoinPoint):类里面那些方法可以被增强,这些方法就叫做连接点

  • 切入点(Advice):类中实际被增强的方法,成为切入点

  • 通知/增强:

    • 前置增强:在调用被增强方法前执行
    • 后置增强:在调用被增强方法后执行
    • 环绕增强:在调用被增强方法前后都执行
    • 异常增强:在调用被增强方法出现异常时执行
    • 最终增强:在调用被增强方法后,无论是否出现异常,都会被执行
  • 切面(Aspect):切面本身是一个动作,将增强应用到切入点的过程

  • 代理(Proxy)

  • 目标对象(Target)

  • 织入(Weaving)

6.3Aspectj

**概述:**Aspectj

相关依赖

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.wdzl</groupId>
    <artifactId>07_AOP_anno</artifactId>
    <version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <!--Spring日志依赖-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!--        junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
        </dependency>
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>
    </dependencies>
</project>

切入点表达式:

**概述:**让Spring框架知道那个类里面的那个方法需要在增强

语法结构

  • execution([权限修饰符])[返回值类型] [全限定类名] ([参数列表])

    • 权限修饰符可以省略
    • 返回值为*代表任意返回值类型
  • 举例

    • 对com.wdzl.dao.UserDao类中的addUser方法进行增强
    • execution(*com.wdzl.dao.UserDao)

7.JDBCTemplate

**概述:**Spring对JDBC的封装,使用它可以方便的去操作数据库

8.事务

8.1事务环境搭建

新建module

编写配置文件

编写Dao层接口,及相应的实现类

测试

8.2事务操作

  • 事务应添加到三层架构中的service层

    • 因为Service负责组装业务
  • 在Spring中进行事务管理

    • 编程式事务
    • 声明式事务
  • 声明式事务管理

    • 基于注解方式
    • 基于XML方式
  • 在Spring中进行声明式事务管理,使用了AOP

8.3常见事务类型

- propagation :事务传播行为
- isolation: 事务隔离级别
- timeout:超时时间
- readOnly:是否只读
- rollbackFor:回滚
ifactId>cglib
3.3.0



切入点表达式:

**概述:**让Spring框架知道那个类里面的那个方法需要在增强

语法结构

- execution([权限修饰符])[返回值类型] [全限定类名] ([参数列表])
  - 权限修饰符可以省略
  - 返回值为*代表任意返回值类型

- 举例
  - 对com.wdzl.dao.UserDao类中的addUser方法进行增强
  - execution(*com.wdzl.dao.UserDao)

## 7.JDBCTemplate

**概述:**Spring对JDBC的封装,使用它可以方便的去操作数据库

## 8.事务

### 8.1事务环境搭建

<font color='cornflowerblue'>新建module</font>

<font color='cornflowerblue'>编写配置文件</font>

<font color='cornflowerblue'>编写Dao层接口,及相应的实现类</font>

<font color='cornflowerblue'>测试</font>

### 8.2事务操作

- 事务应添加到三层架构中的service层
  - 因为Service负责组装业务

- 在Spring中进行事务管理
  - 编程式事务
  - <font color='red'>声明式事务</font>

- 声明式事务管理
  - <font color='red'>基于注解方式</font>
  - 基于XML方式

- 在Spring中进行声明式事务管理,使用了AOP

### 8.3常见事务类型

\- propagation :事务传播行为
\- isolation: 事务隔离级别
\- timeout:超时时间
\- readOnly:是否只读
\- rollbackFor:回滚
\- noRollbackFor:不回滚
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值