Spring-全面详解(学习总结---从入门到深化)(下)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: AOP有以下几种常用的通知类型

SpringAOP_通知类型

2345_image_file_copy_208.jpg

AOP有以下几种常用的通知类型:

2345_image_file_copy_209.jpg

1、编写通知方法

// 通知类
public class MyAspectAdvice {
    // 后置通知
    public void myAfterReturning(JoinPoint joinPoint) {
        System.out.println("切点方法名:" + joinPoint.getSignature().getName());
        System.out.println("目标对象:" + joinPoint.getTarget());
        System.out.println("打印日志" + joinPoint.getSignature().getName() + "方法被执行了!");
   }
    // 前置通知
    public void myBefore() {
        System.out.println("前置通知...");
   }
    // 异常通知
    public void myAfterThrowing(Exception ex) {
        System.out.println("异常通知...");
        System.err.println(ex.getMessage());
   }
    // 最终通知
    public void myAfter() {
        System.out.println("最终通知");
   }
    // 环绕通知
    public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕前");
        Object obj = proceedingJoinPoint.proceed(); // 执行方法
        System.out.println("环绕后");
        return obj;
   }
}

2、配置切面

<!-- 配置AOP -->
<aop:config>
    <!-- 配置切面 -->
    <aop:aspect ref="myAspectJAdvice">
        <!-- 配置切点 -->
        <aop:pointcut id="myPointcut" expression="execution(* com.itbaizhan.dao.UserDao.*(..))"/>
        <!-- 前置通知 -->
        <aop:before method="myBefore" pointcut-ref="myPointcut"></aop:before>
        <!-- 后置通知 -->
        <aop:after-returning method="myAfterReturning" pointcutref="myPointcut"/>
        <!-- 异常通知 -->
        <aop:after-throwing method="myAfterThrowing" pointcutref="myPointcut" throwing="ex"/>
        <!-- 最终通知 -->
        <aop:after method="myAfter" pointcut-ref="myPointcut"></aop:after>
        <!-- 环绕通知 -->
        <aop:around method="myAround" pointcut-ref="myPointcut"></aop:around>
    </aop:aspect>
</aop:config>

SpringAOP_切点表达式

2345_image_file_copy_210.jpg

使用AspectJ需要使用切点表达式配置切点位置,写法如下:

1、标准写法:访问修饰符 返回值 包名.类名.方法名(参数列表)

2、访问修饰符可以省略。

3、返回值使用 * 代表任意类型。

4、包名使用 * 表示任意包,多级包结构要写多个 * ,使用 *.. 表示任 意包结构

5、类名和方法名都可以用 * 实现通配。

6、参数列表

基本数据类型直接写类型
引用类型写 包名.类名
* 表示匹配一个任意类型参数
.. 表示匹配任意类型任意个数的参数

7、全通配: * *..*.*(..)

SpringAOP_多切面配置

2345_image_file_copy_211.jpg

我们可以为切点配置多个通知,形成多切面,比如希望dao层的每 个方法结束后都可以打印日志并发送邮件:

1、编写发送邮件的通知:

public class MyAspectJAdvice2 {
    // 后置通知
    public void myAfterReturning(JoinPoint joinPoint) {
        System.out.println("发送邮件");
   }
}

2、配置切面:

<!-- 通知对象 -->
<bean id="myAspectJAdvice" class="com.itbaizhan.advice.MyAspectAdvice"></bean>
<bean id="myAspectJAdvice2" class="com.itbaizhan.advice.MyAspectAdvice2"></bean>
<!-- 配置AOP -->
<aop:config>
    <!-- 配置切面 -->
    <aop:aspect ref="myAspectJAdvice">
        <!-- 配置切点 -->
        <aop:pointcut id="myPointcut" expression="execution(* *..*.*(..))"/>
        <!-- 后置通知 -->
        <aop:after-returning method="myAfterReturning" pointcutref="myPointcut"/>
    </aop:aspect>
    <aop:aspect ref="myAspectJAdvice2">
        <aop:pointcut id="myPointcut2" expression="execution(*com.itbaizhan.dao.UserDao.*(..))"/>
        <aop:after-returning method="myAfterReturning" pointcut-ref="myPointcut2"/>
    </aop:aspect>
</aop:config>

SpringAOP_注解配置AOP

Spring可以使用注解代替配置文件配置切面:

1、在xml中开启AOP注解支持

<!-- 开启注解配置Aop -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

2、在通知类上方加入注解 @Aspect

3、在通知方法上方加入注解

@Before/@AfterReturning/@AfterThrowing/@After/@Around
@Aspect
@Component
public class MyAspectAdvice {
    // 后置通知
    @AfterReturning("execution(* com.itbaizhan.dao.UserDao.*(..))")
    public void myAfterReturning(JoinPoint joinPoint) {
        System.out.println("切点方法名:" + joinPoint.getSignature().getName());
        System.out.println("目标对象:" + joinPoint.getTarget());
        System.out.println("打印日志" + joinPoint.getSignature().getName() + "方法被执行了!");
   }
    // 前置通知
    @Before("execution(* com.itbaizhan.dao.UserDao.*(..))")
    public void myBefore() {
        System.out.println("前置通知...");
   }
    // 异常通知
    @AfterThrowing(value = "execution(* com.itbaizhan.dao.UserDao.*(..))",throwing = "ex")
    public void myAfterThrowing(Exception ex) {
        System.out.println("异常通知...");
        System.err.println(ex.getMessage());
   }
    // 最终通知
    @After("execution(* com.itbaizhan.dao.UserDao.*(..))")
    public void myAfter() {
        System.out.println("最终通知");
   }
    // 环绕通知
    @Around("execution(* com.itbaizhan.dao.UserDao.*(..))")
    public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕前");
        Object obj = proceedingJoinPoint.proceed(); // 执行方法
        System.out.println("环绕后");
        return obj;
   }
}

4、测试:

@Test
public void testAdd2(){
    ApplicationContext ac = new ClassPathXmlApplicationContext("bean1.xml");
    UserDao userDao = (UserDao) ac.getBean("userDao");
    userDao.update();
}

如何为一个类下的所有方法统一配置切点:

1、在通知类中添加方法配置切点

@Pointcut("execution(* com.itbaizhan.dao.UserDao.*(..))")
public void pointCut(){}

2、在通知方法上使用定义好的切点

@Before("pointCut()")
public void myBefore(JoinPoint joinPoint) {
    System.out.println("前置通知...");
}
@AfterReturning("pointCut()")
public void myAfterReturning(JoinPoint joinPoint) {
    System.out.println("后置通知...");
}

配置类如何代替xml中AOP注解支持?

在配置类上方添加@EnableAspectJAutoProxy即可

@Configuration
@ComponentScan("com.itbaizhan")
@EnableAspectJAutoProxy
public class SpringConfig {
}

SpringAOP_原生Spring实现AOP

2345_image_file_copy_212.jpg

除了AspectJ,Spring支持原生方式实现AOP。

1、引入依赖

<!-- AOP -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.3.13</version>
</dependency>

2、编写通知类

// Spring原生Aop的通知类
public class SpringAop implements MethodBeforeAdvice, AfterReturningAdvice,
ThrowsAdvice, MethodInterceptor {
    /**
     * 前置通知
     * @param method 目标方法
     * @param args 目标方法的参数列表
     * @param target 目标对象
     * @throws Throwable
     */
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("前置通知");
     }
    /**
     * 后置通知
     * @param returnValue 目标方法的返回值
     * @param method 目标方法
     * @param args 目标方法的参数列表
     * @param target 目标对象
     * @throws Throwable
     */
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("后置通知");
   }
    /**
     * 环绕通知
     * @param invocation 目标方法
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("环绕前");
        Object proceed = invocation.proceed();
        System.out.println("环绕后");
        return proceed;
   }
    /**
     * 异常通知
     * @param ex 异常对象
     */
    public void afterThrowing(Exception ex){
        System.out.println("发生异常了!");
    }
}

Spring原生方式实现AOP时,只支持四种通知类型:

2345_image_file_copy_213.jpg

3、编写配置类

<!-- 通知对象 -->
<bean id="springAop" class="com.itbaizhan.advice.SpringAop"></bean>
<!-- 配置代理对象 -->
<bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <!-- 配置目标对象 -->
    <property name="target" ref="userDao"></property>
    <!-- 配置通知 -->
    <property name="interceptorNames">
        <list>
            <value>springAop</value>
        </list>
    </property>
    <!-- 代理对象的生成方式 true:使用CGLib false:使用原生JDK生成-->
    <property name="proxyTargetClass" value="true"></property>
</bean>

4、编写测试类

public class UserDaoTest2 {
    @Test
    public void testAdd(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean2.xml");
        UserDao userDao = (UserDao) ac.getBean("userDaoProxy"); // 获取的是代理对象
        userDao.update();
   }
}

SpringAOP_SchemaBased实现AOP

SchemaBased(基础模式)配置方式是指使用Spring原生方式定义通 知,而使用AspectJ框架配置切面。

1、编写通知类

public class SpringAop implements MethodBeforeAdvice, AfterReturningAdvice,ThrowsAdvice, MethodInterceptor {
    /**
     * 前置通知
     * @param method 目标方法
     * @param args 目标方法的参数列表
     * @param target 目标对象
     * @throws Throwable
     */
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("前置通知");
     }
    /**
     * 后置通知
     * @param returnValue 目标方法的返回值
     * @param method 目标方法
     * @param args 目标方法的参数列表
     * @param target 目标对象
     * @throws Throwable
     */
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("后置通知");
   }
    /**
     * 环绕通知
     * @param invocation 目标方法
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("环绕前");
        Object proceed = invocation.proceed();
        System.out.println("环绕后");
        return proceed;
   }
    /**
     * 异常通知
     * @param ex 异常对象
     */
    public void afterThrowing(Exception ex){
        System.out.println("发生异常了!");
   }
}

2、配置切面

<!-- 通知对象 -->
<bean id="springAop2" class="com.itbaizhan.aop.SpringAop2"/>
<!-- 配置切面 -->
<aop:config>
    <!-- 配置切点-->
    <aop:pointcut id="myPointcut" expression="execution(* com.itbaizhan.dao.UserDao.*(..))"/>
    <!-- 配置切面:advice-ref:通知对象 pointcut-ref:切点 -->
    <aop:advisor advice-ref="springAop2" pointcut-ref="myPointcut"/>
</aop:config>

3、测试

@Test
public void t6(){
    ApplicationContext ac = new ClassPathXmlApplicationContext("aop3.xml");
    UserDao userDao = (UserDao) ac.getBean("userDao");
    userDao.add();
}

Spring事务_事务简介

事务:不可分割的原子操作。即一系列的操作要么同时成功,要么同时失败。

开发过程中,事务管理一般在service层,service层中可能会操作多次数据库,这些操作是不可分割的。否则当程序报错时,可能会造 成数据异常。

如:张三给李四转账时,需要两次操作数据库:张三存款减少、李四存款增加。如果这两次数据库操作间出现异常,则会造成数据错 误。

1、准备数据库

CREATE DATABASE `spring` ;
USE `spring`;
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  `balance` double DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT
CHARSET=utf8;
insert  into `account`(`id`,`username`,`balance`) values (1,'张三',1000),(2,'李四',1000);

2、创建maven项目,引入依赖

<dependencies>
    <!-- mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
   <!-- mysql驱动包 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connectorjava</artifactId>
        <version>8.0.26</version>
    </dependency>
    <!-- druid连接池 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.2.8</version>
    </dependency>
    <!-- spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>springcontext</artifactId>
        <version>5.3.13</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>5.3.13</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>springjdbc</artifactId>
        <version>5.3.13</version>
    </dependency>
    <!-- MyBatis与Spring的整合包,该包可以让Spring创建MyBatis的对象 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatisspring</artifactId>
        <version>2.0.6</version>
    </dependency>
    <!-- junit,如果Spring5整合junit,则junit版本至少在4.12以上 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <!-- spring整合测试模块 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>springtest</artifactId>
        <version>5.3.13</version>
        <scope>test</scope>
    </dependency>
</dependencies>

3、创建配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:context="http://www.springframework.org/schema/context"
      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
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 包扫描 -->
    <context:component-scan basepackage="com.itbaizhan"></context:component-scan>
    <!-- 创建druid数据源对象 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql:///spring"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.itbaizhan.dao"></property>
    </bean>
</beans>

4、编写Java代码

// 账户
public class Account {
    private int id; // 账号
    private String username; // 用户名
    private double balance; // 余额
    // 省略getter/setter/tostring/构造方法
}
@Repository
public interface AccountDao {
    // 根据id查找用户
    @Select("select * from account where id = #{id}")
    Account findById(int id);
    // 修改用户
    @Update("update account set balance = #{balance} where id = #{id}")
    void update(Account account);
}
@Service
public class AccountService {
    @Autowired
    private AccountDao accountDao;
    /**
     * 转账
     * @param id1 转出人id
     * @param id2 转入人id
     * @param price 金额
     */
    public void transfer(int id1, int id2, double price) {
        // 转出人减少余额
        Account account1 = accountDao.findById(id1);
        account1.setBalance(account1.getBalance()-price);
        accountDao.update(account1);
        int i = 1/0; // 模拟程序出错
        // 转入人增加余额
        Account account2 = accountDao.findById(id2);
        account2.setBalance(account2.getBalance()+price);
        accountDao.update(account2);
   }
}

5、测试转账

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath :applicationContext.xml")
public class AccountServiceTest {
    @Autowired
    private AccountService accountService;
    @Test
    public void testTransfer(){
        accountService.transfer(1,2,500);
   }
}

此时没有事务管理,会造成张三的余额减少,而李四的余额并没有 增加。所以事务处理位于业务层,即一个service方法是不能分割的。

Spring事务_Spring事务管理方案

2345_image_file_copy_214.jpg

在service层手动添加事务可以解决该问题:

@Autowired
private SqlSessionTemplate sqlSession;
public void transfer(int id1, int id2,double price) {
    try{
        // account1修改余额
        Account account1 = accountDao.findById(id1);
        account1.setBalance(account1.getBalance()- price);
        accountDao.update(account1);
        int i = 1/0; // 模拟转账出错
        // account2修改余额
        Account account2 = accountDao.findById(id2);
        account2.setBalance(account2.getBalance()+price);
        accountDao.update(account2);  
        sqlSession.commit();
     }catch(Exception ex){
        sqlSession.rollback();
   }
}

但在Spring管理下不允许手动提交和回滚事务。此时我们需要使用 Spring的事务管理方案,在Spring框架中提供了两种事务管理方案:

1 编程式事务:通过编写代码实现事务管理。

2 声明式事务:基于AOP技术实现事务管理。

在Spring框架中,编程式事务管理很少使用,我们对声明式事务管 理进行详细学习。 Spring的声明式事务管理在底层采用了AOP技术,其最大的优点在 于无需通过编程的方式管理事务,只需要在配置文件中进行相关的 规则声明,就可以将事务规则应用到业务逻辑中。

使用AOP技术为service方法添加如下通知:

2345_image_file_copy_215.jpg

Spring事务_Spring事务管理器

2345_image_file_copy_216.jpg

Spring依赖事务管理器进行事务管理,事务管理器即一个通知类, 我们为该通知类设置切点为service层方法即可完成事务自动管理。 由于不同技术操作数据库,进行事务操作的方法不同。如:JDBC提 交事务是 connection.commit() ,MyBatis提交事务是 sqlSession.commit() ,所以 Spring提供了多个事务管理器。

image.jpeg

我们使用MyBatis操作数据库,接下来使用 DataSourceTransactionManager 进行事务管理。

1、引入依赖

<!-- 事务管理 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.3.13</version>
</dependency>
<!-- AspectJ -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.7</version>
</dependency>

2、在配置文件中引入约束

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

3、进行事务配置

<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 进行事务相关配置 -->
<tx:advice id = "txAdvice">
    <tx:attributes>
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>
<!-- 配置切面 -->
<aop:config>
    <!-- 配置切点 -->
    <aop:pointcut id="pointcut" expression="execution(* com.itbaizhan.service.*.*(..))"/>
    <!-- 配置通知 -->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"></aop:advisor>
</aop:config>

Spring事务_事务控制的API

2345_image_file_copy_219.jpg

Spring进行事务控制的功能是由三个接口提供的,这三个接口是 Spring实现的,在开发中我们很少使用到,只需要了解他们的作用 即可:

PlatformTransactionManager接口

PlatformTransactionManager是Spring提供的事务管理器接口,所 有事务管理器都实现了该接口。该接口中提供了三个事务操作方法:

1、TransactionStatus getTransaction(TransactionDefinition definition):获取事务状态信息。

2、void commit(TransactionStatus status):事务提交

3、void rollback(TransactionStatus status):事务回滚

TransactionDefinition接口

TransactionDefinition是事务的定义信息对象,它有如下方法:

String getName():获取事务对象名称。

int getIsolationLevel():获取事务的隔离级别。

int getPropagationBehavior():获取事务的传播行为。

int getTimeout():获取事务的超时时间。

boolean isReadOnly():获取事务是否只读。

TransactionStatus接口

TransactionStatus是事务的状态接口,它描述了某一时间点上事务 的状态信息。它有如下方法:

void flush() 刷新事务

boolean hasSavepoint() 获取是否存在保存点

boolean isCompleted() 获取事务是否完成boolean isNewTransaction() 获取是否是新事务boolean isRollbackOnly() 获取是否回滚void setRollbackOnly() 设置事务回滚

Spring事务_事务的相关配置

<tx:advice> 中可以进行事务的相关配置:

<tx:advice id="txAdvice">
    <tx:attributes>
        <tx:method name="*"/>
        <tx:method name="find*" readonly="true"/>
    </tx:attributes>
</tx:advice>

2345_image_file_copy_220.jpg

Spring事务_事务的传播行为

事务传播行为是指多个含有事务的方法相互调用时,事务如何在这 些方法间传播。 如果在service层的方法中调用了其他的service方法,假设每次执行 service方法都要开启事务,此时就无法保证外层方法和内层方法处 于同一个事务当中。

// method1的所有方法在同一个事务中
public void method1(){
    // 此时会开启一个新事务,这就无法保证method1()中所有的代码是在同一个事务中
    method2();
    System.out.println("method1");
}
public void method2(){
    System.out.println("method2");
}

事务的传播特性就是解决这个问题的,Spring帮助我们将外层方法 和内层方法放入同一事务中。

2345_image_file_copy_221.jpg

Spring事务_事务的隔离级别

事务隔离级别反映事务提交并发访问时的处理态度,隔离级别越 高,数据出问题的可能性越低,但效率也会越低。

2345_image_file_copy_222.jpg

2345_image_file_copy_223.jpg

Spring事务_注解配置声明式事务

Spring支持使用注解配置声明式事务。用法如下:

1、注册事务注解驱动

<!-- 注册事务注解驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

2、在需要事务支持的方法或类上加@Transactional

 @Service
// 作用于类上时,该类的所有public方法将都具有该类型的事务属性
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
public class AccountService {
    @Autowired
    private AccountDao accountDao;
    /**
     * 转账
     * @param id1 转出人id
     * @param id2 转入人id
     * @param price 金额
     */
    // 作用于方法上时,该方法将都具有该类型的事务属性
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
    public void transfer(int id1, int id2,double price) {
        // account1修改余额
        Account account1 = accountDao.findById(id1);
        account1.setBalance(account1.getBalance()-price);
        accountDao.update(account1);
        int i = 1/0; // 模拟转账出错
        // account2修改余额
        Account account2 = accountDao.findById(id2);
        account2.setBalance(account2.getBalance()+price);
        accountDao.update(account2);
   }
}

3 配置类代替xml中的注解事务支持:在配置类上方写 @EnableTranscationManagement

@Configuration
@ComponentScan("com.itbaizhan")
@EnableTransactionManagement
public class SpringConfig {
    @Bean
    public DataSource getDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
       druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
       druidDataSource.setUrl("jdbc:mysql:///spring");
       druidDataSource.setUsername("root");
       druidDataSource.setPassword("root");
        return druidDataSource;
}
    @Bean
    public SqlSessionFactoryBean getSqlSession(DataSource dataSource){
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        return sqlSessionFactoryBean;
   }
    @Bean
    public MapperScannerConfigurer getMapperScanner(){
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("com.itbaizhan.dao");
        return mapperScannerConfigurer;
   }
    @Bean
    public DataSourceTransactionManager getTransactionManager(DataSource dataSource){
         DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
      dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
   }
}


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
30天前
|
存储 安全 Java
Spring Security 入门
Spring Security 是 Spring 框架中的安全模块,提供强大的认证和授权功能,支持防止常见攻击(如 CSRF 和会话固定攻击)。它通过过滤器链拦截请求,核心概念包括认证、授权和自定义过滤器。配置方面,涉及密码加密、用户信息服务、认证提供者及过滤器链设置。示例代码展示了如何配置登录、注销、CSRF防护等。常见问题包括循环重定向、静态资源被拦截和登录失败未返回错误信息,解决方法需确保路径正确和添加错误提示逻辑。
Spring Security 入门
|
18天前
|
人工智能 自然语言处理 Java
Spring Cloud Alibaba AI 入门与实践
本文将介绍 Spring Cloud Alibaba AI 的基本概念、主要特性和功能,并演示如何完成一个在线聊天和在线画图的 AI 应用。
224 7
|
1月前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
85 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
1月前
|
Java 数据库连接 数据库
从入门到精通---深入剖析Spring DAO
在Java企业级开发中,Spring框架以其强大的功能和灵活性,成为众多开发者的首选。Spring DAO(Data Access Object)作为Spring框架中处理数据访问的重要模块,对JDBC进行了抽象封装,极大地简化了数据访问异常的处理,并能统一管理JDBC事务。本文将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring DAO,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
30 1
|
2月前
|
监控 Java 数据安全/隐私保护
如何用Spring Boot实现拦截器:从入门到实践
如何用Spring Boot实现拦截器:从入门到实践
67 5
|
2月前
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
80 9
|
3月前
|
前端开发 Java 数据库
SpringBoot学习
【10月更文挑战第7天】Spring学习
48 9
|
2月前
|
Java Kotlin 索引
学习Spring框架特性及jiar包下载
Spring 5作为最新版本,更新了JDK基线至8,修订了核心框架,增强了反射和接口功能,支持响应式编程及Kotlin语言,引入了函数式Web框架,并提升了测试功能。Spring框架可在其官网下载,包括文档、jar包和XML Schema文档,适用于Java SE和Java EE项目。
41 0
|
3月前
|
XML Java 数据格式
Spring学习
【10月更文挑战第6天】Spring学习
33 1
|
3月前
|
Java 测试技术 开发者
springboot学习四:Spring Boot profile多环境配置、devtools热部署
这篇文章主要介绍了如何在Spring Boot中进行多环境配置以及如何整合DevTools实现热部署,以提高开发效率。
135 2