目录
事务实现类(PlatformTransactionManager接口)
IOC控制反转
#白话:
- Spring容器在内部封装对象,省去get、set、构造方法人力写封装代码,引用封装对象
- IOC容器底层就是对象工厂
IOC实现类
- ClassPathXmlApplicationContext //xml配置文件
- FileSystemXmlApplicationContext //文件路径全限定名
- AnnotationConfigApplicattionContext //配置类
DI依赖注入
XML配置文件
bean对象创建
- bean标签 ,自定义id值,对应全限定类名class值
- 对象属性设置
- set方法注入属性
- property标签 ,属性名name值,ref值为外部引入bean标签
- property标签 ,属性名name值(对象属性需要存在set方法),value值
- 集合属性注入
-
<property name="属性名"> <array> <value>注入值</value> </array> </property> <property name="属性名"> <list> <value>注入值</value> </list> </property> <property name="属性名"> <map> <entry key="键名" value="值"></entry> </map> </property> <property name="属性名"> <set> <value>注入值</value> </set> </property> <!--集合属性注入对象类型值--> <property name="集合属性名"> <list> <ref bean="#{id}"> </list> </property> <!--集合值提取注入集合--> <!--引入新命名空间util--> <util:list id="集合ID"> <value>属性值</value> </util:list> <bean id=" " class="类全路径"> <property name="集合属性" ref="集合ID"></property> </bean>
-
- 集合属性注入
- 有参构造方法注入属性
- constructor-arg标签,属性名name值,value值
- set方法注入属性
p命名空间引入(简化xml配置文件)
xmlns:p="http://www.springframework.org/schema/p"
<bean id=" “ class=” “ p:name=" "></bean>
bean的作用域(scope属性)
-
单例singletion //只创建一次对象,在加载配置文件时创建
-
多例prototype //每次使用getBean方法,就创建一次对象
bean的返回类型更改
-
创建新类,继承FactoryBean接口(类的泛型<T>),重写接口的方法
bean自动装配(autowire属性)
- byName:根据属性名称注入
- byType:根据属性类型注入
- bean的创建对象id值必须唯一,否则会报错
外部配置文件引入(数据库连接)
- 引入新命名空间context
- 引入.properties数据库配置文件
<context:property-placeholder location="名称.properties" />
- 配置数据库连接池
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<porperty name="driverClassName" value="${prop.driverClassName}"></property>
<porperty name="url" value="${prop.url}"></property>
<porperty name="username" value="${prop.username}"></property>
<porperty name="password" value="${prop.password}"></property>
</bean>
注解方式
4个注解
- @Component //普通注解
- @Service //Service层/业务逻辑层
- @Controller //web层
- @Repository //Dao/持久层
注解使用
- 导入jar包(aop.jar)
- 引入 命名空间context,开启注解组件扫描
<contexxt:component-scan base-packages="包名全路径" ></context:component-scan>
- 创建类,方法上面添加对应注解
- 注解的值可以省略,默认是类名,且首字母小写
属性注入
- @Autowired //根据属性名称注入
- @Qualifier //根据属性类型注入,与@Autowired联用
- @Resource //既可以根据属性名称,也可以根据属性类型注入,java自带的方法
- @value //普通注入
完全注解开发(配置类)
- 创建类,添加注解,替换xml配置文件
@Configuration
@ComponentScan(basePackage="包名路径")
public class SpringConfig{}
- 属性注入使用自动装配
- @Autowired/@Qualifier/@Resource/@Value
- 实现方法
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
AOP面向切面编程
#白话
在不更改原有功能模块代码的前提下,实现添加新的功能模块
AOP术语
- 连接点
- 类中可以被增强的方法
- 切入点
- 实际增强的方法
- 通知(增强)
- 实现业务逻辑的部分
- 通知类型
- 前置通知(被增强方法执行之前通知)
- 后置通知(被增强方法执行之后通知,出现异常时不在通知)
- 环绕通知(被增强方法执行之前和之后都通知)
- 异常通知(被增强方法出现异常时通知)
- 最终通知(被增强方法无论执行完毕,还是出现异常都通知)
- 切面
- 把通知应用到切入点的过程
AspectJ
Spring框架基于AspectJ实现AOP操作,AspectJ不是Spring框架组成部分,独立存在,一般Spring框架进行AOP操作,需要与AspectJ联用
切入点表达式
语法结构:execution([权限修饰符][返回类型][类全限定名][方法名]([参数列表]))
-
类名、方法名:可以使用 “ * ”代替,表示包下所有类、方法的都可以被增强
-
参数列表: ”..“,表示参数值
实现AOP操作
XML配置文件
- 创建增强类、被增强类,创建方法
- xml配置文件,创建增强类对象、被增强类对象(bean标签)
- 配置切入点和连接点
<aop:config>
<!--切入点-->
<aop:pointcut id="pcut" expression="被增强类切入点表达式" />
<!--切面-->
<aop:aspect ref="增强类id">
<aop:before method="增强类方法名" pointcut-ref="pcut" >
</aop:aspect>
</aop:config>
注解方式
- 引入命名空间aop、context
- 开启生成代理对象,开启注解组件扫描
<context:component-scan base-packages="包的路径"></context:component-scan>
<!--开启生成代理对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
- 创建增强类、被增强类,创建方法
- 增强类上面添加注解@Aspect,生成代理对象
- 增强方法添加通知类型注解
- @Before //前置通知
- @After //最终通知
- @AfterReturning //后置通知
- @AfterThrowing //异常通知
- @Around //环绕通知,一般不用
//环绕通知
public void around(ProceedingJoinPoint proceedingJoinPoint ) throws Throwable{
System.out.println("之前。。。。");
//被增强的方法执行
proceedingJoinPoint.proceed();
System.out.println("之后。。。。");
}
-
同一个切入点表达式抽取
@Pointcut(value="execution(* com.atguigu.spring5.aopanno.User.add(..))");
public void pointDemo(){ }
//通知类型注解
@Before(value="pointDemo()")
增强优先级
- 同一个方法被多个增强类增强,设置添加优先级
- @Order(数字类型值) //数字越小,优先级越高
完全注解开发
- 创建配置类
@Configuration
@ComponentScan(basePackage="包路径") //注解扫描功能
@EnableAspectJAutoProxy(proxyTargetClass=true) //开启生成代理对象
public class SpringConfig{}
- 创建增强类、被增强类,创建方法
- 增强方法添加通知类型注解
JdbcTemplate技术
XML配置
- 数据库连接池
<bean id="dataSource" class="com.alibaba.Druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/DB"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
- 创建JdbcTemplate对象 ,注入dataSource
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
- 持久层注入JdbcTtemplate对象,set方法注入
注解方式
- 配置类
@Configuration
@ComponentScan(basePacckage="包路径")
public class SpringConfig{
@Bean
public DruidDataSource getDruidDataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSourcce.setDriverClassName("com.mysql.jdbc.Driver");
dataSourcce.setUrl("jdbc:mysql://localhost:3306/DB");
dataSourcce.setUsername("root");
dataSourcce.setPaawword("root");
return dataSource;
}
}
-
持久层注入JdbcTtemplate对象
public class Dao{
@Autowired
private JdbcTemplate jdcTemplate;
}
事务
事务特性(ACID)
- 原子性
- 一致性
- 隔离性
- 持久性
事务管理
事务一般添加在业务逻辑层(service层)
操作方式
- 编程式事务管理(按事务管理的逻辑写实现代码)
- 声明式事务管理(使用)
- 底层使用AOP原理
事务实现类(PlatformTransactionManager接口)
- DataSourceTransactionManager //mybatis、jdbc
- HibernateTransactionManager //Hibernate
声明式事务管理
XML配置
- 配置事务管理器
<!--创建事务管理器-->
<bean id="dataSource" class="org.springframework.jdbc.dataSource.DataSourceTransactionmanager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource">
</bean>
- 配置通知
<tx:advice id="advice">
<!--配置事务参数-->
<tx:attributes>
<!--指定哪个方法添加事务-->
<tx:method name="添加事务类中的方法名" propagation="传播行为值" />
</tx:attributes>
</tx:advice>
- 配置切入点和切面
<aop:config>
<!--切入点-->
<aop:pointcut id="pcut" expression="切入点表达式" />
<!--切面-->
<aop:advisor advice-ref="advice" pointcut-ref="pcut" ></aop:advisor>
</aop:config>
注解方式
- 配置事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.dataSource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
- 引入命名空间tx
- 开启事务注解
<tx:annotation-driven transaction-manager="transactionmanager"></tx:annotation-driven>
- 业务逻辑层添加事务注解@Transactional
- 添加在类上,所有方法都开启事务
- 添加在方法上,只有当前方法开启事务
事务参数
- propagation(事务传播行为)
- REQUIRED(默认)
- 当前方法中存在事务,调用另一个方法也会使用当前方法中的事务
- 当前方法中不存在事务,调用另一个方法后会创建新事务
- REQUIRED_NEW
- 当前方法调用另一个方法,不论当前方法中是否存在事务,都会创建新的事务
- SUPPORTS
- NOT_SUPPORTED
- MANDATORY
- NEVER
- NESTED
- REQUIRED(默认)
- isolation(隔离级别)
- 多事务操作之间不会影响
- 存在3个问题
- 脏读
- 一个未提交事务读取到另一个未提交事务的数据
- 不可重复读
- 一个未提交事务读取到另一个已提交事务修改的数据
- 幻读
- 一个未提交事务读取到另一个已提交事务添加的数据
- 脏读
- 解决读的问题:默认隔离级别->REPEATABLE_READ(可重复读)
- timeout(超时时间)
- 事务提交时间,超时事务回滚
- 默认值-1,以秒为单位
- readOnly(是否只读)
- 默认值false,可查询可修改
- true,只查询
- rollbackFor(回滚)
- 设置异常触发回滚
- noRollbackFor(不回滚)
- 设置异常触发不回滚
完全注解开发
- 配置类
@Configuration //配置类
@ComponentScan(basePackage="包路径") //开启注解扫描组件
@EnableTransactionManagement //开启事务管理器
public class SpringConfig{
//创建数据库连接池
@Bean
public DruidDataSource getDruidDataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/DB");
dataSource.setUsername("root");
dataSource.setPassword("root");
return dataSource;
}
//创建JdbcTemplate对象
@Bean
public JdbcTemplate getJdbcTemplate(DataSource dataSource){
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
//创建TransactionManager事务管理器
@Bean
public DataSourceTransactonManager getDataSourceTransactionManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
- 业务逻辑层添加事务注解@Transactional