2024.3.23-25@spring框架学习笔记

P127  3:24
  AcccountServiceImpl类中的内容:

package com.powernode.bank.service.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import com.powernode.bank.service.AccountService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service("accountService")
//@Transactional
public class AccountServiceImpl implements AccountService {
    @Resource(name = "accountDao")
    private AccountDao accountDao;


    //控制事务,因为在这个方法中要完成所有的转账业务。
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void transfer(String fromActno, String toActno, double money) {

        //第一步:开启事务

        //第二步:执行核心业务逻辑
        //查询转出账户的余额是否充足
        Account fromAct = accountDao.selectByActno(fromActno);
        if (fromAct.getBalance() < money) {
            throw new RuntimeException("余额不足!!!");
        }

        //余额充足
        Account toAct = accountDao.selectByActno(toActno);

        //将内存中两个对象的余额先修改。
        fromAct.setBalance(fromAct.getBalance() - money);
        toAct.setBalance(toAct.getBalance() + money);

        //数据库更新
        int count = accountDao.update(fromAct);

        //模拟异常
//        String s =null;
//        s.toString();


        count += accountDao.update(toAct);

        if(count != 2){
            throw new RuntimeException("转账失败,联系银行!");
        }

        //第三步:如果执行业务流程过程中,没有异常,提交事务
        //第四步:如果执行业务流程过程中,有异常,回滚事务

        //withdraw();
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void withdraw(){

    }


    @Resource(name = "accountService2")
    private AccountService accountService;

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void save(Account act) {
        //这里调用dao的insert方法。
        accountDao.insert(act);//保存act-003账户

         //创建账户对象
        Account act2 = new Account("act-004",1000.0);
        try{
            accountService.save(act2);//保存act-004账户
        }catch (Exception e){

        }

        //继续往后进行我当前1号事务自己的事儿。


    }

}

P128  Spring事务之测试事务隔离级别:
见上集内容
P129  Spring事务之测试事务隔离级别 :

IsolationService1类中的内容:
package com.powernode.bank.service.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

@Service("i1")
public class IsolationService1 {

    @Resource(name = "accountDao")
    public AccountDao accountDao;

    //1号
    //负责查询
    //当前事务可以读取到别的事务没有提交的数据
    //@Transactional(isolation = Isolation.READ_UNCOMMITTED)
    //对方事务提交之后的数据我才能读到。
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void getByActno(String actno){
        Account account = accountDao.selectByActno(actno);
        System.out.println("查询到的账户信息:" + account);
    }

}

IsolationService2类中的内容:
package com.powernode.bank.service.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("i2")
public class IsolationService2 {

    @Resource(name = "accountDao")
    private AccountDao accountDao;

    //2号
    //负责insert
    @Transactional
    public void save(Account act){

        accountDao.insert(act);
        //睡眠一会
        try {
            Thread.sleep(1000 * 20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

测试类中的内容:
@Test
public void testIsolation1(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    IsolationService1 i1 = applicationContext.getBean("i1", IsolationService1.class);
    i1.getByActno("act-004");

}

@Test
public void testIsolation2(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    IsolationService2 i2 = applicationContext.getBean("i2", IsolationService2.class);
    Account act = new Account("act-004",1000.0);
    i2.save(act);

}
P130 Spring事务之事务超时避免踩坑  :

@Transactional(timeout = 10)
以上代码表示设置事务的超时时间为10秒。
表示超过10秒如果该事务中所有的DML语句还没有执行完毕的话,最终结果会选择回滚。
默认值-1,表示没有时间限制。
这里有个坑,事务的超时时间指的是哪段时间?
在当前事务当中,最后一条DML语句执行之前的时间。如果最后一条DML语句后面很有很多业务逻辑,这些业务代码执行的时间不被计入超时时间。
当然,如果想让整个方法的所有代码都计入超时时间的话,可以在方法最后一行添加一行无关紧要的DML语句。
只读事务
代码如下:
@Transactional(readOnly = true)
将当前事务设置为只读事务,在该事务执行过程中只允许select语句执行,delete insert update均不可执行。
该特性的作用是:启动spring的优化策略。提高select语句执行效率。
如果该事务中确实没有增删改操作,建议设置为只读事务。
设置哪些异常回滚事务
代码如下:
@Transactional(rollbackFor = RuntimeException.class)
表示只有发生RuntimeException异常或该异常的子类异常才回滚。
设置哪些异常不回滚事务
代码如下:
@Transactional(noRollbackFor = NullPointerException.class)
表示发生NullPointerException或该异常的子类异常不回滚,其他异常则回滚。


IsolationService2类中的内容:
package com.powernode.bank.service.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("i2")
public class IsolationService2 {

    @Resource(name = "accountDao")
    private AccountDao accountDao;

    //2号
    //负责insert
    @Transactional(timeout = 10)//设置事务超时时间为10秒
    public void save(Account act){

        //睡眠一会
        try {
            Thread.sleep(1000 * 15);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        accountDao.insert(act);


//        //睡眠一会
//        try {
//            Thread.sleep(1000 * 20);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }


        //可以在这里写一个无关紧要的DML语句

    }
}

测试类中的内容:
@Test
public void testIsolation2(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    IsolationService2 i2 = applicationContext.getBean("i2", IsolationService2.class);
    Account act = new Account("act-004",1000.0);
    i2.save(act);

}

P131 Spring事务之只读事务启动优化策略 :
IsolationService2类中的内容:
package com.powernode.bank.service.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("i2")
public class IsolationService2 {

    @Resource(name = "accountDao")
    private AccountDao accountDao;

    //2号
    //负责insert
    @Transactional(readOnly = true, timeout = 10)//设置事务超时时间为10秒
    public void save(Account act){

//        //睡眠一会
//        try {
//            Thread.sleep(1000 * 15);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        accountDao.insert(act);


        //睡眠一会
        try {
            Thread.sleep(1000 * 20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        //可以在这里写一个无关紧要的DML语句

    }
}

测试类中的内容:
@Test
public void testIsolation2(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    IsolationService2 i2 = applicationContext.getBean("i2", IsolationService2.class);
    Account act = new Account("act-004",1000.0);
    i2.save(act);

}

P132  Spring事务之设置遇到哪些异常时回滚:
IsolationService2类中的内容:
package com.powernode.bank.service.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;

@Service("i2")
public class IsolationService2 {

    @Resource(name = "accountDao")
    private AccountDao accountDao;

    //2号
    //负责insert
    //@Transactional(readOnly = true, timeout = 10)//设置事务超时时间为10秒
    @Transactional(rollbackFor = RuntimeException.class)//只要发生RuntimeException或者这个异常的子类异常,都回滚
    public void save(Account act) throws IOException {

//        //睡眠一会
//        try {
//            Thread.sleep(1000 * 15);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        accountDao.insert(act);

        //模拟异常
        if(1 == 1){
//            throw new IOException();
            throw new RuntimeException();
        }


        //睡眠一会
        try {
            Thread.sleep(1000 * 20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        //可以在这里写一个无关紧要的DML语句

    }
}


测试类中的内容:
@Test
public void testIsolation2() throws IOException {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    IsolationService2 i2 = applicationContext.getBean("i2", IsolationService2.class);
    Account act = new Account("act-004",1000.0);
    i2.save(act);

}

P133 Spring事务之设置遇到哪些异常不回滚 :
IsolationService2类中的内容:
package com.powernode.bank.service.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;

@Service("i2")
public class IsolationService2 {

    @Resource(name = "accountDao")
    private AccountDao accountDao;

    //2号
    //负责insert
    //@Transactional(readOnly = true, timeout = 10)//设置事务超时时间为10秒
    //@Transactional(rollbackFor = RuntimeException.class)//只要发生RuntimeException或者这个异常的子类异常,都回滚
    @Transactional(noRollbackFor = NullPointerException.class) //当异常是空指针异常的时候不回滚。
    public void save(Account act) throws IOException {

//        //睡眠一会
//        try {
//            Thread.sleep(1000 * 15);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        accountDao.insert(act);

        //模拟异常
        if(1 == 1){
//            throw new IOException();
            throw new RuntimeException();
            //throw new NullPointerException();
        }


        //睡眠一会
        try {
            Thread.sleep(1000 * 20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        //可以在这里写一个无关紧要的DML语句

    }
}

测试类与上集相同

P134  Spring事务之全注解式开发:
time:1.5H
Spring6Config类中的内容:
package com.powernode.bank;

import com.alibaba.druid.pool.DruidDataSource;
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;

@Configuration   //代替spring.xml配置文件,在这个类当中完成配置。
@ComponentScan("com.powernode.bank")
@EnableTransactionManagement //开启事务注解
public class Spring6Config {

    //Spring框架,看到这个@Bean注解后,会调用这个被标注的方法,这个方法的返回值是一个java对象,这个java对象会自动纳入IoC容器管理。
    //返回的对象就是Spring容器当中的一个Bean了。
    //并且这个bean的名字是:dataSource
    @Bean(name  = "dataSource")
    public DruidDataSource getDataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/spring6");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        return dataSource;
    }
    @Bean(name  = "jdbcTemplate")
    public JdbcTemplate getJdbcTemplate(DataSource dataSource){//Spring在调用这个方法的时候会自动给我们传递过来一个dataSource对象。
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }
    @Bean(name  = "txManager")
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){
        DataSourceTransactionManager txManager = new DataSourceTransactionManager();
        txManager.setDataSource(dataSource);
        return txManager;

    }

}

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

    <!--组件扫描 -->
    <context:component-scan base-package="com.powernode.bank" />


    <!--配置数据源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" >
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/spring6"/>
        <property name="username" value="root" />
        <property name="password" value="123456" />
    </bean>

    <!--配置JdbcTemplate -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!--配置事务管理器 -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!--开启事务注解驱动器,开启事务注解。告诉Spring框架,采用注解的方式去控制事务。 -->
    <tx:annotation-driven transaction-manager="txManager" />

</beans>
测试类中的内容:
@Test
public void testNoXML(){
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Spring6Config.class);
    AccountService accountService = applicationContext.getBean("accountService", AccountService.class);
    try{
        accountService.transfer("act-001","act-002",10000);
        System.out.println("转账成功");
    }catch(Exception e){
        e.printStackTrace();
    }

}
其它内容略
P135 spring事务之声明式事务XML实现方式  :
声明式事务之XML实现方式
配置步骤:
● 第一步:配置事务管理器
● 第二步:配置通知
● 第三步:配置切面
记得添加aspectj的依赖:
<!--aspectj依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>6.0.0-M2</version>
</dependency>

Spring配置文件如下:
记得添加aop的命名空间。

AccountDao接口中的内容:
package com.powernode.bank.dao;

import com.powernode.bank.pojo.Account;

/**
 * 专门负责账号信息的CRUD操作。
 * DAO中只执行SQL语句,没有任何业务逻辑。
 * 也就是说DAO不和业务挂钩。
 */
public interface AccountDao {
    /**
     * 根据账号查询账户信息
     * @param actno
     * @return
     */
    Account selectByActno(String actno);

    /**
     * 更新账户信息。
     * @param act
     * @return
     */
    int update(Account act);

}

AccountDaoImpl类中的内容:
package com.powernode.bank.dao.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import jakarta.annotation.Resource;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {

    @Resource(name = "jdbcTemplate")
    private JdbcTemplate jdbcTemplate;

    @Override
    public Account selectByActno(String actno) {
        String sql = "select actno, balance from t_act where actno = ?";
        Account account = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(Account.class), actno);

        return account;
    }

    @Override
    public int update(Account act) {
        String sql = "update t_act set balance = ? where actno = ?";
        int count = jdbcTemplate.update(sql, act.getBalance(), act.getActno());
        return count;
    }


}


Account类中的内容:
package com.powernode.bank.pojo;

/**
 * 银行账号类
 */
public class Account {
    private String actno;
    private Double balance;

    public Account() {
    }

    public Account(String actno, Double balance) {
        this.actno = actno;
        this.balance = balance;
    }

    public String getActno() {
        return actno;
    }

    public void setActno(String actno) {
        this.actno = actno;
    }

    public Double getBalance() {
        return balance;
    }

    public void setBalance(Double balance) {
        this.balance = balance;
    }

    @Override
    public String toString() {
        return "Account{" +
                "actno='" + actno + '\'' +
                ", balance=" + balance +
                '}';
    }
}

AccountService接口中的内容:
package com.powernode.bank.service;

import com.powernode.bank.pojo.Account;

/**
 * 业务接口
 * 事务就是在这个接口下控制的。
 */
public interface AccountService {
    /**
     * 转账业务方法
     * @param fromActno  从这个账户转出
     * @param toActno   转入这个账号
     * @param money //转账金额
     */
    void transfer(String fromActno,String toActno, double money);

}

AccountServiceImpl类中的内容:
package com.powernode.bank.service.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import com.powernode.bank.service.AccountService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service("accountService")
public class AccountServiceImpl implements AccountService {
    @Resource(name = "accountDao")
    private AccountDao accountDao;


    //控制事务,因为在这个方法中要完成所有的转账业务。
    @Override
    public void transfer(String fromActno, String toActno, double money) {

        //第一步:开启事务

        //第二步:执行核心业务逻辑
        //查询转出账户的余额是否充足
        Account fromAct = accountDao.selectByActno(fromActno);
        if (fromAct.getBalance() < money) {
            throw new RuntimeException("余额不足!!!");
        }

        //余额充足
        Account toAct = accountDao.selectByActno(toActno);

        //将内存中两个对象的余额先修改。
        fromAct.setBalance(fromAct.getBalance() - money);
        toAct.setBalance(toAct.getBalance() + money);

        //数据库更新
        int count = accountDao.update(fromAct);

        //模拟异常
//        String s =null;
//        s.toString();


        count += accountDao.update(toAct);

        if(count != 2){
            throw new RuntimeException("转账失败,联系银行!");
        }

        //第三步:如果执行业务流程过程中,没有异常,提交事务
        //第四步:如果执行业务流程过程中,有异常,回滚事务

    }

    }

spring配置文件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"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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/tx http://www.springframework.org/schema/tx/spring-tx.xsd
                      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--组件扫描 -->
    <context:component-scan base-package="com.powernode.bank" />


    <!--配置数据源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" >
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/spring6"/>
        <property name="username" value="root" />
        <property name="password" value="123456" />
    </bean>

    <!--配置JdbcTemplate -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!--配置事务管理器 -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

        <!--配置通知 ,具体的增强代码。-->
        <!--注意:在通知当中要关联事务管理器。 -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <!--配置通知的相关属性 -->
        <tx:attributes>
            <!--之前所讲的所有的事务属性都可以在以下标签中配置。 -->
            <tx:method name="transfer" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="modify*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="query*" read-only="true"/>
            <tx:method name="select*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="get*" read-only="true"/>


        </tx:attributes>
    </tx:advice>

        <!--配置切面 -->
    <aop:config>
        <!--切点 -->
        <aop:pointcut id="txPointcut" expression="execution(* com.powernode.bank.service..*(..))"/>
        <!--切面 = 通知 + 切点 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
    </aop:config>

</beans>
测试类中的内容:

@Test
public void testNoAnnotation(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    AccountService accountService = applicationContext.getBean("accountService", AccountService.class);
    try{
        accountService.transfer("act-001","act-002",10000.0);
        System.out.println("转账成功");
    }catch (Exception e){
        e.printStackTrace();
    }


}


P136  Spring框架对JUnit4的支持:
十七、Spring6整合JUnit5
17.1 Spring对JUnit4的支持

Spring提供的方便主要是这几个注解:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring.xml")
在单元测试类上使用这两个注解之后,在单元测试类中的属性上可以使用@Autowired。比较方便。

juint:
spring支持junit4的文件依赖:
<?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>org.example</groupId>
    <artifactId>spring6-015-junit</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <!--仓库-->
    <repositories>
        <!--spring里程碑版本的仓库-->
        <repository>
            <id>repository.spring.milestone</id>
            <name>Spring Milestone Repository</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>

    <dependencies>
        <!--Spring context依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.0-M2</version>
        </dependency>
        <!--spring对junit支持的依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <!--这个版本spring6,既支持JUnit4又支持JUnit5. -->
            <version>6.0.0-M2</version>
        </dependency>

        <!--junit4依赖 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

    </dependencies>


    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

</project>
依赖文件:
<?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>org.example</groupId>
    <artifactId>spring6-015-junit</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <!--仓库-->
    <repositories>
        <!--spring里程碑版本的仓库-->
        <repository>
            <id>repository.spring.milestone</id>
            <name>Spring Milestone Repository</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>

    <dependencies>
        <!--Spring context依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.0-M2</version>
        </dependency>
        <!--spring对junit支持的依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <!--这个版本spring6,既支持JUnit4又支持JUnit5. -->
            <version>6.0.0-M2</version>
        </dependency>

        <!--junit4依赖 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

    </dependencies>


    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

</project>
spring配置文件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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

        <context:component-scan base-package="com.powernode.spring6.bean" />

</beans>
User类中的内容:
package com.powernode.spring6.bean;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class User {
    @Value("张三")
    private String name;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public User() {
    }

    public User(String name) {
        this.name = name;
    }
}

测试类中的内容:
package com.powernode.spring6.test;

import com.powernode.spring6.bean.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring.xml")
public class SpringJUnit4Test {
    @Autowired
    private User user;

    @Test
    public void testUser(){
//        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
//        User user = applicationContext.getBean("user", User.class);
        System.out.println(user.getName());
    }

    @Test
    public void testUser2(){
//        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
//        User user = applicationContext.getBean("user", User.class);
        System.out.println(user.getName());
    }

    @Test
    public void testUser3(){
//        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
//        User user = applicationContext.getBean("user", User.class);
        System.out.println(user.getName());
    }
}

P137 spring框架对JUnit5的支持:
17.2 Spring对JUnit5的支持
引入JUnit5的依赖,Spring对JUnit支持的依赖还是:spring-test,如下:
<!--junit5依赖-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.0</version>
<scope>test</scope>
</dependency>

依赖文件pom:
<?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>org.example</groupId>
    <artifactId>spring6-015-junit</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <!--仓库-->
    <repositories>
        <!--spring里程碑版本的仓库-->
        <repository>
            <id>repository.spring.milestone</id>
            <name>Spring Milestone Repository</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>

    <dependencies>
        <!--Spring context依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.0-M2</version>
        </dependency>
        <!--spring对junit支持的依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <!--这个版本spring6,既支持JUnit4又支持JUnit5. -->
            <version>6.0.0-M2</version>
        </dependency>

        <!--junit4依赖 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

        <!--junit5依赖-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.9.0</version>
            <scope>test</scope>
        </dependency>

    </dependencies>


    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

</project>
spring配置文件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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

        <context:component-scan base-package="com.powernode.spring6.bean" />

</beans>

User类中的内容:
package com.powernode.spring6.bean;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class User {
    @Value("张三")
    private String name;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public User() {
    }

    public User(String name) {
        this.name = name;
    }
}

测试类中的内容:
package com.powernode.spring6.test;

import com.powernode.spring6.bean.User;
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:spring.xml")
public class SpringJUnit5Test {

    @Autowired
    private User user;
    @Test
    public void testUser(){
        System.out.println(user.getName());
    }

}


p138 -p145 略:要学习mybatis框架
P146 在Spring主配置文件中引入子配置文件 :
引入其它配置文件:
<import resource = "common.xml" />

p147  spring框架的八大设计模式:
十九、Spring中的八大模式
19.1 简单工厂模式
BeanFactory的getBean()方法,通过唯一标识来获取Bean对象。是典型的简单工厂模式(静态工厂模式);
19.2 工厂方法模式
FactoryBean是典型的工厂方法模式。在配置文件中通过factory-method属性来指定工厂方法,该方法是一个实例方法。
19.3 单例模式
Spring用的是双重判断加锁的单例模式。请看下面代码,我们之前讲解Bean的循环依赖的时候见过:
19.4 代理模式
Spring的AOP就是使用了动态代理实现的。
19.5 装饰器模式
JavaSE中的IO流是非常典型的装饰器模式。
Spring 中配置 DataSource 的时候,这些dataSource可能是各种不同类型的,比如不同的数据库:Oracle、SQL Server、MySQL等,也可能是不同的数据源:比如apache 提供的org.apache.commons.dbcp.BasicDataSource、spring提供的org.springframework.jndi.JndiObjectFactoryBean等。
这时,能否在尽可能少修改原有类代码下的情况下,做到动态切换不同的数据源?此时就可以用到装饰者模式。
Spring根据每次请求的不同,将dataSource属性设置成不同的数据源,以到达切换数据源的目的。
Spring中类名中带有:Decorator和Wrapper单词的类,都是装饰器模式。
19.6 观察者模式
定义对象间的一对多的关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。Spring中观察者模式一般用在listener的实现。
Spring中的事件编程模型就是观察者模式的实现。在Spring中定义了一个ApplicationListener接口,用来监听Application的事件,Application其实就是ApplicationContext,ApplicationContext内置了几个事件,其中比较容易理解的是:ContextRefreshedEvent、ContextStartedEvent、ContextStoppedEvent、ContextClosedEvent
19.7 策略模式
策略模式是行为性模式,调用不同的方法,适应行为的变化 ,强调父类的调用子类的特性 。
getHandler是HandlerMapping接口中的唯一方法,用于根据请求找到匹配的处理器。
比如我们自己写了AccountDao接口,然后这个接口下有不同的实现类:AccountDaoForMySQL,AccountDaoForOracle。对于service来说不需要关心底层具体的实现,只需要面向AccountDao接口调用,底层可以灵活切换实现,这就是策略模式。
19.8 模板方法模式
Spring中的JdbcTemplate类就是一个模板类。它就是一个模板方法设计模式的体现。在模板类的模板方法execute中编写核心算法,具体的实现步骤在子类中完成。

spring MVC
p148  END
time:2.5h+1.5h(前天)

视频网址:
https://www.bilibili.com/video/BV1Ft4y1g7Fb?p=148&vd_source=ff898217e3612fcbdefecfdc49657ab1

springMVC


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值