Spring学习笔记

Spring框架概述

1.Spring是轻量级的开源的JavaEE框架

2.Spring可以解决企业应用开发的复杂性

3.Spring有两个核心部分:IOCAOP

(1)IOC:控制反转,把创建对象的过程交给Spring进行管理
(2)AOP:面向切面,不修改源代码进行功能增强

4.Spring特点

   (1)方便解耦,简化开发
   (2)AOP编程支持
   (3)方便程序测试
   (4)方便和其他框架进行整合
   (5)方便进行事务操作
   (6)降低API开发难度

5.Spring版本5.x

        [https://repo.spring.io/release/org/springframework/spring](https://repo.spring.io/release/org/springframework/spring)

入门案例
1.idea,创建普通Java工程
2.导入Spring5相关jar包 Beans Core
Cotent Expression
3.创建普通类,在这个类创建普通方法

public class User {
   public void add(){
        System.out.println("add......");
   }
}

4.创建Spring配置文件,在配置文件配置创建的对象
(1)Spring配置文件使用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.cs.spring5.User"></bean> </beans>
5.进行测试代码编写
@Test public void testAdd(){ //1、加载spring配置文件 ApplicationContext
context = new ClassPathXmlApplicationContext("bean.xml");
//2、获取配置创建的对象 User user = context.getBean("user", User.class);

        System.out.println(user);
        user.add();
    }

IOC容器(控制反转)

(1)IOC底层原理
(2)IOC接口(BeanFactory)
(3)IOC操作Bean管理(基于xml)
(4)IOC操作Bean管理(基于注解)

1.什么是IOC?

(1)控制反转,把对象创建和对象之间的调用过程,交给Spring 进行管理
(2)使用IOC目的,为了耦合度降低
(3)做入门案例就是IOC实现

2.IOC底层原理

(1)xml解析,工厂模式,反射

3.IOC(接口)

1.IOC思想基于IOC容器完成,IOC容器底层就是对象工厂

2.Spring提供IOC容器实现两种方式:(两个接口)

              (1)BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用

                     *加载配置文件的时候不会创建对象,在获取对象(使用)的时候才会创建对象。 
                     
              (2)ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员进行使用。

                     *加载配置文件的时候就会把配置文件对象进行创建。

3.ApplicationContext接口有实现类

   FileSystemXmlApplicationContext
   和ClassPathXmlApplicationContext

4.IOC操作Bean管理

1.什么是Bean管理(概念)

(0)Bean管理指的是两个操作
(1)Spring创建对象
(2)Spring注入属性

2.Bean管理操作有两种方式

(1)基于xml配置文件方式实现 基于xml方式创建对象

 <!--配置User对象创建-->
                                   <bean id="user" class="com.cs.spring5.User"></bean>

(Ⅰ)在Spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
(Ⅱ)在bean标签中有很多属性,介绍常用的属性 *id属性:唯一标识,不能加特殊符号 *class属性:类全路径(包全路径) *name属性:和id属性差不多,但是它可以加特殊符号,
(Ⅲ)创建对象时候,默认也是执行无参数构造方法完成对象创建

基于xml方式注入属性

(Ⅰ)DI:依赖注入,就是注入属性

第一种注入方式:使用set方法进行注入 创建类,定义属性和对应的set方法

public class Book {
                                                               //创建属性
                                                               private String bname;
                                                               private String bauthor;
                                                              //创建属性对应的set方法
                                                               public void setBname(String bname) {
                                                                           this.bname = bname;
                                                                }

                                                               public void setBauthor(String bauthor) {
                                                                           this.bauthor = bauthor;
                                                                }
                                                           }

在Spring配置文件配置对象创建,配置属性注入

 <!--set方法注入属性-->
                                                     <bean id="book" class="com.cs.spring5.Book">
                                                     <!--使用property完成属性注入
                                                           name:类里面属性名称
                                                           value:向属性注入的值
                                                      -->
                                                     <property name="bname" value="易筋经"></property>
                                                     <property name="bauthor" value="达摩老祖"></property>
                                                     </bean>
                                   第二种注入方式:使用有参数构造进行注入
                                       
                        

<i>创建类,定义属性,创建属性对应的有参数构造方法
                                             /**
                                              * 使用有参构造注入
                                             */
                                             public class Orders {
                                             //属性
                                             private String oname;
                                             private String address;
                                             //有参数的构造
                                             public Orders(String oname, String address) {
                                             this.oname = oname;
                                             this.address = address;
                                             }
                                            }
                                            <ii>在Spring配置文件进行配置
                                                 <!--3、用有参构造注入属性-->
                                                 <bean id="orders" class="com.cs.spring5.Orders">
                                                 <constructor-arg name="oname" value="电脑"></constructor-arg>
                                                 <constructor-arg name="address" value="China"></constructor-arg>
                                                 </bean>

p名称空间注入(了解)

使用P名称空间注入,可以简化基于xml配置方式

第一步 添加p名称空间在配置文件中

<xmlns:p="http://www.springframework.org/schema/p"
                                             第二步 进行属性注入,在Bean标签里面进行操作
                                                    <!--set方法注入属性-->
                                                    <bean id="book" class="com.cs.spring5.Book" p:bname="九阳神功" p:bauthor="无名氏">
                                                    </bean>
                                    IOC操作Bean管理(xml注入其他类型属性)
                                    1、字面量
                                   (1)null值
                                        <!--null值-->
                                        <property name="adress">
                                        <null/>
                                        </property>
                                   (2)属性值包含特殊符号 
                                        <!--属性值包含特殊符号
                                            方法1、把<>进行转义&lt;&gt;
                                            方法2、把带特殊符号内容写到CDATA
                                        -->
                                        <property name="adress">
                                        <value><![CDATA[<<南京>>]]></value>
                                        </property>

(Ⅱ)注入属性,外部bean

(1)创建两个类sevice类和dao类
(2)在service调用dao里面的方法
(3)在Spring配置文件中进行配置

  public class UserService {

                                             //创建UserDao类型属性,生成set方法
                                             private UserDao userDao;

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

                                             public void add(){
                                             System.out.println("service add......");
                                             userDao.update();
                                              }
                                             }
                                             
 <bean id="userService" class="com.cs.spring5.service.UserService">
                                             <!--注入userDao对象
                                                 name属性值:类里面属性名称
                                                 ref属性:创建userDao对象bean标签id值
                                             -->
                                             <property name="userDao" ref="userDaoImpl"></property>
                                             </bean>
                                             <bean id="userDaoImpl"  class="com.cs.spring5.dao.UserDaoImpl"></bean>


                                        

## (Ⅲ)注入属性-内部bean和级联赋值

                                           

## (1)一对多关系:部门和员工 
一个部门(一)有多个员工,一个员工(多)属于一个部门

                                             
                                           

## (2)实体类中表示一对多关系

                                             
                                         

```java
  //部门类
                                           public class Dept {
                                           private String dname;

                                           public void setDname(String dname) {
                                           this.dname = dname;
                                            }
                                           }
                                           
                                           //员工类
                                           public class Emp {
                                           private String ename;
                                           private String gender;
                                           //员工属于某一个部门,使用对象形式进行表示
                                           private Dept dept;

                                           public void setDept(Dept dept) {
                                               this.dept = dept;
                                           }

                                           public void setEname(String ename) {
                                               this.ename = ename;
                                           }

                                           public void setGender(String gender) {
                                               this.gender = gender;
                                           }
                                         }

(3)在Spring配置文件中进行配置

 <!--内部bean-->
                                        <bean id="emp" class="com.cs.spring5.bean.Emp">
                                           <!--设置两个普通的属性-->
                                           <property name="ename" value="lucy"></property>
                                           <property name="gender" value="nv"></property>
                                           <!--设置对象类型的属性-->
                                           <property name="dept">
                                              <bean id="dept" class="com.cs.spring5.bean.Dept">
                                                  <property name="dname" value="安保部"></property>
                                              </bean>
                                           </property>
                                        </bean>
                                
                                
                                注入属性-级联赋值
                                    第一种写法
                                        <!--级联赋值-->
                                        <bean id="emp" class="com.cs.spring5.bean.Emp">
                                           <!--设置两个普通的属性-->
                                           <property name="ename" value="lucy"></property>
                                           <property name="gender" value=""></property>
                                           <!--级联赋值-->
                                           <property name="dept" ref="dept"></property>
                                        </bean>
                                        <bean id="dept" class="com.cs.spring5.bean.Dept">
                                           <property name="dname" value="财务部"></property>
                                        </bean>
                                        
                                    第二种写法(需要get方法)
                                        <!--级联赋值-->
                                        <bean id="emp" class="com.cs.spring5.bean.Emp">
                                           <!--设置两个普通的属性-->
                                           <property name="ename" value="lucy"></property>
                                           <property name="gender" value=""></property>
                                           <!--级联赋值-->
                                           <property name="dept" ref="dept"></property>
                                           <property name="dept.dname" value="技术部"></property>
                                        </bean>
                                        <bean id="dept" class="com.cs.spring5.bean.Dept">
                                            <property name="dname" value="财务部"></property>
                                        </bean>

IOC操作Bean管理(xml注入集合属性)

1、注入数组类型属性
2、注入List集合类型属性
3、注入Map集合类型属性
(1)创建类,定义数组,List,Map,Set类型属性,生成对应set方法

  public class Stu {
                                                  //数组类型的属性
                                                  private String[] courses;

                                                  //List集合类型属性
                                                  private List<String> list;

                                                  //Map集合类型属性
                                                  private Map<String,String> maps;

                                                  //Set集合类型属性
                                                  private Set<String> sets;

                                                  public void setCourses(String[] courses) {
                                                       this.courses = courses;
                                                  }

                                                  public void setList(List<String> list) {
                                                       this.list = list;
                                                  }

                                                  public void setMaps(Map<String, String> maps) {
                                                       this.maps = maps;
                                                  }

                                                  public void setSets(Set<String> sets) {
                                                       this.sets = sets;
                                                  }
                                                }

(2)在Spring配置文件中进行配置

<!--集合类型属性注入-->
                                                <bean id="stu" class="com.cs.spring5.collectiontype.Stu">
                                                    <!--数组类型属性注入-->
                                                    <property name="courses">
                                                        <array>
                                                            <value>java课程</value>
                                                            <value>数据库课程</value>
                                                        </array>
                                                    </property>
                                                    <!--list类型属性注入-->
                                                    <property name="list">
                                                        <array>
                                                            <value>张三</value>
                                                            <value>小张</value>
                                                        </array>
                                                    </property>
                                                    <!--map类型属性注入-->
                                                    <property name="maps">
                                                        <map>
                                                            <entry key="JAVA" value="php"></entry>
                                                            <entry key="PHP" value="php"></entry>
                                                        </map>
                                                    </property>
                                                    <!--set类型属性注入-->
                                                    <property name="sets">
                                                        <set>
                                                            <value>MySQL</value>
                                                            <value>Redis</value>
                                                        </set>
                                                    </property>
                                                </bean> 

4、在集合里面设置对象类型值

 <!--创建多个course对象-->
                                        <bean id="course1" class="com.cs.spring5.collectiontype.Course">
                                              <property name="ename" value="Spring5框架"></property>
                                        </bean>
                                        <bean id="course2" class="com.cs.spring5.collectiontype.Course">
                                              <property name="ename" value="MyBatis框架"></property>
                                        </bean>
                                    
                                         <!--注入list集合类型,值是对象-->
                                         <property name="courseList">
                                            <list>
                                               <ref bean="course1"></ref>
                                               <ref bean="course2"></ref>
                                            </list>
                                         </property>

5、把集合注入部分提取出来

(1)在Spring配置文件中引入名称空间util

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

(2)使用util标签完成list集合注入提取

 <!--提取list集合类型属性注入-->
                                              <util:list id="booklist">
                                                  <value>易筋经</value>
                                                  <value>九阴真经</value>
                                                  <value>九阳神功</value>
                                              </util:list>

                                              <!--提取list集合类型属性注入使用-->
                                              <bean id="book" class="com.cs.spring5.collectiontype.Book">
                                                  <property name="list" ref="booklist"></property>
                                              </bean>

IOC操作Bean管理(FactoryBean)

1、Spring有两种类型bean,一种普通bean,另外一种工厂bean(FactoryBean)
2、普通bean:在Spring配置文件中定义的bean类型就是返回类型

3、工厂bean:

在Spring配置文件中定义bean类型可以和返回类型不一样
第一步,创建类,让这个类作为工厂bean,实现接口FactoryBean
第二步,实现接口里面的方法,在实现的方法中定义返回的bean类型

public class MyBean implements FactoryBean<Course> 
{ 
//定义返回bean
 @Override
  public Course getObject() throws Exception {
   Course course = new Course();
    course.setEname("adc");
     return course; 
     }
     @Override
      public Class<?> getObjectType() 
      { 
      return null; 
      } 
      @Override
       public boolean isSingleton() 
       {
        return false;
         } 
         }

IOC操作Bean管理(bean作用域)

1、在Spring里面,设置创建bean实例是单实例还是多实例
2、在Spring里面,默认情况下,bean是单实例对象

                                            @Test
                                            public void testCollection2(){
                                              ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
                                              Book book1 = context.getBean("book", Book.class);
                                              Book book2 = context.getBean("book", Book.class);
                                              //book.test();
                                              System.out.println(book1);
                                              System.out.println(book2);
                                            }

输出情况为(相同):

com.cs.spring5.collectiontype.Book@d59286 
com.cs.spring5.collectiontype.Book@d59286

3、如何设置单实例还是多实例

(1)在Spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例
(2)scope属性值 第一个值 默认值,singleton,表示是单实例对象 第二个值 prototype,表示是多实例对象 <beanid="book"class="com.cs.spring5.collectiontype.Book"scope="prototype>

输出情况为(不同):

 com.cs.spring5.collectiontype.Book@d59286 
 com.cs.spring5.collectiontype.Book@1e18270

(3)singleton和prototype区别

第一、singleton单实例,prototype多实例
第二、设置scope值是singleton时候,加载spring配置文件就会创建单实例对象 设置scope值是prototype时候,不是在加载spring配置文件时候创建,在调用getBean方法时候创建多实例对象

IOC操作Bean管理(bean生命周期)

1、生命周期

(1)从对象创建到对象销毁的过程

2、bean生命周期

(1)通过构造器创建bean实例(无参数构造)
(2)为bean的属性设置值和对其他bean引用(调用set方法)
(3)调用bean的初始化的方法(需要进行配置初始化的方法)
(4)bean可以使用了(对象获取到了)
(5)当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法)

3、演示bean的生命周期

  public class Orders {
                                  private String oname;

                                  //无参构造
                                  public Orders(){
                                       System.out.println("第一步 执行无参数构造创建bean实例");
                                  }

                                  public void setOname(String oname) {
                                       this.oname = oname;
                                       System.out.println("第二步 调用set方法设置属性值");
                                  }

                                  //创建执行初始化的方法
                                  public void initMethod(){
                                       System.out.println("第三步 执行初始化的方法");
                                  }

                                  //创建执行的销毁的方法
                                  public void destroyMethod(){
                                       System.out.println("第五步 执行销毁的方法");
                                  }
                                }
                                
                                
                                 <bean id="orders" class="com.cs.spring5.bean.Orders" init-method="initMethod" destroy-method="destroyMethod">
                                    <property name="oname" value="手机"></property>
                                 </bean>
                                 
                                 
                                 public void testCollection4(){
                                    /*
                                       ApplicationContext context = 
                                       new ClassPathXmlApplicationContext("bean4.xml");
                                    */
                                       ClassPathXmlApplicationContext context =
                                       new ClassPathXmlApplicationContext("bean4.xml");

                                       Orders orders = context.getBean("orders", Orders.class);
                                       System.out.println("第四步 获取创建bean实例对象");
                                       System.out.println(orders);

                                       //手动让bean实例销毁
                                       context.close();
                                 }

4、bean的后置处理器

(加上后置处理器之后是7步)
(1)通过构造器创建bean实例(无参数构造)
(2)为bean的属性设置值和对其他bean引用(调用set方法)
(3)把bean实例传递bean后置处理器的方法postProcessBeforeInitialization()
(4)调用bean的初始化的方法(需要进行配置初始化的方法)
(5)把bean实例传递bean后置处理器的方法postProcessAfterInitialization()
(6)bean可以使用了(对象获取到了)
(7)当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法)

                                        5、演示添加后置处理器效果
                                            (1)创建类,实现接口BeanPostProcessor,创建后置处理器
   public class MyBeanPost implements BeanPostProcessor {
                                                @Override
                                                public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
                                                     System.out.println("在初始化之前执行的方法");
                                                     return bean;
                                                }

                                                @Override
                                                public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
                                                     System.out.println("在初始化之后执行的方法");
                                                     return bean;
                                                }
                                           }
  <!--配置后置处理器-->
                                                   <bean id="myBeanPost" class="com.cs.spring5.bean.MyBeanPost"></bean>
                                                   
                                        
                                        
                                     

## IOC操作Bean管理(xml自动装配)

                                           

## 1、什么是自动装配

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

## 2、演示自动装配过程

                                               (1)根据属性名称自动注入
                     

```xml
<!--实现自动装配
                         bean标签属性autowire,配置自动装配
                         autowire属性常用两个值:byName根据属性名称注入,注入值bean的id值和类属性名称一样
                         byType根据属性类型注入
                     -->
                     <bean id="emp" class="com.cs.spring5.autowire.Emp" autowire="byName">
                     <!--        <property name="dept" ref="dept"></property>-->
                     </bean>
                     <bean id="dept" class="com.cs.spring5.autowire.Dept"></bean>
                   (2)根据属性类型自动注入
                     <bean id="emp" class="com.cs.spring5.autowire.Emp" autowire="byType">
                     <!--        <property name="dept" ref="dept"></property>-->
                     </bean>
                     <bean id="dept" class="com.cs.spring5.autowire.Dept"></bean>
            
            IOC操作Bean管理(外部属性文件)
                1、直接配置数据库信息
                   (1)配置德鲁伊连接池
                   (2)引入德鲁伊连接池依赖jar包
                   <!--直接配置连接池-->
                   <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
                   <!-- 获取properties文件内容,根据key获取,使用spring表达式获取 -->
                   <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
                   <property name="url" value="jdbd:mysql://localhost:3306/newsmanager"></property>
                   <property name="username" value="root"></property>
                   <property name="password" value="1318579525"></property>
                   </bean>

2、引入外部属性文件配置数据库连接池

                                           (1)创建外部属性文件,properties格式文件,写数据库信息
 prop.driverClass=com.mysql.jdbc.Driver
                                                  prop.url=jdbc:mysql://localhost:3306/newsmanager
                                                  prop.username=root
                                                  prop.password=1318579525
                                           (2)把外部properties属性文件引入到spring配置文件中
                                                  *引入context名称空间
  <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">
                                                   在spring配置文件使用标签引入外部属性文件
                                                   <!--引入外部属性文件-->
                                                   <context:property-placeholder location="classpath:jdbc.properties"/>
                                                   <!--配置连接池-->
                                                   <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
                                                   <property name="driverClassName" value="${prop.driverClass}">
                                                   </property>
                                                   <property name="url" value="${prop.url}"></property>
                                                   <property name="username" value="${prop.username}"></property>
                                                   <property name="password" value="${prop.password}"></property>
                                                   </bean>

(2)基于注解方式实现

                   1、什么是注解?
                   
                    <1>注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值...)
                    <2>使用注解,注解作用在类上面,方法上面,属性上面
                    <3>使用注解目的:简化xml配置

2、Spring针对Bean管理中创建对象提供注解

                      ①@Component
                      ②@Service
                      ③@Controller
                      ④@Repository
                      上面四个注解功能是一样的,都可以用来创建bean实例                               

3、基于注解方式实现对象创建

        第一步,引入依赖
                           spring-aop-5.2.6.RELEASE.jar
        第二步,开启组件扫描
                           <!--开启组件扫描
                               1、如果扫描多个包,多个包使用逗号隔开
                               2、扫描包上层目录
                           -->
                           <context:component-scan base-package="com.cs"></context:component-scan>
        第三步,创建类,在类上面添加创建对象注解
                            //在注解里面value属性值可以省略不写,
                            //默认值是类名称,首字母小写
                            //@Component(value = "userService")//<bean id="userService" class="...">
                            //@Service
                            //@Controller
                            @Repository
                             public class UserService {
                                 public void add(){
                                    System.out.println("service add......");
                                 }
                             }                                            

4、开启组件扫描细节配置

                      use-default-filters="false"表示现在不使用默认filter,自己配置filter
                      context:include-filter,设置扫描哪些内容
                      context:exclude-filter:设置哪些内容不进行扫描         

5、基于注解方式实现属性注入

 ①@AutoWired:根据属性类型进行自动装配
       第一步 把service和dao对象创建,在service和dao类添加创建对象注解
       第二步 在service注入dao对象,在service类添加dao类型属性,在属性上面使用注解
  @Service
                           public class UserService {
                           //定义dao类型属性
                           //不需要添加set方法
                           //添加注入属性注解
                           @Autowired
                            private UserDao userDao;

                           public void add(){
                               System.out.println("service add......");
                               userDao.add();
                           }
                      第三步
                  ②@Qualifier:根据属性名称进行注入
                       这个@Qualifier注解的使用,和上面@Autowired一起使用
                       //定义dao类型属性
                       //不需要添加set方法
                       //添加注入属性注解
                       @Autowired//根据类型进行注入
                       @Qualifier(value = "userDaoImp1")//根据名称进行注入
                       private UserDao userDao;@Resource:可以根据类型注入,可以根据名称注入
                       //   @Resource//根据类型进行注入
                       @Resource(name = "userDaoImpl1")//根据名称进行注入

                       private UserDao userDao;@Value:注入普通类型属性
                       @Value(value = "abc")
                       private String name;

6、完全注解开发

1)创建配置类,替代xml配置文件
                             @Configuration//作为配置类,替代xml配置文件
                             @ComponentScan(basePackages = {"com.cs"})
                             public class SpringConfig {

                             }2)编写测试类
                             @Test
                              public void testService2(){
                              //加载配置类
                              ApplicationContext context = 
                              new AnnotationConfigApplicationContext(SpringConfig.class);
                              UserService userService = 
                              context.getBean("userService", UserService.class);
                              System.out.println(userService);
                              userService.add();
                              }

AOP(概念)

1、什么是AOP

(1)面向切面编程(方面),利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
(2)通俗描述:不通过修改源代码方式,在主干功能里面添加新功能
(3)使用登录例子说明AOP:在登陆中添加权限判断模块

2、AOP底层原理

(1)AOP底层使用动态代理 <Ⅰ>有两种情况动态代理 第一种
有接口情况,使用JDK动态代理 创建接口实现类代理对象,增强类的方法
第二种 没有接口情况,使用CGLIB动态代理
创建子类的代理对象,增强类的方法
(2)AOP(JDK动态代理)
使用JDK动态代理,使用Proxy类里面的方法创建代理对象
调用newProxyInstance方法 方法有三个参数: 第一参数,类加载器
第二参数,增强方法所在的类,这个类实现的接口,支持多个接口
第三参数,实现这个接口InvocationHandler,创建代理对象,写增强的方法
编写JDK动态代理代码 ①创建接口,定义方法

public interface UserDao {
public int add(int a,int b); public String update(String id);

          }
          ②创建接口实现类,实现方法
          public class UserDaoImpl implements UserDao{
          @Override
          public int add(int a, int b) {
           return a+b;
          }

          @Override
          public String update(String id) {
           return id;
          }
          }
          ③使用Proxy类创建接口代理对象
          public class JDKProxy {
          public static void main(String[] args) {
          //创建接口实现类代理对象
          Class[] interfaces = {UserDao.class};
          UserDaoImpl userDao = new UserDaoImpl();
          UserDao dao =  (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));
          int result = dao.add(1, 2);
          System.out.println("result:" + result);
          }
        }

         //创建代理对象代码
          class UserDaoProxy implements InvocationHandler{
          //把创建的是谁的代理对象,把谁传递过来
          //有参数构造传递
           private Object obj;
           public UserDaoProxy(Object obj){
             this.obj = obj;
           }
           //增强的逻辑
           @Override
           public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

           //方法之前
           System.out.println("方法之前执行...." + method.getName() + ":传递的参数..." + Arrays.toString(args));
           //被增强的方法执行
           Object res = method.invoke(obj, args);
           //方法之后
           System.out.println("方法之后执行...." + obj);

            return res;
            }
           }

3、AOP(术语)

(有很多,列举四种常用的) (1)连接点
类里面可以被增强的方法,这些方法称为连接点 (2)切入点
实际被真正增强的方法,称为切入点 (3)通知(增强)
①实际增强的逻辑部分称为通知(增强) ②通知有多种类型:
前置通知:增强的方法之前 后置通知:增强的方法之后 环绕通知:前后都有
异常通知:异常(try-catch) 最终通知:最终会被执行 (4)切面 指一个动作
把通知应用到切入点过程

4、AOP操作(准备工作)

(1)Spring框架一般都是基于AspectJ实现AOP操作
什么是AspectJ?
AspectJ不是Spring组成部分,独立AOP框架,一般把AspectJ和Spring框架一起使用,进行AOP操作

(2)基于AspectJ实现AOP操作 基于xml配置文件 基于注解方式实现(使用)

(3)在项目工程里面引入AOP相关依赖

(4)切入点表达式 ①切入点表达式作用:知道对哪个类里面的哪个方法进行增强
②语法结构:
execution([权限修饰符][返回类型][类全路径]方法名称)
举例1:对com.cs.dao.BookDao类里面的add进行增强

  execution(*com.cs.dao.BookDao.add(..))
              *表示所有修饰符
              返回类型可以省略
        举例2:对com.cs.dao.BookDao类里面的所有的方法进行增强
 execution(*com.cs.dao.BookDao.*(..))
        举例2:对com.cs.dao.BookDao包里面的所有类,类里面的所有的方法进行增强
 execution(*com.cs.dao.*.*(..))

5、AOP操作(AspectJ注解)

(1)创建类

,在类里面定义方法 public class
User { public void add(){ System.out.println(“add…”); } }

(2)创建增强类(编写增强逻辑)

①在增强类里面,创建方法,让不同方法代表不同通知 //增强的类 public class
UserProxy { //前置通知 public void before(){
System.out.println(“before…”); } }

(3)进行通知的配置

①在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:context="http://www.springframework.org/schema/context"
             xmlns:aop="http://www.springframework.org/schema/aop"

             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
             http://www.springframework.org/schema/aop
             http://www.springframework.org/schema/aop/spring-aop.xsd">

             <!--开启注解扫描-->
             <context:component-scan base-package="com.cs.spring5.aopanno">
             </context:component-scan>
             </beans>

②使用注解创建User和UserProxy对象

  //增强的类
    @Component
    public class UserProxy {
    //前置通知
      public void before(){
        System.out.println("before......");
      }
    }
    
    //被增强的类
    @Component
    public class User {
      public void add(){
        System.out.println("add.......");
      }
    }
 
 ③在增强类上面添加注解@Aspect
    @Aspect
    public class UserProxy {
    //前置通知
     public void before(){
       System.out.println("before......");
     }
    }

④在spring配置文件中开启生成代理对象

<!--开启Aspect生成代理对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

(4)配置不同类型的通知

①在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
//增强的类 @Component //生成代理对象 @Aspect public class UserProxy {
//前置通知 //@Before注解表示作为前置通知


```java
@Before(value =
"execution(*com.cs.spring5.aopanno.User.add(..))") public void before(){
System.out.println("before......"); } } @After(value = "execution(*
com.cs.spring5.aopanno.User.add(..))") public void after(){
System.out.println("after......"); } @AfterReturning(value =
"execution(\* com.cs.spring5.aopanno.User.add(..))") public void
afterReturning(){ System.out.println("afterReturning......."); }
@AfterThrowing(value = "execution(\*
com.cs.spring5.aopanno.User.add(..))") public void afterThrowing(){
System.out.println("afterThrowing........"); } //环绕通知 @Around(value
= "execution(\* com.cs.spring5.aopanno.User.add(..))") public void
around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
System.out.println("环绕之前..........."); //被增强的方法执行
proceedingJoinPoint.proceed();

            System.out.println("环绕之后...........");
            }

## (5)公共切入点抽取

 //相同切入点抽取 @Pointcut(value = "execution(\*
com.cs.spring5.aopanno.User.add(..))") public void pointdemo(){
          }
          //前置通知
          //@Before注解表示作为前置通知
          @Before(value = "pointdemo()")
          public void before(){
            System.out.println("before......");
          }

(

## 6)有多个增强类多同一个方法进行增强,设置增强类优先级

①在增强类上面添加注解@Order(数字类型值),数字类型值越小优先级越高
@Component @Aspect @Order(1) public class PersonProxy {

(

## 7)完全使用注解开发

 ①创建配置类,不需要创建xml配置文件 @Configuration
@ComponentScan(basePackages = {"com.cs"})//开启扫描
@EnableAspectJAutoProxy(proxyTargetClass = true) public class ConfigAop
{ }

## 6、AOP操作(AspectJ配置文件)

(1)创建两个类,增强类和被增强类,创建方法
(2)在spring配置文件中创建两个对象 <!--创建对象-->

```xml
<bean id="book" class="com.cs.spring5.aopxml.Book"></bean>
<bean id="bookProxy" class="com.cs.spring5.aopxml.BookProxy"></bean>

(3)在spring配置文件中配置切入点

<aop:config>
<!--切入点-->
<aop:pointcut id="p" expression="execution(* com.cs.spring5.aopxml.Book.buy(..))"/>

          <!--配置切面-->
          <aop:aspect ref="bookProxy">
          <!--增强作用在具体的方法上-->
          <aop:before method="before" pointcut-ref="p"/>
          </aop:aspect>
          </aop:config>

JdbcTemplate(概念和准备)

(1)什么是JdbcTemplate

①Spring框架对JDBC进行封装,使用JdbcTemplate方便实现对数据库操作

(2)准备工作

①引入相关jar包

mysql-connector-java-5.0.4-bin.jar
spring-jdbc-5.2.6.RELEASE.jar
spring-orm-5.2.6.RELEASE.jar
spring-tx-5.2.6.RELEASE.jar druid-1.1.9.jar

②在spring配置文件中配置数据库连接池

  <!-- 配置连接池 -->
       <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
       <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
       <property name="url" value="jdbc:mysql:///newsmanager"></property>
       <property name="username" value="root"></property>
       <property name="password" value="1318579525"></property>
       </bean>

③配置JdbcTemplate对象,注入DataSource

  <!--JdbcTemplate对象-->
       <bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
       <!--注入DataSource-->
       <property name="dataSource" ref="dataSource"></property>
       </bean>

④创建Service类,创建dao类,在dao注入JdbcTemplate对象

配置文件

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

Service

 @Service
      public class BookService {
      //注入dao
      @Autowired
      private BookDao bookDao;
      }
      

Dao

 @Repository
      public class BookDaoImpl implements BookDao {
      //注入JdbcTemplate
      @Autowired
      private JdbcTemplate jdbcTemplate;
      }

(3)JdbcTemplate操作数据库(添加)

①对应数据库创建实体类 public class

UserInfo { private int userID; private String userName; private String
userPass; private String sex; private int age; private String email;

           public int getUserID() {
            return userID;
           }

           public void setUserID(int userID) {
            this.userID = userID;
           }

           public String getUserName() {
            return userName;
           }

           public void setUserName(String userName) {
            this.userName = userName;
           }

           public String getUserPass() {
            return userPass;
           }

           public void setUserPass(String userPass) {
            this.userPass = userPass;
           }

           public String getSex() {
            return sex;
           }

           public void setSex(String sex) {
            this.sex = sex;
           }

           public int getAge() {
            return age;
           }

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

           public String getEmail() {
            return email;
           }

           public void setEmail(String email) {
            this.email = email;
           }
           }

②编写service和dao

在dao进行数据库添加操作 调用JdbcTemplate对象里面update方法实现添加操作

 @Repository
       public class BookDaoImpl implements BookDao {
       //注入JdbcTemplate
       @Autowired
       private JdbcTemplate jdbcTemplate;
       //添加的方法
       @Override
       public void add(Book book) {
       String sql = "insert into book(userName,userPass,sex,age,email) value(?,?,?,?,?)";
       Object obj[] = {book.getUserName(),book.getUserPass(),book.getSex(),book.getAge(),book.getEmail()};
        int update = jdbcTemplate.update(sql,obj);
        System.out.println(update);
       
        }
       }
     ③测试类
        @Test
        public void testJdbcTemplate(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        BookService bookService = context.getBean("bookService",BookService.class);
        Book book = new Book();
        book.setUserName("sb王");
        book.setUserPass("123");
        book.setSex("男");
        book.setAge(22);
        book.setEmail("sb@qq.com");
        bookService.addBook(book);

        }

(4)JdbcTemplate操作数据库(修改和删除)

①修改

@Override public void
updateBook(Book book) { String sql = "update book set userName =
?,userPass = ? where userId = ?"; Object obj[] =
{book.getUserName(),book.getUserPass(),book.getUserID()}; int update =
jdbcTemplate.update(sql, obj); System.out.println(update); } ②删除
@Override public void delete(int id) { String sql = "delete from book
where userId = ?"; Object obj = id; int update =
jdbcTemplate.update(sql, obj); System.out.println(update);

         }
         

③测试类

   @Test
     public void testJdbcTemplate(){
     ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
     BookService bookService = context.getBean("bookService",BookService.class);
     //添加
     /* Book book = new Book();
     book.setUserName("sb王");
     book.setUserPass("123");
     book.setSex("男");
     book.setAge(22);
     book.setEmail("sb@qq.com");
     bookService.addBook(book);*/

     //修改
    /* Book book = new Book();
     book.setUserName("sb王");
     book.setUserPass("123");
     book.setUserID(1);
     bookService.updateBook(book);*/

     //删除
     bookService.deleteBook(6);
     }

(5)JdbcTemplate操作数据库(查询返回某个值)

queryForObject()

①查询表里面有多少条记录,返回是某个值
②使用JdbcTemplate实现查询返回某个值的代码 有两个参数: sql语句
返回类型Class //查询记录数

 @Override public int selectCount() { String
sql = "select count(\*) from book"; Integer count =
jdbcTemplate.queryForObject(sql, Integer.class); return count; }

(6)JdbcTemplate操作数据库(查询返回对象)

queryForObject()

①有三个参数: sql语句
RowMapper,是接口,返回不同类型数据,使用这个接口里面实现类完成数据封装
sql语句值

 @Override
  public Book findBookInfo(int id) { String sql =
"select \* from book where userId = ?"; Book book =
jdbcTemplate.queryForObject(sql, new
BeanPropertyRowMapper<Book>(Book.class), id); return book; }

(7)JdbcTemplate操作数据库(查询返回集合)

query()

①有三个参数:
sql语句
RowMapper,是接口,返回不同类型数据,使用这个接口里面实现类完成数据封装
sql语句值

@Override public List<Book> findAllBook() { String sql =
"select \* from book"; List<Book> bookList = jdbcTemplate.query(sql, new
BeanPropertyRowMapper<Book>(Book.class)); return bookList; }

(8)JdbcTemplate操作数据库(批量操作)

①批量操作:操作表里面多条记录
②JdbcTemplate实现批量添加操作

batchUpdate(String sql,List<Object[]>
batchArgs) 有两个参数: sql语句 List集合,添加多条记录数据 @Override
public void batchAddBook(List<Object[]> batchArgs) { String sql =
"insert into book(userName,userPass,sex,age,email) value(?,?,?,?,?)";
int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);
System.out.println(Arrays.toString(ints)); }
     ③JdbcTemplate实现批量修改操作
  @Override
        public void batchUpdateBook(List<Object[]> batchArgs) {
        String sql = "update book set userName = ?,userPass = ? where userId = ?";
        int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);
        System.out.println(Arrays.toString(ints));
        }
     ④JdbcTemplate实现批量删除操作
  @Override
        public void batchDeleteBook(List<Object[]> batchArgs) {
        String sql = "delete from book where userId = ?";
        int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);
        System.out.println(Arrays.toString(ints));
        }
        
        测试类:
        List<Object[]> batchArgs = new ArrayList<>();

        Object[] o1 = {1};
        Object[] o2 = {2};
        Object[] o3 = {3};
        batchArgs.add(o1);
        batchArgs.add(o2);
        batchArgs.add(o3);
        //调用批量添加
        bookService.batchDelete(batchArgs);

事务操作(事务概念)

(1)什么是事务?

①事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操作都失败
②典型场景:银行转账 lucy转账100元,给mary lucy少100,mary多100

##( 2)事务四个特性(ACID特性)

①原子性 ②一致性 ③隔离性 ④持久性

事务操作(搭建事务操作环境)

(1)创建数据库表,添加记录

(2)创建service,搭建dao,完成对象创建和注入关系
①service注入dao,在dao,在JdbcTemplate注入DataSource\

 @Service注入JdbcTemplate public class UserService { //注入dao
@Autowired private UserDao userDao; }

           @Repository
           public class UserDaoImpl implements UserDao {

           @Autowired
           private JdbcTemplate jdbcTemplate;
           }


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



           <!-- 配置连接池 -->
           <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
           <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
           <property name="url" value="jdbc:mysql:///newsmanager"></property>
           <property name="username" value="root"></property>
           <property name="password" value="1318579525"></property>
           </bean>

           <!--JdbcTemplate对象-->
           <bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
           <!--注入DataSource-->
           <property name="dataSource" ref="dataSource"></property>
           </bean>

(3)在dao创建两个方法,多钱和少钱的方法,在service创建方法(转账的方法)

@Repository public class UserDaoImpl implements UserDao {

              @Autowired
              private JdbcTemplate jdbcTemplate;



              //多钱
              @Override
              public void addMoney() {
              String sql = "update t_account set money = money + ? where username = ?";
              jdbcTemplate.update(sql,100,"marry");
              }
              //Lucy转账100给mary
              //少钱
              @Override
              public void reduceMoney() {
              String sql = "update t_account set money = money - ? where username = ?";
              jdbcTemplate.update(sql,100,"lucy");
              }
              }   
              
              
              
              @Service
              public class UserService {
              //注入dao
              @Autowired
              private UserDao userDao;

              //转账的方法
              public void accountMoney(){
              //lucy少100
              userDao.reduceMoney();
        
              //mary多100
              userDao.addMoney();
              }
              }

(4)上面代码,如果正常执行没有问题,但是如果代码执行过程中出现异常,有问题
//转账的方法

 public void accountMoney(){ //lucy少100
userDao.reduceMoney();

              //模拟异常
              int i = 10/0;

              //mary多100
              userDao.addMoney();
              }   
     ①上面问题如何解决呢?
        使用事务进行解决
     ②事务操作过程
try{
        //1、开启事务

        //2、进行业务操作

        //lucy少100
        userDao.reduceMoney();

        //模拟异常
        int i = 10/0;

        //mary多100
        userDao.addMoney();


    //第三步 没有发生异常,提交事务
    }catch (Exception e){
        //第四步 出现异常,事务回滚
    }

事务操作(Spring事务管理介绍)

(1)事务添加到J2EE三层结构里面Service层(业务逻辑层)
(2)在Spring进行事务管理操作
①有两种方式:编程式事务管理和声明式事务管理(使用) (3)声明式事务管理
①基于注解方式 ②基于xml配置文件方式
(4)在Spring进行声明式事务管理,底层使用AOP原理 (5)Spring事务管理API
①提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类

事务操作(注解声明式事务管理)

(1)在Spring配置文件配置事务管理器

(2)在Spring配置文件,开启事务注解 ①在Spring配置文件引入名称空间tx

<xmlns:tx="http://www.springframework.org/schema/tx"

             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
             http://www.springframework.org/schema/aop
             http://www.springframework.org/schema/aop/spring-aop.xsd
             http://www.springframework.org/schema/tx
             http://www.springframework.org/schema/tx/spring-tx.xsd">
             
          ②开启事务注解
             <!--开启事务注解-->
             <tx:annotation-driven transaction-manager="TransactionManager"></tx:annotation-driven>
      ③在service类上面(获取service类里面方法上面)添加事务注解   
          @Transactionl,这个注解添加到类上面,也可以添加方法上面
            如果把这个注解添加类上面,这个类里面所有的方法都添加事务
            如果把这个注解添加方法上面,为这个方法添加事务
   @Service
             @Transactional
             public class UserService {

事务操作(声明式事务管理参数配置)

(1)在service类上面添加注解@Transactional,在这个注解里面可以配置事务相关参数
(2)propagation:事务传播行为
多事务方法直接进行调用,这个过程中事务是如何进行管理的
Spring框架事务传播行为有7种
REQUIRED 如果add方法本身有事务,调用update方法之后,update使用当前add方法里面事务
如果add方法本身没有事务,调用update方法之后,创建新事务
REQUIRED_NEW 使用add方法调用update方法,如果add无论是否有事务,都创建新的事务

(3)ioslation:事务隔离级别
事务有特性成为隔离性,多事务操作之间不会产生影响。不考虑隔离性产生很多问题
有三个读问题:脏读、不可重复读、虚(幻)读

①脏读:一个未提交的事务读取到另一个未提交事务的数据

②不可重复读:一个未提交的事务读取到了另一个已提交事务修改的数据

③虚读:一个未提交的事务读取到了另一个已提交事务添加的数据

通过设置事务的隔离性就可以解决三个读的问题:
READ UNCOMMITTED(读未提交) READ COMMITTED(读已提交) REPEATABLE
READ(可重复读)Mysql默认为 SERIALIZABLE(串行化)

@Service
@Transactional(propagation = Propagation.REQUIRED,isolation =
Isolation.REPEATABLE\_READ) public class UserService {

(4)timeout:超时时间 事务需要在一定时间内进行提交,如果不提交进行回滚
默认值是-1,设置时间以秒单位进行计算 (5)readOnly:是否只读
读:查询操作,写:添加修改删除操作
readOnly默认值是false,表示可以查询,可以添加修改删除操作
设置readOnly值是true,设置成true之后,只能查询 (6)rollbackFor:回滚
设置出现哪些异常进行事务回滚 (7)noRollbackFor:不回滚
设置出现哪些异常不进行事务回滚

事务操作(XML声明式事务管理) (1)在Spring配置文件中进行配置 第一步
配置事务管理器 第二步 配置通知 第三步 配置切入点和切面\

 <!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property> </bean>
              <!--2、配置通知-->
              < tx:advice id="txadvice">
              <!--配置事务参数-->
              <tx:attributes>
              <!--指定哪种规则方法上面添加事务-->
              <tx:method name="accountMoney" propagation="REQUIRED"/>
              </tx:attributes>
              </tx:advice>

              <!--3、配置切入点和切面-->
              <aop:config>
              <!--配置切入点-->
              <aop:pointcut id="pt" expression="execution(* com.cs.spring5.service.UserService.*(..))"/>
              <!--配置切面-->
              < aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
              </aop:config>         

事务操作(完全注解开发)

(1)创建配置类,使用配置类替代xml配置文件

@Configuration//配置类 @ComponentScan(basePackages =
"com.cs")//开启组件扫描 @EnableTransactionManagement//开启事务 public
class TxConfig { //创建数据库连接池 @Bean public DruidDataSource
getDruidDataSource(){ DruidDataSource dataSource = new
DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///newsmanager");
dataSource.setUsername("root"); dataSource.setPassword("1318579525");
return dataSource; } //创建JdbcTemplate对象 @Bean public JdbcTemplate
getJdbcTemplate(DataSource dataSource){
//到IOC容器中根据类型找到dataSource JdbcTemplate jdbcTemplate = new
JdbcTemplate(); //注入dataSource jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate; } //事务管理器 @Bean public
DataSourceTransactionManager getDataSourceTransactionManager(DataSource
dataSource){ DataSourceTransactionManager transactionManager = new
DataSourceTransactionManager();
transactionManager.setDataSource(dataSource); return transactionManager;
} }

Spring5框架新功能

(1)整个Spring5框架的代码基于Java8,运行时兼容JDK9,许多不建议使用的类和方法在代码库中删除
(2)Spring5.0框架自带了通用的日志封装
①Spring5已经移除log4jconfigListener,官方建议使用log4j2
②Spring框架整合log4j2 第一步引入jar包
第二步创建log4j2.xml配置文件

 <?xml version="1.0" encoding="UTF-8"?>
      <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
      <!--Configuration后面的status用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,可以看到log4j2内部各种详细输出-->
      <configuration status="INFO">
      <!--先定义所有的appender-->
      <appenders>
      <!--输出日志信息到控制台-->
      <console name="Console" target="SYSTEM_OUT">
      <!--控制日志输出的格式-->
      <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
      </console>
      </appenders>
          <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
          <!--root:用于指定项目的根日志,如果没有单独指定Logger,则会使用root作为默认的日志输出-->
          <loggers>
          <root level="info">
          <appender-ref ref="Console"/>
          </root>
          </loggers>
          </configuration>
          

(3)Spring5框架核心容器支持@Nullable注解

①@Nullable注解可以使用在方法上面,属性上面,参数上面,表示方法返回可以为空,属性值可以为空,参数值可以为空

(4)Spring5核心容器支持函数式风格

GenericApplacationContext
//函数式风格创建对象,交给spring进行管理 @Test public void
testGenericApplicationContext() { //1 创建GenericApplicationContext对象
GenericApplicationContext context = new GenericApplicationContext(); //2
调用context的方法对象注册 context.refresh();
context.registerBean(“user1”,User.class,() -> new User()); //3
获取在spring注册的对象 // User user =
(User)context.getBean(“com.atguigu.spring5.test.User”); User user =
(User)context.getBean(“user1”); System.out.println(user); }

(5)Spring5支持整合JUnit5

①整合JUnit4
第一步引入Spring相关依赖针对测试依赖 spring-test-5.2.6.RELEASE.jar
第二步创建测试类,使用注解方式完成

@RunWith(SpringJUnit4ClassRunner.class)//指定junit版本
@ContextConfiguration("classpath:bean1.xml")//加载配置文件 public class
JTest4 { @Autowired private UserService userService;

              @Test
              public void test1(){
              userService.accountMoney();
              }
              }
         ②Spring整合JUnit5
            第一步 引入JUnit5的jar包
              org.junit.jupiter.api.DynamicTest;
            第二步 创建测试类,使用注解完成
              package com.cs.spring5.test;


              import com.cs.spring5.service.UserService;
              import org.junit.jupiter.api.Test;
              import org.junit.jupiter.api.extension.ExtendWith;

              import org.springframework.beans.factory.annotation.Autowired;
              import org.springframework.test.context.ContextConfiguration;
              import org.springframework.test.context.junit.jupiter.SpringExtension;


              @ExtendWith(SpringExtension.class)//注解引用
              @ContextConfiguration("classpath:bean1.xml")
              public class JTest5 {
              @Autowired
              private UserService userService;

              @Test
              public void test1(){
              userService.accountMoney();
              }
              }

③使用一个复合注解替代上面两个注解替代上面两个注解完成整合

   @SpringJUnitConfig(locations = "classpath:bean1.xml")
        public class JTest5 {
        @Autowired
        private UserService userService;

        @Test
        public void test1(){
        userService.accountMoney();
        }
        }

Spring5框架新功能

(1)SpringWebflux介绍
(2)响应式编程
(3)Webflux执行流程和核心API
(4)SpringWebflux(基于注解编程)
(5)SpringWebflux(基于函数式编程模型)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值