spring5学习笔记

Spring5

1.基本概念

  1. 轻量级开源javaee框架

  2. 解决开发复杂性

  3. 两大核心:IOC,Aop

    IOC:控制反转,将对象创建交给spring进行管理

    Aop:面向切面,不修改源代码进行功能增强

  4. 特点:

    1. 方便解耦,简化开发
    2. Aop支持
    3. 方便测试
    4. 方便整合各种框架
    5. 方便事务操作,降低api难度
      spring5学习笔记_第1张图片

入门测试

  1. 框架下载导入[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jcu8wPzV-1650025796628)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220319135557285.png)]

  2. xml配置[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N5wKEKKV-1650025796629)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220319135612639.png)]

  3. @Test
    public void add(){
        //加载配置文件(src下)
        ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");
        //获取配置创建对象
        User user = context.getBean("User", User.class);
        System.out.println(user);
        user.add();
    }
    
    

2.Ioc容器

底层原理

百度百科: 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做**依赖注入(Dependency Injection,简称DI**),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ho2usKzf-1650025796629)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220319140245899.png)]

image-20220319140346838

对于两个类之间耦合度过高的问题:

  1. 工厂模式
  2. Ioc

IOC过程

  1. 配置xml

  2. 创建工厂类,

  3. public static Object create(){
        Object o=null;
        //此处使用xml解析获取全类名
        String classname="com.fate.spring5.User";
        //反射获取对象
        try {
            Class clazz =Class.forName(classname);
            o = clazz.newInstance();
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return o;
    }
    

BeanFactory接口

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

2,IOC容器的两种实现方式

  1. BeanFactory:IOC容器的基本实现,通常是spring内部使用

    加载配置文件的时候不会创建对象,在获取的时候才创建

  2. ApplicationContext:BeanFactory的子接口,提供更多,更强大的功能

    在加载配置文件的时候,就进行对象的创建

3,ApplicationContext实现类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qpJxq3uq-1650025796630)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220319144856834.png)]

FileSystemXmlApplicationContext:使用磁盘路径

ClassPathXmlApplicationContext:使用项目的类路径

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-abLFyoZY-1650025796631)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220319145523657.png)]

包含一些拓展方法

Bean操作

Bean管理

  1. 创建对象
  2. 属性注入

操作Bean管理(xml)

创建:同入门测试
  1. 在配置文件中使用bean标签,标签中添加对应属性,就可实现对象的创建
  2. 标签:id:唯一标识**||class**:全类名**||name**:类似于id
  3. 创建对象的时候,默认执行无参构造器
注入:
  1. DI:依赖注入,就是注入属性

    set注入(先创建,后注入)
    public class Book {
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Book{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
    

    <bean id="book" class="com.fate.spring5.Book">

        <property name="name" value="差不多得了">

        property>
    bean>
Book book = context.getBean("book", Book.class);
System.out.println(book);
有参构造注入

    <bean id="order" class="com.fate.spring5.Order">
        <constructor-arg name="name" value="默认订单">constructor-arg>
        <constructor-arg name="address" value="默认地址">constructor-arg>
    bean>
public class Order {
    private String name;
    private String address;

    public Order() {
    }
//必须存在有参数构造
    public Order(String name, String address) {
        this.name = name;
        this.address = address;
    }

    @Override
    public String toString() {
        return "Order{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}
@Test
public void order(){
    Order order = context.getBean("order", Order.class);
    System.out.println(order);
}
P名称空间注入(set方法简化):
xmlns:p="http://www.springframework.org/schema/p"

<bean id="bookTest" class="com.fate.spring5.Book" p:name="坂本真绫">bean>
@Test
public void p(){
    Book bookTest = context.getBean("bookTest", Book.class);
    System.out.println(bookTest);
}
xml注入其他类型属性

        <constructor-arg name="address" >
            <null/>
        constructor-arg>
对于特殊字符,可以使用CDATA或转义字符
 <bean id="book" class="com.fate.spring5.Book">

        <property name="name">
        <value>
            >]]>
        value>
        property>
    bean>
外部Bean
  1. 创建两个类

  2. 在service中调用dao的方法

  3. 配置xml

    <bean id="userService" class="com.fate.spring5.service.UserService">
    
            <property name="userDao" ref="userDao"> property>
        bean>
        <bean id="userDao" class="com.fate.spring5.dao.UserDao"> bean>
    
@Test
public void outBean(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
    UserService userService = context.getBean("userService", UserService.class);
    userService.add();
}
内部Bean与级联赋值
  1. 一对多关系:
  2. 实体间的一对多的关系

两种方式

外部赋值

<bean id="emp" class="com.fate.spring5.bean.Emp">
    <property name="name" value="lucy"> property>
    <property name="gender" value=""> property>
    <property name="dept" ref="dept"> property>
bean>

<bean id="dept" class="com.fate.spring5.bean.Dept">
<property name="name" value="xdzn"> property>
bean>

内部赋值,内部类需要get方法

<bean id="emp" class="com.fate.spring5.bean.Emp">
        <property name="name" value="lucy"> property>
        <property name="gender" value=""> property>

        <property name="dept" ref="dept"> property>

        <property name="dept.name" value="519"> property>
    bean>
    <bean id="dept" class="com.fate.spring5.bean.Dept"> bean>
注入集合属性

类型定义

public class Student {
    private String[] courses;

    private List<String> list;

    private Map<String, String> map;

    private Set<String> set;

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

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

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    @Override
    public String toString() {
        return "Student{" +
                "courses=" + Arrays.toString(courses) +
                ", list=" + list +
                ", map=" + map +
                ", set=" + set +
                '}';
    }
}
<bean id="student" class="collectiontype.Student">

    <property name="courses" >
        <array>
            <value>数据结构 value>
            <value>java value>
            <value>python value>
        array>
    property>

        <property name="list">
            <list value-type="java.lang.String">
                <value>高等数学 value>
                <value>离散数学value>
            list>
        property>

        <property name="map">
            <map value-type="java.lang.String" key-type="java.lang.String">
                <entry key="1" value="通用英语"> entry>
                <entry key="2" value="大学物理"> entry>
            map>
        property>
        <property name="set">
            <set value-type="java.lang.String">
                <value>value>
                <value> 狠狠的寄value>
                <value> 寄麻了value>
            set>
        property>
    bean>

提取list进行注入


<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">

<bean id="teacher" class="collectiontype.Teacher">
    <property name="list" ref="list"> property>
bean>
<util:list id="list">
    <value> 1value>
    <value> 12value>
    <value> 134value>
    <value> 1234value>
    <value> 1111value>
util:list>
beans>
IOC操作Bean管理(FactoryBean)
  1. spring中有两种bean(普通bean,工厂bean)
  2. 普通bean:bean标签里定义什么类型,返回什么类型
  3. 工厂bean:定义类型与返回类型可以不同
<bean id="myBean" class="factoryBean.Mybean"> bean>
public class Mybean implements FactoryBean<Courses> {
    @Override
    public Courses getObject() throws Exception {
        Courses courses = new Courses();
        courses.setName("差不多得了");
        return courses;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }

    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}
@Test
public void test1(){
    ApplicationContext context = new ClassPathXmlApplicationContext("FactoryBeanTest.xml");
    Courses courses = context.getBean("myBean", Courses.class);
    System.out.println(courses);
}
IOC操作Bean管理(作用域)
  1. 在bean中可以设置bean是否是单例

  2. 默认情况下都是单例[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hcFOaZoj-1650025796632)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220321175948260.png)]

  3. 如何设置是否单例

    scope属性:singleton(默认,表示单例)| |prototype:多实例

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VN5C9eL0-1650025796633)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220321180120372.png)]

  4. 区别

    singleton:单例,prototype多实例

    当scope为singleton时,加载配置文件时就会创建实例对象,如果是prototype,在调用getBean时才会创建

  5. 其他属性

    request:放在request域中

    session:放在session域中

IOC操作Bean管理(生命周期)
  1. 创建:通过构造器创建bean实例
  2. 属性注入,引用其他bean
  3. 调用bean的初始化方法,需要配置
  4. bean可使用(对象获取成功)
  5. 当容器关闭的时候,调用bean的销毁方法(需要配置)

演示



    <bean id="orders" class="beanlife.Orders" init-method="init" destroy-method="destroy">
    <property name="name" value="我不知道哇"> property>
    bean>
public class Orders {
    private String name;

    public Orders() {
        System.out.println("对象创建了");
    }

    public void setName(String name) {
        System.out.println("调用set方法");
        this.name = name;
    }
    public void init(){
        System.out.println("初始化方法");
    }

    public void destroy(){
        System.out.println("销毁方法");
    }
}
@Test
public void test1(){
    ApplicationContext context = new ClassPathXmlApplicationContext("beanlifeTest.xml");
    Orders orders = context.getBean("orders", Orders.class);
    System.out.println("获取到对象:"+orders);
    //销毁
    ((ClassPathXmlApplicationContext)context).close();
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Fq8d0Fm-1650025796633)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220322081355772.png)]

其他(bean的后置处理器,总计七步)

  1. 创建:通过构造器创建bean实例
  2. 属性注入,引用其他bean
  3. 把备案实例传递给bean的后置处理器的方法(postProcessBeforeInitialization)
  4. 调用bean的初始化方法,需要配置
  5. 把备案实例传递给bean的后置处理器另一个方法(postProcessAfterInitialization)
  6. bean可使用(对象获取成功)
  7. 当容器关闭的时候,调用bean的销毁方法(需要配置)

    <bean id="myBeanPost" class="beanlife.MyBeanPost"> bean>
public class MyBeanPost implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化之前执行:postProcessBeforeInitialization");
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化之后:postProcessAfterInitialization");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DNEKNeHE-1650025796634)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220322085627828.png)]

IOC操作Bean管理(自动装配)(实际开发一般使用注解)

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

演示


    <bean id="depts" class="autowire.Depts"> bean>
    <bean id="emps" class="autowire.Emps" >
    <property name="depts" ref="depts"> property>
    bean>
IOC操作Bean管理(引入外部属性文件)

直接显式配置数据库信息

  1. 配置德鲁伊连接池
  2. 引入德鲁伊jar包
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">

        <property name="driverClassName" value="com.mysql.jdbc.Driver"> property>
        <property name="url" value="jdbc:mysql://localhost:3306/userDb"> property>
        <property name="username" value="root"> property>
        <property name="password" value="mzf200314"> property>
    bean>

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

<context:property-placeholder location="jdbc.properties"/>
   <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">

      <property name="driverClassName" value="${prop.driverClassName}"> property>
        <property name="url" value="${prop.url}"> property>
        <property name="username" value="${prop.username}"> property>
        <property name="password" value="${prop.password}"> property>
    bean>

操作Bean管理(注解)

简化xml配置

spring针对bean管理提供了如下注解:
  1. @Component
  2. @Service,业务逻辑层,service层上
  3. @Controller:web层
  4. @Repository:dao层

上述注解功能相同都能创建bean实例,不同的名称只是用于区分程序

基于注解方式实现对象实例创建
  1. 引入aop.jar包

  2. 开启组件扫描

    <context:component-scan base-package="fromZJ"> context:component-scan>
    
  3. 创建类,添加注解

    @Service(value = "userService")
    public class UserService {
    
        public void add(){
            System.out.println("userService add");
        }
    }
    
  4. 组件扫描细节配置

    
        <context:component-scan base-package="fromZJ" use-default-filters="false">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
        context:component-scan>
    
        <context:component-scan base-package="fromZJ">
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"/>
        context:component-scan>
    
    
基于注解方式实现属性注入

提供以下注解实现属性注入

  1. @AutoWired:根据属性类型进行注入

    1. 将service与dao对象都进行创建,并添加创建注解
    2. 定义属性,添加属性注入注解
  2. @Qualifier:根据名称进行注入(需与@AutoWired一起使用–场景:一个接口存在多个实现类)

  3. @Resource:二者皆可(来自javax包,java官方提供,spring不建议使用)

  4. @Value:普通类型注入

完全注解开发
  1. 创建配置类,替代xml
/**
 * Configuration:表示该类为配置类,替代xml配置文件
 * ComponentScan:代替xml开启组件扫描
 * @author m
 */
@Configuration
@ComponentScan(basePackages = {"config","dao","fromZJ"})
public class SpringConfig {
}

3.AOP

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

图解AOP

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N1ubCTnU-1650025796635)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220322210520446.png)]

底层原理

  1. 底层使用动态代理

    两种动态代理:

    有接口:JDK的动态代理;

    ​ 创建接口实现类的代理对象

    无接口:CGLIB动态代理

    ​ 创建当前类子类的代理对象

  2. AOP(JDK动态代理)

    创建Proxy对象,调用newProxyInstance方法,

    三个参数

    类加载器

    代理类实现的接口们

    实现InvocationHandler,创建代理对象,写增强的方法

  3. AOP(术语)

    1. 连接点

      可以被增强的方法

    2. 切入点

      实际真正增强的方法

    3. 通知(增强)

      实际增强的逻辑部分

      多种类型:

      1. 前置通知:@Before
      2. 后置通知(返回通知):@AfterReturning
      3. 环绕通知:@Around
      4. 异常通知:@AfterThrowing
      5. 最终通知:@After
    4. 切面

      是动作,把通知应用到切入过程

AOP操作

I 一般基于AspectJ实现AOP操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yiSrkwc7-1650025796636)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220406193149563.png)]

II 两种方式进行实现

​ xml配置

​ 注解(主要)

III 引入依赖

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KEGuEetX-1650025796636)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220406195029331.png)]

IV 依赖表达式

​ 知道对哪个类里面的哪个方法进行增强

​ 格式:

​ execution([权限修饰符] [返回类型] [全类名] [方法名] ([参数列表]))

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-75JD7JHN-1650025796637)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220406200916976.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fDaFngvH-1650025796638)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220406200949817.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m0IZa0eP-1650025796638)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220406201016627.png)]

AOP操作基于注解

  1. 创建bean

  2. 创建增强类

  3. 进行通知配置

    @Configuration
    @ComponentScan(basePackages = {"AOPANN"})
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    public class Config {
    }
    

    开启注解扫描

    
        <context:component-scan base-package="AOPTEST1"> context:component-scan>
    

    使用注解创建User和UserProxy

    在增强类上增加注解

    xml开启生成代理对象

    
        <aop:aspectj-autoproxy> aop:aspectj-autoproxy>
    
  4. 配置不同类型通知

    在增强类中,在作为通知方法的上面添加通知类注解,使用切入点表达式进行配置

  5. 对切入点进行抽取

@Component
@Aspect
public class UserProxy {
    @Pointcut(value = "execution(* AOPTEST1.User.add(..))")
    public void fuck(){

    }
    @Before(value = "fuck()")
    public void before(){
        System.out.println("before..");
    }
    @After(value = "fuck()")
    public void after(){
        System.out.println("after..");
    }
    @AfterReturning(value = "fuck()")
    public void afterReturning(){
        System.out.println("afterReturning..");
    }
    @AfterThrowing(value = "fuck()")
    public void afterThrowing(){
        System.out.println("afterThrowing..");
    }
    @Around(value = "fuck()")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("before around..");

            proceedingJoinPoint.proceed();

        System.out.println("after around..");
    }

}
  1. 多个增强类,设置优先级

    @Order(1)
    

4.jdbctemplate

**概念: **Spring对jdbc进行了封装,方便对数据库的准备操作:

  1. 依赖引入
  2. 配置连接池对象
  3. 配置jdbcTemplate

jdbctemplate数据库操作

  1. 创建实体类
  2. 编写service和dao

批量操作(batchUpdate)

5.事物管理

事务:事务是数据库操作的最基本单元,逻辑上一组操作,要么都成功,要么都失败

原子性(Atomicity):要么都成功,要么都失败

一致性(Consistency):事务前后数据完整性要保证一致

隔离性(Isolation)

隔离性是多个用户并发访问数据库时,数据库为每个用户开启的事务,不能被其他事务的操作数据所干扰,事务之间要相互隔离

持久性(Durability) – 事务提交

  • 事务没有提交,恢复原状

  • 事务提交,持久化到数据库

Spring事务

  1. 通常添加到service层

  2. 两种方式:编程式和声明式

  3. 声明式的两种实现方式:注解,xml配置

  4. 在spring进行事务管理的时候,底层使用了AOP

注解方式实现声明式
  1. 开辟命名空间

    xmlns:tx="http://www.springframework.org/schema/tx"
    
  2. 开启事务注解


    <tx:annotation-driven transaction-manager="manager"/>
  1. 添加注解(可以在方法上,也可以在类上)

    @Transactional
    

事务管理参数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kq8Fbvc8-1650025796639)(C:\Users\m\AppData\Roaming\Typora\typora-user-images\image-20220412081856714.png)]

propagation:事务传播行为

​ 支持当前事务:

  1. REQUIRED(默认):支持使用当前事务,如果当前事务不存在,创建一个新事务。
  2. SUPPORTS:支持使用当前事务,如果当前事务不存在,则不使用事务。
  3. MANDATORY:强制,支持使用当前事务,如果当前事务不存在,则抛出Exception。

不支持当前事务:

  1. REQUIRES_NEW:创建一个新事务,如果当前事务存在,把当前事务挂起。
  2. NOT_SUPPORTED:无事务执行,如果当前事务存在,把当前事务挂起。
  3. NEVER:无事务执行,如果当前有事务则抛出Exception。

其它:

  1. NESTED:嵌套事务,如果当前事务存在,那么在嵌套的事务中执行。如果当前事务不存在,则表现跟REQUIRED一样。

ioslation:事务隔离级别

事务的隔离级别

事务隔离级别 脏读 不可重复读 幻读
读未提交(Read-Uncommitted)
不可重复读(Read-Committed)
可重复读(mysql默认)(Repeatable-Read)
串行化(Serializable)

事务的并发问题

  1. 脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
  2. 不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
  3. 幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

timedout:超时时间

​ 超时就回滚(默认-1不会超时)

readonly:只读

​ 读:查,写:增删改

​ 默认false,可读可写

rollbackFor:回滚

​ 出现哪些异常回滚

noRollbackFor:不回滚

​ 出现哪些异常不回滚

xml方式实现声明式事务管理
  1. 配置事务管理器

    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="manager">
    
  2. 配置通知

    <tx:advice transaction-manager="manager" id="advice">
        <tx:attributes>
            <tx:method name="account*"/>
        tx:attributes>
    tx:advice>
    
  3. 配置切入点和切面

    <aop:config>
        <aop:pointcut id="pt" expression="execution(* com.fate.service.impl.UserServiceImpl.accountMoney(..))"/>
        <aop:advisor advice-ref="advice" id="adv" pointcut-ref="pt"/>
    aop:config>
    
    完全注解开发
    package com.fate.config;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import com.alibaba.druid.pool.DruidDataSourceFactory;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    import javax.sql.DataSource;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    @Configuration //声明配置类
    @ComponentScan(basePackages = "com.fate") //开启组件扫描
    @EnableTransactionManagement //开启事务
    public class TxConfig {
        @Bean
        public DruidDataSource getDruidDataSource() {
            DruidDataSource druidDataSource = null;
            Properties properties = new Properties();
            InputStream inputStream = null;
            try {
                inputStream = TxConfig.class.getClassLoader().getResourceAsStream("jdbc.properties");
                properties.load(inputStream);
                druidDataSource=(DruidDataSource)DruidDataSourceFactory.createDataSource(properties);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return druidDataSource;
        }
        @Bean
        public JdbcTemplate getJdbcTemplate( DruidDataSource druidDataSource){
            JdbcTemplate jdbcTemplate = new JdbcTemplate();
            jdbcTemplate.setDataSource(druidDataSource);
            return jdbcTemplate;
        }
        @Bean
        public DataSourceTransactionManager dataSourceTransactionManager(DruidDataSource druidDataSource){
            DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
            dataSourceTransactionManager.setDataSource(druidDataSource);
            return dataSourceTransactionManager;
        }
    }
    

6.新特性

基于java8,支持jdk9,多不建议使用的类和方法都被删除

自带通用的日志封装*

支持@Nullable注解(表示该位置可以为空)

支持Lambda 表达式

@Test
public void test2(){
    GenericApplicationContext genericApplicationContext = new GenericApplicationContext();
    genericApplicationContext.refresh();
    genericApplicationContext.registerBean(User.class,()->new User());
}

支持JUnit5框架

  1. 引入spring test包

    @SpringJUnitConfig(locations = "classpath:JDBC.xml")
    

SpringWebFlux

后面再补吧

你可能感兴趣的:(spring)