spring笔记

spring概述

在pom文件中是使用resource标签可以修改资源路径不用再默认的resource文件夹下

 <resources>
        <resource>
<directory>src/resources/</directory>
        <includes>
            <include>*.xml</include>
        </includes>
        </resource>

该配置中含有一个filtering来解决编码过程中的配置文件的变量注入问题,不同的开发环境启用不同的配置属性,使用filtering可以进行灵活切换

filtering:开启过滤,用指定的参数替换指定文件夹下的文件中的参数(eg. ${name})

 <filtering>true</filtering>

IOC容器:

控制反转,把对象的创建和对象之间的过程交给spring进行管理,降低耦合度

过程:xml解析、工厂模式、反射,实现对象创建流程

spring类创建流程:1.将类路径写在xml文件中定义所需要类的bean;2.创建工厂类,解析xml文件,获取xml中自定义bean的class的字符串(user=“come.w.user”)对象,然后通过反射(Class class=class.forname(user))的方式获取对象的类值,然后进行class.newInstance()创建object对象,进行强制转换为user

IOC底层就是对象工厂,在内部提供了两个重要的接口(BeanFactory,ApplicationContext),作用为加载配置文件通过工厂模式的过程去创建对象

   ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("bean.xml");

        user user = classPathXmlApplicationContext.getBean("user", user.class);

BeanFactory:是spring内部使用,不提供给开发者使用,加载配置文件时不创建对象,在获取对象时才创建

ApplicationContext:beanFactory的子接口,比beanfactory提供了更多更强大的功能,面向开发者使用,加载配置文件时就会创建对象

在进行web项目开发时一般将对象在服务器启动前创建,所以使用ApplicationContext创建对象

1、@Data可以为类提供读写功能,从而不用写get、set方法。
2、他还会为类提供 equals()、hashCode()、toString() 方法。

Bean管理:spring创建对象,spring进行属性的注入

实现方式:基于XML配置文件的方式,基于注解方式实现

bean对象的属性可以根据set方法进行设置或者进行有参构造的方式进行设置,在进行有参构造时,@data注解没有实现有参构造方法需自己在类中实现

  <bean id="user" class="user">
<property name="age" value="18"></property>
        <property name="name" value="lishi"></property>
    </bean>

<bean id="user" class="user">
<constructor-arg  name="age" value="18"></constructor-arg>
        <constructor-arg name="name" value="lishi"></constructor-arg>
    </bean>

p命名空间:

  <?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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="world" class="com.app.World"/>

<!-- 通过set方法注入的传统的bean定义 -->
<bean id="hello1" class="com.app.Hello">
<property name="p1" value="v1"/>
<property name="p2" value="v2"/>
<property name="world" ref="world"/>
</bean>

<!-- 通过set方法注入的使用p命名空间的bean定义 -->
<bean id="hello2" class="com.app.Hello" p:p1="v1" p:p2="v2" p:world-ref="world"/>

</beans>
  

c命名空间:

  <?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:c="http://www.springframework.org/schema/c"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="world" class="com.app.World"/>

<!-- 传统的使用constructor-arg通过构造方法注入的bean定义 -->
<bean id="hello1" class="com.app.Hello">
<constructor-arg index="0" value="arg1"/>
<constructor-arg index="1" value="2"/><!-- arg2 -->
<constructor-arg index="2" ref="world"/><!-- arg3 -->
</bean>
<!-- 使用c命名空间通过构造方法注入的bean定义 -->
<bean id="hello2" class="com.app.Hello" c:arg1="c_arg1" c:arg2="2" c:arg3-ref="world"/>
</beans>
   

空值注入:

 <bean id="user" class="user">
<property name="name">
    <null/>
</property>
    </bean>

bean注入方式:(外部注入,内部注入,级联注入)

级联注入:

 <bean id="car" class="com.gong.spring.beans.Car"></bean>
  
    <bean id="student" class="com.gong.spring.beans.Student">
        <property name="name" value="tom"></property>
        <property name="age" value="12"></property>
        <property name="score" value="98.00"></property>  
        <property name="car" ref="car"></property>
        <property name="car.name" value="baoma"></property>
    </bean>

spring中有两种bean对象:一种是普通bean,另一种是工厂bean(beanFactory)

普通bean:在配置文件中定义的bean类型就是返回的bean类型

工厂bean:在配置文件定义bean类型可以和返回值类型不一样(实现方法:

1.创建类没让这个类作为工厂bean实现接口FactoryBean

2.实现接口里面的方法,在实现的方法中定义返回的bean类型

bean的作用域与生命周期:

singleton——唯一 bean 实例:当一个 bean 的作用域为 singleton,那么Spring IoC容器中只会存在一个共享的 bean 实例,并且所有对 bean 的请求,只要 id 与该 bean 定义相匹配,则只会返回bean的同一实例

prototype——每次请求都会创建一个新的 bean 实例:当一个bean的作用域为 prototype,表示一个 bean 定义对应多个对象实例 prototype 作用域的 bean 会导致在每次对该 bean 请求** (将其注入到另一个 bean 中,或者以程序的方式调用容器的 getBean() 方法**)时都会创建一个新的bean 实例。prototype是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。根据经验,对有状态的bean 应该使用 prototype 作用域,而对无状态的 bean 则应该使用 singleton 作用域

request——每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效request只适用于Web程序,每一次 HTTP 请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,当请求结束后,该对象的生命周期即告结束。

session——每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效:session只适用于Web程序,session作用域表示该针对每一次 HTTP 请求都会产生一个新的 bean,同时该 bean 仅在当前 HTTP session内有效.与request作用域一样,可以根据需要放心的更改所创建实例的内部状态,而别的 HTTP session 中根据userPreferences 创建的实例,将不会看到这些特定于某个 HTTP session 的状态变化。当HTTP session最终被废弃的时候,在该HTTP session作用域内的bean也会被废弃掉

globalSession:global session 作用域类似于标准的 HTTP session 作用域,不过仅仅在基于 portlet 的 web应用中才有意义。Portlet 规范定义了全局 Session 的概念,它被所有构成某个 portlet web 应用的各种不同的 portlet所共享。在global session 作用域中定义的 bean 被限定于全局portlet Session的生命周期范围内。

生命周期:

概念:Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,这其中包含了一系列关键点:

流程图:
在这里插入图片描述
在这里插入图片描述

bean生命周期:

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

Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:

1、Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法

2、Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法

3、容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。

4、工厂后处理器接口方法:这个包括了AspectJWeavingEnabler,ConfigurationClassPostProcessor,
CustomAutowireConfigurer等等非常有用的工厂后处理器,接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

ico自动装配:在xml文件中通过配置bean标签的属性叫做手动装配,自动装配指根据指定的装配规则(属性名称或者属性类型),spring自动将匹配的属性进行注入

实现:

  • bean标签中有autowire,配置自动装配,autowire睡醒常用两个值:byName根据属性名称注入,注入值bean的id值和属性名称是一样的
  • bytype根据属性类型注入


<bean id="userMapper" class="edu.cn.dao.UserMapperImpl" autowire="byName"/>

<bean id="userService" class="edu.cn.dao.UserServiceImpl" autowire="byName"/>


外部属性文件管理

1.将context命名空间引入xml

2.在spring配置文件中使用标签引入外部属性文件

<!-- 引入DB配置文件 -->
<context:property-placeholder location="classpath:oracleDriver.properties"/>
<!-- 配置数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${name}"></property>
<property name="password" value="${password}"></property>
</bean>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        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">

<!-- 注解包扫描 -->
<context:component-scan base-package="com.test.fx.service"></context:component-scan>
<!-- 引入DB配置文件 -->
<context:property-placeholder location="classpath:oracleDriver.properties"/>
<!-- 配置数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${name}"></property>
<property name="password" value="${password}"></property>
</bean>
<!-- 创建SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations" value="classpath:com/baizhi/fx/dao/*DaoImpl.xml"></property>
</bean>
<!-- 扫描Mapper文件并生成dao对象 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<property name="basePackage" value="com.test.fx.dao"></property>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事务管理器注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
注解:

概念:代码的特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值…),可作用于方法、类、属性上面

对象创建:

种类:@component、@service、@controller、@repository这四个注解功能相同都可以来创建bean实例对象(原始开发要引入aop依赖,然后开启注解扫描)

在定义包扫描时可以配置相应的包扫描规则:

<context:component-scan base-package="com.dancer.crud" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

属性注入:

@Autowired(根据属性类型进行注入)、@qualifier(根据属性名称进行注入)【当一个接口有多个实现类时无法根据属性类型进行注入,需要使用@qualifier(value=“userdaoImpl”)不配置默认使用实现类首字母小写】、@resource(可以根据属性类型也可以是属性名称)、@value注入普通类型属性(@value(value=“abc”))

完全注解开发:

概念:使用配置类代替xml,用注解@configuration定义配置类,用@componentScan开启注解扫描,定义applicationcontext时使用AnnotationConfigApplicationContext:注意导入aop

 ApplicationContext applicationContext = new AnnotationConfigApplicationContext(config.class);

AOP概念:

概念:面向切面编程,可以预编译方式和运行期动态地啊你实现在不修改源代码情况下给程序动态添加功能的技术

底层原理:aop底层使用动态代理,在有接口的情况下使用JDK进行动态代理,在没有接口情况下使用CGLIB进行动态代理

场景:日志记录、异常处理、权限验证、缓存处理、事务处理、数据持久化、效率检查、内容分发

  1. Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。
  2. Joint point(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point(连接点指类中的方法)
  3. Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。(被抽取了共性功能的方法)
  4. Advice(通知):Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。(抽取的共性功能组成的代码逻辑)
  5. Target(目标对象):织入 Advice 的目标对象()
  6. Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程

spring AOP底层实现,是通过JDK动态代理或者CGlib代理在运行时期在对象初始化阶段织入代码的

区别:jdk动态代理基于接口实现CGlib基于类的继承实现

Aspect驱动实现步骤:

1.定义一个切面类Aspect(在声明的类上添加@Component @Aspect两个注解 springboot中引入aop-stater依赖)

2.定义切点Pointcut 【定义切点,并定义切点在什么地方执行,采用@Pointcut注解完成,如@pointcut(public “”com.xxx.xxx.“”.(…) 规则:修饰符【可以写,但不可以使用“”+返回值类型+包下的类+哪些方法+方法参数 “*”代表不限, “…”两个点代表参数不限】

3.定义Advice通知(利用通知的5种类型注解@after、@before、@afterReturning、@afterThrowing、@around来完成某个切点的增强动作,如【@before(“point()“,point为第二部定义的切点】)

/**
 *声明一个切面
 */
@Aspect
@Component
public class advice {
    private Logger logger= LoggerFactory.getLogger(advice.class);


    /**
     * 定义一个切点
     */
    @Pointcut(value = "execution(* com.macro.mall.search.controller.*.*(..))")
    public void  firstpoint(){

    }
    /**
     *定义一个通知
     * 此处的通知不能将方法名写成point(),会报错
     */
    @Around("firstpoint()")
    public Object logger(ProceedingJoinPoint point) throws Throwable {
        String s = point.getTarget().getClass().toString();
        String name = point.getSignature().getName();
        Object[] args = point.getArgs();
        ObjectMapper mapper = new ObjectMapper();
logger.info("调用前:"+s+":"+name+"传参为:"+mapper.writeValueAsString(args));
//让目标方法执行
        Object proceed = point.proceed();

        logger.info("调用后:"+s+":"+name+"传参为:"+mapper.writeValueAsString(args));
        return proceed;
    }

}
jbdcTemplate
  • execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;

  • update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;

  • query方法及queryForXXX方法:用于执行查询相关语句;

  • call方法:用于执行存储过程、函数相关语句。

    使用c3p0进行数据库操作并在jdbc中注入DataSource数据源

    <context:property-placeholder location="classpath:db.properties"/>
                 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
                    <property name="user" value="${jdbc.user}"></property>
                     <property name="password" value="${jdbc.password}"></property>
                     <property name="driverClass" value="${jdbc.driverClass}"></property>
                     <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
                 </bean>
    
                 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
                    <property name="dataSource" ref="dataSource"></property>
                 </bean>
    

事务

概念:事务是数据库操作最基本的单元逻辑上一组操作要么成功要么失败,一个失败则全部操作失败

特性(ACID):原子性(过程不可分割,要么都成功,要么都失败)、一致性(操作之前与操作之后总量不变)、隔离性(多个人去操作同一条记录,之间不会产生任何影响)、持久性(当事务提交后表中数据将发生变化)

事务操作方式:

1.编程式事务:


  1. 步骤一:配置一个事务管理器,Spring使用PlatformTransactionManager接口来管理事务,所以咱们需要使用到他的实现类!!
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

        2. 步骤二:配置事务管理的模板
<!-- 配置事务管理的模板 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"/>
</bean>

        3. 步骤三:在需要进行事务管理的类中,注入事务管理的模板
<bean id="accountService" class="com.itheima.demo1.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
<property name="transactionTemplate" ref="transactionTemplate"/>
</bean>
  // 注入事务模板对象
    private TransactionTemplate transactionTemplate;
    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    public void pay(final String out, final String in, final double money) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                // 扣钱
                accountDao.outMoney(out, money);
                int a = 10/0;
                // 加钱
                accountDao.inMoney(in, money);
            }
        });
    }

2.声明式事务管理(通过配置做到),可以基于注解方式或者xml文件,底层基于aop实现

spring事务管理API:

提供的一个接口:代表事务管理器针对不同框架提供了不同实现类(platformTransationManager),在使用事务管理时接口分别实现了不同操做类型的类用来做事务控制

注解方式实现声明式事务:

  1. 在spring配置文件中配置事务管理器
<bean id="defaultTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/><--此处为自己配置的数据源-->
</bean><--该类是platformTransationManager的jdbc实现-->

2.开启事务注解:(引入context命名空间)

<!-- 使用annotation定义事务 -->
    <tx:annotation-driven transaction-manager="defaultTransactionManager" proxy-target-class="true" />

3.在service类上面添加事务注解

@Transactional
public class TestServiceBean implements TestService {   
    private TestDao dao;   
    public void setDao(TestDao dao) {
        this.dao = dao;
    }   
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<Object> getAll() {
        return null;
    }   
}
事物传播行为介绍

事物超时设置:
@Transactional(timeout=30) //默认是30秒

Transactional属性:

  • ioslation:事务隔离级别(多事务操作之间不会产生影响,不考虑隔离性产生很多问题,脏读,幻读,不可重复读)
  • propagation:事务传播行为(多事务方法直接进行调用这个过程中事务是如何进行管理的)
  • timeout:超时时间(到期不提交执行事务回滚,默认为-1:不超时)
  • readOnly(只读操作)
  • rollbackFor:回滚:设置哪些异常进行事务回滚
  • norollbackFor:设置哪些异常不进行事务回滚

事务隔离级别:
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
读取未提交数据(会出现脏读, 不可重复读) 基本不使用
@Transactional(isolation = Isolation.READ_COMMITTED)
读取已提交数据(会出现不可重复读和幻读)
@Transactional(isolation = Isolation.REPEATABLE_READ)
可重复读(会出现幻读)
@Transactional(isolation = Isolation.SERIALIZABLE)
串行化

MYSQL: 默认为REPEATABLE_READ级别
SQLSERVER: 默认为READ_COMMITTED

@Transactional(propagation=Propagation.REQUIRED)1. 脏读 : 一个事务读取到另一事务未提交的更新数据
2. 不可重复读 : 在同一事务中, 多次读取同一数据返回的结果有所不同, 换句话说,后续读取可以读到另一事务已提交的更新数据. 相反, "可重复读"在同一事务中多次读取数据时, 能够保证所读数据一样, 也就是后续读取不能读到另一事务已提交的更新数据
3. 幻读 : 一个事务读到另一个事务已提交的insert数据

  • @Transactional(propagation=Propagation.NOT_SUPPORTED)
    容器不为这个方法开启事务
  • @Transactional(propagation=Propagation.REQUIRES_NEW)
    不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
  • @Transactional(propagation=Propagation.MANDATORY)
    必须在一个已有的事务中执行,否则抛出异常@Transactional(propagation=Propagation.NEVER)
  • 必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)
  • @Transactional(propagation=Propagation.SUPPORTS)
    如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.
xml配置声明式事务:

步骤:

1.配置事务管理器

2.配置通知

3.配置切入点和切面

无论是使用注解的方式还是XML,最终支持事务管理的一定是事务管理器dataSourceTransactionManager,事务管理是AOP中的一个简单应用,AOP面向切面编程, 切面就是从目标对象中抽取出来一些公共功能或一些非核心业务代码所存放的类 ,面向对象为纵向继承,面向切面为横向抽取。

1、创建切面;2、写通知;3、写切入点表达式。事务管理器就相当于AOP中的切面,如果在XML中就要配置切入点表达式。

需要通过XML配置事务:

1、配置事务管理器DataSourceTransactionManager (依赖于数据源)

2、写切入点表达式(通知作用到连接点上) aop:pointcut

3、配置事务通知tx:advice,(依赖事务管理器), 在设置好的切入点表达式下再次进行事务设置,选择加事务的方法名tx:method

4、切入点和通知要联系起来**<aop:advisor advice-ref=“tx” pointcut-ref=“pointCut”/>


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

<context:component-scan base-package="com.atguigu.book_xml"></context:component-scan>

<!-- 引入属性文件 -->
<context:property-placeholder location="db.properties"/>

<!-- 创建数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>

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

<!-- 配置事务管理器,不管是用注解方式或xml方式配置事务,一定要有DataSourceTransactionManager事务管理器的支持
        事务依赖于数据源所产生的连接对象,只有连接对象创建成功了才能够处理事务
        -->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 配置事务通知,依赖于事务管理器 -->
<tx:advice id="tx" transaction-manager="dataSourceTransactionManager">
<tx:attributes>
<!-- 在设置好的切入点表达式下再次进行事务设置 -->
<tx:method name="buyBook"/>
<tx:method name="checkOut"/>

<!-- 只有select开头的方法才会被事务处理 ,利用通配符-->
<tx:method name="select*" read-only="true"/>
<tx:method name="insert*"/>
<tx:method name="update*"/>
<tx:method name="delete*"/>

<tx:method name="*"/>

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

<!-- 配置切入点表达式,一定是针对于切面如何作用于连接点上。需要将切入点表达式和事务通知联系起来 -->
<aop:config>
<aop:pointcut expression="execution(* com.w.book_xml.service.impl.*.*(..))" id="pointCut"/>
<--配置切面-->
<aop:advisor advice-ref="tx" pointcut-ref="pointCut"/>
</aop:config>

</beans>

完全注解方式实现声明式事务控制

1.创建配置类来替代xml

@Configuration
@ComponentScan("com.springdemo.dao")
@EnableTransactionManagement
public class AppConfig1 {

    @Bean
    public DruidDataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=true");
        ds.setUsername("root");
        ds.setPassword("123456@#");
        ds.setInitialSize(5);
        return ds;
    }

    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

}
webflux(响应式编程)

用于web开发功能与springmvc相似但底层区别很大,webflux是响应式编程框架,传统web框架基于servlet容器实现,webflux是一种异步非阻塞的框架,异步非阻塞的框架在servlet3.1以后才支持,核心基于reactor的相关API实现,默认使用容器为Netty(高性能的NIO框架,异步非阻塞)

心得不够…

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值