导图社区 Spring
这是一个关于Spring的思维导图,主要内容有IOC、Dl、其他注解、全注解、在测试中的注解等。
编辑于2022-11-13 14:19:24 河南Spring
spring框架是由于软件开发的复杂性而创建的,spring的使用是由基本的JavaBean 来完成以前只可能有EJB来完成的功能。从简单性,可测性和松耦合性角度来看,绝大部分Java应用都使用spring
IOC
负责创建对象,管理对象(通过依赖注入),整合对象,配置对象,以及管理这些对象的生命周期。
DI
DI注解
Autowried
按照类型进行注入,如果注入失败,按照名称进行注入
通过@Qualifiler结合去指明bean中的id
Resource
按照名称进行注入,如果注入失败,按照类型进行注入
通过name属性进行指明bean中的id
DI注解的注入方式
属性/字段注入
直接在属性上添加注解,是最简单的注入方式
setter注入
在setter方法上添加注解
构造注入
在spring某个版本后可以直接使用有参构造不用注解,也可以使用注解
其他注解
Scope:定义Bean的作用范围
Value
直接复制:@Value("值")
读取配置文件中的值,并赋值给当前属性
必须保证此配置文件已经加载到spring中!否则读取失败
全注解
@Configuration:
@Configuration:表示当前类是一个配置类,用于代替配置文件,相当于applicationContext.xml
@Bean
@Bean:放在方法上,默认bean的id=方法名,也可以自定义 配置数据源
@PropertySource
@PropertySource:用于加载指定的配置文件,相当于 <context:property-placeholder location=""/>
@ComponentScan
@ComponentScan:用于指定扫描包路径,相当于 <context:component-scan base-package=""/>
@Import
@Import:导入其他配置类。相当于 <import resource=""></import>
在测试中的注解
AnnotationConfigApplicationContext
import
Runwith
spring注入jdbc连接使用数据库
扫描注册包路径:让包下的类添加相应的注解起到作用
<!--扫描注解包路径:让包下的类添加相应注解起到作用--> <!--<context:component-scan base-package="cn.yunhe.dao,cn.yunhe.service" />--> <context:component-scan base-package="cn.yunhe" />
加载外部数据库配置文件
<!--加载外部的数据库配置文件--> <!--在框架中只要碰到location,后面必须要使用classpath--> <context:property-placeholder location="classpath:jdbc.properties" />
配置数据源:使用德鲁伊数据库
<!--配置数据源:使用德鲁伊连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean>
配置JdncTemplate:将JdncTemplate的控制权交给IOC
<!--配置JdbcTemplate:将JdbcTemplate的控制权交给IOC--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg name="dataSource" ref="dataSource" /> </bean>
BeanFactory和ApplicationContext的区别
1.BeanFactory: IOC的最顶级的接口,定义了bean中最基本的功能,在获取bean时,是延期加载的,在调用getBean时提供。 2.ApplicationContext: 是由BeanFactory派生出来的结构,获得bean时,立即加载,在启动时,就创建的加载全部的bean
spring的核心实现类
ClassPathXmlAppLictioncontext 根据类路径(编译后的路径)读取xml配置文件 FileSystemXmlApplicationContext 根据本地磁盘路径读取xml配置文件 AnnotationConigApplicationContext 读取配置类加载的配置的
Bean的作用域
1.singletion 单例模式.IOC只创建一次,随后一直存在 2.prototype 原型模式。每次获取Bean的时候都回去创建一个新的对象 3.request 创建请求,创建一个新的Bean对象 4.session 创建会话,创建一个新的Bean对象 5.globalSessions 在分布式环境下,对应全局Session。如果不是在分布式的环境,相当于Session
Bean的生命周期
实例化Bean
对于 BeanFactory 容器,当客户向容器请求一个尚未初始化的 bean 时, 或初始化 bean 的时候需要注入另一个尚未初始化的依赖时,容器就会调用 createBean 进行实例化。对于 ApplicationContext 容器,当容器启动结束后, 通过获取 BeanDefinition 对象中的信息,实例化所有的 bean。
设置对象属性(注入依赖)
实例化后的对象被封装在 BeanWrapper 对象中,紧接着,Spring 根据 BeanDefinition 中的信息 以及 通过 BeanWrapper 提供的设置属性的接口完 成依赖注入。
处理Aware接口
接着,Spring 会检测该对象是否实现了 xxxAware 接口,并将相关的 xxxAware 实例注入给 Bean: 如果这个 Bean 已经实现了 BeanNameAware 接口,会调用它实现的 setBeanName(String beanId)方法,此处传递的就是 Spring 配置文件中 Bean 的 id 值; 如果这个 Bean 已经实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory()方法,传递的是 Spring 工厂自身。 如果这个 Bean 已经实现了 ApplicationContextAware 接口,会调用 setApplicationContext(ApplicationContext)方法,传入 Spring 上下文
BeanPostProcessor
如果想对 Bean 进行一些自定义的处理,那么可以让 Bean 实现了 BeanPostProcessor 接口,那将会调用postProcessBeforeInitialization(Object obj, String s)方法。由于这个方法是 在 Bean 初始化结束时调用的,所以可以被应用于内存或缓存技术;
InitializingBean 与 init-method
如果 Bean 在 Spring 配置文件中配置了 init-method 属性,则会自动调 用其配置的初始化方法。
子主题如果这个 Bean 实现了 BeanPostProcessor 接口,将会调用 postProcessAfterInitialization(Object obj, String s)方法;
以上几个步骤完成后,Bean 就已经被正确创建了,之后就可以使用这个Bean 了。
DisposableBean
当 Bean 不再需要时,会经过清理阶段,如果Bean 实现了 DisposableBean 这个接口,会调用其实现的 destroy()方法
destroy-method
最后,如果这个 Bean 的 Spring 配置中配置了 destroy-method 属性,会 自动调用其配置的销毁方法
spring特点
优点
1.spring属于低侵入设计 2.IOC将对象之间的依赖关系交给spring降低组件之间耦合性,让我们更加专注于业务逻辑 3.提供面向切面编程 4.对各种主流插件提供很好的集成支持 5.对事务支持的很好,只需配置即可,无须手动控制
缺点
依赖反射,影响性能。
spring配置方式
xml文件配置
基于注解
基于java
AOP
在软件业,AOP是Aspect Oriented Programming的缩写,面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术
切面的类型通知
前置通知
目标方法的调用之前调用通知功能 <aop:piintcut id="poit" expression="execution(*cn.yunhe.service..*.*(..)"/> <aop:aspect rep="myadvice" >(rep"公共模块id") 前置通知/增强 <aop:before method="before" pointcut-ref="poit"> 使用注解时:@Before(value="方法名()")
Before
后置通知
目标方法调用之后调用通知 <aop:after-returning method="after" pointcut-ref="poit" returning="result"> returning和方法名保存一致 后置用注解的形式 @AfterReturning(pointcut="方法名" returning="result")
After
返回通知
目标方法成执行之后调用通知 <aop:after method="myFinal" pointcut-ref="poit" > 使用注解形式 @After("方法名")
After-returning
异常通知
目标方法抛出异常之后调用通知 <aop:after-throwing method="processException" pointcut-ref="poit" throwing="ex" /> throwing 和方法入参名保持一致 使用注解 @Afterthrowing(pointcut="方法名" throwing="e")
After-throwing
环绕通知
在被通知的方法调用之前和调用之后执行自定义的行为 <aop:around method="around" pointcut-ref="poit" > 是前四种通知的整合,并且不能同是使用 使用注解 @Around("方法名")
Around
AOP的使用
创建maven项目
添加pom依赖
创建配置文件,引入AOP头部,开启IOC注解驱动
完善项目结构,完善spring注解
编写公共模块(需要加强的地方)
配置AOP
概念
面向切面编程。将程序中重复的功能封装公共模块,利用动态代理,在程序运行期间,在不修改源码的情况下对方法进行功能增强。
实现
默认使用的是JDK动态代理。如果失败的话,会切换到CGLIB动态代理。
AOP使用场景
事务
异常处理
日志
AOP表达式
execution(* cn.yunhe.service..*.*(..): 匹配到service包及其子包所有的类所有的方法所有的参数!
打开AOP注册驱动
<aop:aspectj-autoproxy proxy-target-class="true">
基于配置文件如何切换成cglib动态代理
<aop:config proxy-target-class="true">:true:cglib动态代理。false:JDK动态代理。 如果使用AOP注解驱动: <aop:aspectj-autoproxy proxy-target-class="true" />:true:cglib动态代理。false:JDK动态代理。
基于配置类如何切换成cglib动态代理
@EnableAspectJAutoProxy(proxyTargetClass = true)
基于XML配置文件的注解
基于配置类的注解
连接点:Join Point
连接点是在应用执行过程中,能够插入切面的一个点,这个点可以是调用方法时.抛出异常时,修改一个字段时
切入点:Pointcut
用注解形式 @Pointcut("execution(*业务层路径..*.*(..)")
切面:Aspect
切面是通知和切点的结合,通知和切点共同定义了切面的全部内容
织入:Weaving
织入是把切面应用到目标对象并且创建新的代理对象的过程,切面在指定的连接点被织入到目标对象中
引入:Introduction
引入允许我们在现有的类中添加新方法和属性
代理模式
代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的
动态代理
运行时才确认的代理关系
动态代理的实现
JDK动态代理
基于接口的动态代理技术,必须要有接口。
CGLIM动态代理
基于父类的动态代理技术,基于目标类生成一个子类作为代理类。
静态代理
编译时就已经确定好了代理关系
代理意义
为目标对象增加很多功能!做再次的增强! 代理模式可以在不改变原代码的情况下,为程序增加新的功能。 new出来的代理对象就是所谓的编译时期的代理对象,也就是静态代理。 在运行时创建的代理对象就是动态代理。
spring事务
1.编程式事务----自己写代码 2.生明式事务----使用AOP实现
spring事务管理器
PlatformTranscationManger 顶级接口 事务定义参数的接口,事务隔离等级,事务传播行为
事务隔离等级
1 读未提交 2 读已提交 3 可重复读 4 串行化 5 默认(以数据库的事务隔离级别为准)
事务传播行为
spring 常用的属性
1 REQUIRED 2 SUPPORTS(用于查询)
1.REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务时,加入到这个事务中
2.SUPPORTS
支持当前事务,如果当前没有事务,就以非事务放式执行。
3.MANDATORY
使用当前事务,如果当前没有事务,就抛去异常
4.REQUIRES-NEW
新建事务如果当前在事务中,把当前事务挂起
5.NOT-SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
6.NEVER
以非事务方式运行,如果当前存在事务抛出异常
7.NESTED
如果当前存在事务,则在嵌套事务内执行,如果当前没有事务,也执行REQUIRED类型的操作
spring其他属性
read-only
是否只读 true/false
timeout
超时时间 默认为-1,不超时
入门案例
以配置文件的形式
创建数据库
创建maven工程
搭建项目结构
创建配置文件
<!--开启IOC注解驱动--> <context:component-scan base-package="cn.yunhe" /> <!--加载外部数据库配置文件--> <context:property-placeholder location="classpath:jdbc.properties" /> <!--配置数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!--配置jdbcTemplate--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg 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="find*" propagation="SUPPORTS" /> <tx:method name="get*" propagation="SUPPORTS" /> <!--<tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT" rollback-for="RuntimeException" />--> <tx:method name="transfer" propagation="REQUIRED" /> <tx:method name="*" propagation="REQUIRED" /> </tx:attributes> </tx:advice> <!--配置AOP,将事务和方法结合--> <aop:config proxy-target-class="true"> <!--配置切入点--> <aop:pointcut id="point" expression="execution(* cn.yunhe.service..*.*(..))" /> <!--织入--> <aop:advisor advice-ref="txAdvice" pointcut-ref="point" /> </aop:config>
完善实现类
加入声明式事务--配置事务管理器
以注解的形式
创建数据库
创建maben工程
搭建项目结构
创建配置文件和编写注解
<!--引入外部数据库配置文件--> <context:property-placeholder location="classpath:jdbc.properties" /> <!--IOC注解驱动--> <context:component-scan base-package="cn.yunhe" /> <!--配置数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!--配置JdbcTemplate--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg name="dataSource" ref="dataSource" /> </bean> <!--配置事务管理器--> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!--打开事务注解驱动--> <!--transaction-manager:指定事务注解配置的事务规则放入到哪个事务管理器中!--> <!--proxy-target-class:指定动态代理。默认是false:JDK动态代理。true:cglib!--> <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" />
完善实现类
加入声明式事务
事务注解:Transactional
第一种使用指定属性 @Transactional(propagation=Propagation.REQUIRED, rollbackFor={RuntimeException.class,Error.class}) 第二种用默认属性 @Transactional
默认属性
默认的事务传播行为 :REQUIRED 默认的隔离等级 :DEFAULT 默认的timeout:-1 默认的回滚异常是:RuntimeException&&Error
如何使用
放在类上
类中的所有方法都遵循比事务规则;如果覆盖类上的事务规则,则在方法上指定即可
放在方法上
只对当前方法起作用
以配置类的形式
创建数据库
创建maven工程
搭建项目结构
创建配置类
// 相当于添加了<tx:annotation-driven proxy-target-class="true" /> @EnableTransactionManagement(proxyTargetClass=true) //开启事务注解驱动 @PropertySource("classpath:jdbc.properties") @ComponentScan("cn.yunhe") @Configuration public class SpringConfig { //读取外部数据库配置 @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; //配置数据源(使用setter注入) @Bean public DruidDataSource dataSource(){ DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driver); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } //配置JdbcTemplate(有参构造注入) @Bean public JdbcTemplate jdbcTemplate(){ return new JdbcTemplate(dataSource()); } //配置事务管理器(有参构造注入) @Bean public DataSourceTransactionManager transactionManager(){ return new DataSourceTransactionManager(dataSource()); } }
完善实现类
加入声明式事务
在测试类中
@RunWith(SpringRunner.class) 读取配置类中属性 @ContextConfiguration(classes = SpringConfig.class)
Spring
spring框架是由于软件开发的复杂性而创建的,spring的使用是由基本的JavaBean 来完成以前只可能有EJB来完成的功能。从简单性,可测性和松耦合性角度来看,绝大部分Java应用都使用spring
IOC
负责创建对象,管理对象(通过依赖注入),整合对象,配置对象,以及管理这些对象的生命周期。
DI
DI注解
Autowried
按照类型进行注入,如果注入失败,按照名称进行注入
通过@Qualifiler结合去指明bean中的id
Resource
按照名称进行注入,如果注入失败,按照类型进行注入
通过name属性进行指明bean中的id
DI注解的注入方式
属性/字段注入
直接在属性上添加注解,是最简单的注入方式
setter注入
在setter方法上添加注解
构造注入
在spring某个版本后可以直接使用有参构造不用注解,也可以使用注解
其他注解
Scope:定义Bean的作用范围
Value
直接复制:@Value("值")
读取配置文件中的值,并赋值给当前属性
必须保证此配置文件已经加载到spring中!否则读取失败
全注解
@Configuration:
@Configuration:表示当前类是一个配置类,用于代替配置文件,相当于applicationContext.xml
@Bean
@Bean:放在方法上,默认bean的id=方法名,也可以自定义 配置数据源
@PropertySource
@PropertySource:用于加载指定的配置文件,相当于 <context:property-placeholder location=""/>
@ComponentScan
@ComponentScan:用于指定扫描包路径,相当于 <context:component-scan base-package=""/>
@Import
@Import:导入其他配置类。相当于 <import resource=""></import>
在测试中的注解
AnnotationConfigApplicationContext
import
Runwith
spring注入jdbc连接使用数据库
扫描注册包路径:让包下的类添加相应的注解起到作用
<!--扫描注解包路径:让包下的类添加相应注解起到作用--> <!--<context:component-scan base-package="cn.yunhe.dao,cn.yunhe.service" />--> <context:component-scan base-package="cn.yunhe" />
加载外部数据库配置文件
<!--加载外部的数据库配置文件--> <!--在框架中只要碰到location,后面必须要使用classpath--> <context:property-placeholder location="classpath:jdbc.properties" />
配置数据源:使用德鲁伊数据库
<!--配置数据源:使用德鲁伊连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean>
配置JdncTemplate:将JdncTemplate的控制权交给IOC
<!--配置JdbcTemplate:将JdbcTemplate的控制权交给IOC--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg name="dataSource" ref="dataSource" /> </bean>
BeanFactory和ApplicationContext的区别
1.BeanFactory: IOC的最顶级的接口,定义了bean中最基本的功能,在获取bean时,是延期加载的,在调用getBean时提供。 2.ApplicationContext: 是由BeanFactory派生出来的结构,获得bean时,立即加载,在启动时,就创建的加载全部的bean
spring的核心实现类
ClassPathXmlAppLictioncontext 根据类路径(编译后的路径)读取xml配置文件 FileSystemXmlApplicationContext 根据本地磁盘路径读取xml配置文件 AnnotationConigApplicationContext 读取配置类加载的配置的
Bean的作用域
1.singletion 单例模式.IOC只创建一次,随后一直存在 2.prototype 原型模式。每次获取Bean的时候都回去创建一个新的对象 3.request 创建请求,创建一个新的Bean对象 4.session 创建会话,创建一个新的Bean对象 5.globalSessions 在分布式环境下,对应全局Session。如果不是在分布式的环境,相当于Session
Bean的生命周期
实例化Bean
对于 BeanFactory 容器,当客户向容器请求一个尚未初始化的 bean 时, 或初始化 bean 的时候需要注入另一个尚未初始化的依赖时,容器就会调用 createBean 进行实例化。对于 ApplicationContext 容器,当容器启动结束后, 通过获取 BeanDefinition 对象中的信息,实例化所有的 bean。
设置对象属性(注入依赖)
实例化后的对象被封装在 BeanWrapper 对象中,紧接着,Spring 根据 BeanDefinition 中的信息 以及 通过 BeanWrapper 提供的设置属性的接口完 成依赖注入。
处理Aware接口
接着,Spring 会检测该对象是否实现了 xxxAware 接口,并将相关的 xxxAware 实例注入给 Bean: 如果这个 Bean 已经实现了 BeanNameAware 接口,会调用它实现的 setBeanName(String beanId)方法,此处传递的就是 Spring 配置文件中 Bean 的 id 值; 如果这个 Bean 已经实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory()方法,传递的是 Spring 工厂自身。 如果这个 Bean 已经实现了 ApplicationContextAware 接口,会调用 setApplicationContext(ApplicationContext)方法,传入 Spring 上下文
BeanPostProcessor
如果想对 Bean 进行一些自定义的处理,那么可以让 Bean 实现了 BeanPostProcessor 接口,那将会调用postProcessBeforeInitialization(Object obj, String s)方法。由于这个方法是 在 Bean 初始化结束时调用的,所以可以被应用于内存或缓存技术;
InitializingBean 与 init-method
如果 Bean 在 Spring 配置文件中配置了 init-method 属性,则会自动调 用其配置的初始化方法。
子主题如果这个 Bean 实现了 BeanPostProcessor 接口,将会调用 postProcessAfterInitialization(Object obj, String s)方法;
以上几个步骤完成后,Bean 就已经被正确创建了,之后就可以使用这个Bean 了。
DisposableBean
当 Bean 不再需要时,会经过清理阶段,如果Bean 实现了 DisposableBean 这个接口,会调用其实现的 destroy()方法
destroy-method
最后,如果这个 Bean 的 Spring 配置中配置了 destroy-method 属性,会 自动调用其配置的销毁方法
spring特点
优点
1.spring属于低侵入设计 2.IOC将对象之间的依赖关系交给spring降低组件之间耦合性,让我们更加专注于业务逻辑 3.提供面向切面编程 4.对各种主流插件提供很好的集成支持 5.对事务支持的很好,只需配置即可,无须手动控制
缺点
依赖反射,影响性能。
spring配置方式
xml文件配置
基于注解
基于java
AOP
在软件业,AOP是Aspect Oriented Programming的缩写,面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术
切面的类型通知
前置通知
目标方法的调用之前调用通知功能 <aop:piintcut id="poit" expression="execution(*cn.yunhe.service..*.*(..)"/> <aop:aspect rep="myadvice" >(rep"公共模块id") 前置通知/增强 <aop:before method="before" pointcut-ref="poit"> 使用注解时:@Before(value="方法名()")
Before
后置通知
目标方法调用之后调用通知 <aop:after-returning method="after" pointcut-ref="poit" returning="result"> returning和方法名保存一致 后置用注解的形式 @AfterReturning(pointcut="方法名" returning="result")
After
返回通知
目标方法成执行之后调用通知 <aop:after method="myFinal" pointcut-ref="poit" > 使用注解形式 @After("方法名")
After-returning
异常通知
目标方法抛出异常之后调用通知 <aop:after-throwing method="processException" pointcut-ref="poit" throwing="ex" /> throwing 和方法入参名保持一致 使用注解 @Afterthrowing(pointcut="方法名" throwing="e")
After-throwing
环绕通知
在被通知的方法调用之前和调用之后执行自定义的行为 <aop:around method="around" pointcut-ref="poit" > 是前四种通知的整合,并且不能同是使用 使用注解 @Around("方法名")
Around
AOP的使用
创建maven项目
添加pom依赖
创建配置文件,引入AOP头部,开启IOC注解驱动
完善项目结构,完善spring注解
编写公共模块(需要加强的地方)
配置AOP
概念
面向切面编程。将程序中重复的功能封装公共模块,利用动态代理,在程序运行期间,在不修改源码的情况下对方法进行功能增强。
实现
默认使用的是JDK动态代理。如果失败的话,会切换到CGLIB动态代理。
AOP使用场景
事务
异常处理
日志
AOP表达式
execution(* cn.yunhe.service..*.*(..): 匹配到service包及其子包所有的类所有的方法所有的参数!
打开AOP注册驱动
<aop:aspectj-autoproxy proxy-target-class="true">
基于配置文件如何切换成cglib动态代理
<aop:config proxy-target-class="true">:true:cglib动态代理。false:JDK动态代理。 如果使用AOP注解驱动: <aop:aspectj-autoproxy proxy-target-class="true" />:true:cglib动态代理。false:JDK动态代理。
基于配置类如何切换成cglib动态代理
@EnableAspectJAutoProxy(proxyTargetClass = true)
基于XML配置文件的注解
基于配置类的注解
连接点:Join Point
连接点是在应用执行过程中,能够插入切面的一个点,这个点可以是调用方法时.抛出异常时,修改一个字段时
切入点:Pointcut
用注解形式 @Pointcut("execution(*业务层路径..*.*(..)")
切面:Aspect
切面是通知和切点的结合,通知和切点共同定义了切面的全部内容
织入:Weaving
织入是把切面应用到目标对象并且创建新的代理对象的过程,切面在指定的连接点被织入到目标对象中
引入:Introduction
引入允许我们在现有的类中添加新方法和属性
代理模式
代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的
动态代理
运行时才确认的代理关系
动态代理的实现
JDK动态代理
基于接口的动态代理技术,必须要有接口。
CGLIM动态代理
基于父类的动态代理技术,基于目标类生成一个子类作为代理类。
静态代理
编译时就已经确定好了代理关系
代理意义
为目标对象增加很多功能!做再次的增强! 代理模式可以在不改变原代码的情况下,为程序增加新的功能。 new出来的代理对象就是所谓的编译时期的代理对象,也就是静态代理。 在运行时创建的代理对象就是动态代理。
spring事务
1.编程式事务----自己写代码 2.生明式事务----使用AOP实现
spring事务管理器
PlatformTranscationManger 顶级接口 事务定义参数的接口,事务隔离等级,事务传播行为
事务隔离等级
1 读未提交 2 读已提交 3 可重复读 4 串行化 5 默认(以数据库的事务隔离级别为准)
事务传播行为
spring 常用的属性
1 REQUIRED 2 SUPPORTS(用于查询)
1.REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务时,加入到这个事务中
2.SUPPORTS
支持当前事务,如果当前没有事务,就以非事务放式执行。
3.MANDATORY
使用当前事务,如果当前没有事务,就抛去异常
4.REQUIRES-NEW
新建事务如果当前在事务中,把当前事务挂起
5.NOT-SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
6.NEVER
以非事务方式运行,如果当前存在事务抛出异常
7.NESTED
如果当前存在事务,则在嵌套事务内执行,如果当前没有事务,也执行REQUIRED类型的操作
spring其他属性
read-only
是否只读 true/false
timeout
超时时间 默认为-1,不超时
入门案例
以配置文件的形式
创建数据库
创建maven工程
搭建项目结构
创建配置文件
<!--开启IOC注解驱动--> <context:component-scan base-package="cn.yunhe" /> <!--加载外部数据库配置文件--> <context:property-placeholder location="classpath:jdbc.properties" /> <!--配置数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!--配置jdbcTemplate--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg 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="find*" propagation="SUPPORTS" /> <tx:method name="get*" propagation="SUPPORTS" /> <!--<tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT" rollback-for="RuntimeException" />--> <tx:method name="transfer" propagation="REQUIRED" /> <tx:method name="*" propagation="REQUIRED" /> </tx:attributes> </tx:advice> <!--配置AOP,将事务和方法结合--> <aop:config proxy-target-class="true"> <!--配置切入点--> <aop:pointcut id="point" expression="execution(* cn.yunhe.service..*.*(..))" /> <!--织入--> <aop:advisor advice-ref="txAdvice" pointcut-ref="point" /> </aop:config>
完善实现类
加入声明式事务--配置事务管理器
以注解的形式
创建数据库
创建maben工程
搭建项目结构
创建配置文件和编写注解
<!--引入外部数据库配置文件--> <context:property-placeholder location="classpath:jdbc.properties" /> <!--IOC注解驱动--> <context:component-scan base-package="cn.yunhe" /> <!--配置数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!--配置JdbcTemplate--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg name="dataSource" ref="dataSource" /> </bean> <!--配置事务管理器--> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!--打开事务注解驱动--> <!--transaction-manager:指定事务注解配置的事务规则放入到哪个事务管理器中!--> <!--proxy-target-class:指定动态代理。默认是false:JDK动态代理。true:cglib!--> <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" />
完善实现类
加入声明式事务
事务注解:Transactional
第一种使用指定属性 @Transactional(propagation=Propagation.REQUIRED, rollbackFor={RuntimeException.class,Error.class}) 第二种用默认属性 @Transactional
默认属性
默认的事务传播行为 :REQUIRED 默认的隔离等级 :DEFAULT 默认的timeout:-1 默认的回滚异常是:RuntimeException&&Error
如何使用
放在类上
类中的所有方法都遵循比事务规则;如果覆盖类上的事务规则,则在方法上指定即可
放在方法上
只对当前方法起作用
以配置类的形式
创建数据库
创建maven工程
搭建项目结构
创建配置类
// 相当于添加了<tx:annotation-driven proxy-target-class="true" /> @EnableTransactionManagement(proxyTargetClass=true) //开启事务注解驱动 @PropertySource("classpath:jdbc.properties") @ComponentScan("cn.yunhe") @Configuration public class SpringConfig { //读取外部数据库配置 @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; //配置数据源(使用setter注入) @Bean public DruidDataSource dataSource(){ DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driver); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } //配置JdbcTemplate(有参构造注入) @Bean public JdbcTemplate jdbcTemplate(){ return new JdbcTemplate(dataSource()); } //配置事务管理器(有参构造注入) @Bean public DataSourceTransactionManager transactionManager(){ return new DataSourceTransactionManager(dataSource()); } }
完善实现类
加入声明式事务
在测试类中
@RunWith(SpringRunner.class) 读取配置类中属性 @ContextConfiguration(classes = SpringConfig.class)