spring(aop-事务)

#AOP(面象切面编程,是oop的扩展和衍生)
* aop:是横向抽取机制取代了传统的纵行继承
* aop:可以用于权限的校验,日志的监控deng。

#Spring的AOP底层实现原理
* jdk的动态代理(通过目标类实现了接口,使用jdk的动态代理)

	*cglib的代理方式(目标类没有实现接口,使用cglib的代理)

#Spring的AOP开发
* AOP思想最早有AOP联盟组织提供
* Spring的AOP有自己的实现方式(比较繁琐),于是Spring借用 AspectJ作为自生的AOP的开发。
* Spring有两套AOP(一套是自己的AOP,另一套是AspectJ的AOP)
AspectJ的AOP使用较多。
#Spring中aop的术语
* Joinpoint:连接点,可以被拦截的点(可以被增强的点)
* Pointcut:切入点,实际被拦截的点
* Advice:通知,增强(方法层面的增强,在方法时加强,例如在登入方法之前,要实现权限校验的方法)
* Introduction:引介.(类层面的增强)
* target:被增强的对象()
* Weaving:织入
* Proxy:代理对象
* Aspect:切面,由多个通知和切入点组合
* [外链图片转存失败(img-C41jYx5S-1566801164230)(https://i.imgur.com/NLHC6Zh.png)]
#Aop开发的入门
* eg:在执行删除之前进行权限的校验

* 要增强的方法的申明(chechPri())
	* public class StudentAspectXml {

	    public void chechPri() {
	        System.out.println("权限的校验");
	    }
	}

* 将切面类交给Spring管理
	*<bean id="studentAspect" class="com.echo.Proxy.StudentAspectXml"/>

* 切面的引入
  <!--切面的引入-->
<aop:config>
    <!--表示那个方法要增强-->
    <aop:pointcut id="pointcut1" expression="execution(* com.echo.daoimpl.StudentDaoImpl.delete(..))"/>
    <!--切面编程,指定要插入的方法-->
    <aop:aspect ref="studentAspect">
        <!--check方法时在save()方法之前执行-->
        <aop:before method="chechPri" pointcut-ref="pointcut1"/>
    </aop:aspect>
</aop:config>

#AOP通知的类型
* 前置 <aop:before />(可以获得切入点的信息JoinPoint)
*
<aop:before method=“chechPri” pointcut-ref=“pointcut1”/>

	*对应的增强方法: public void chechPri(JoinPoint joinPoint) {
  	 				 System.out.println("权限的校验" + joinPoint);
					}

*后置<aop:after-returning/>
	*  <aop:after-returning method=" writelog" pointcut-ref="pointcut2"  	returning="result"/>
	*  
	* public void writelog(Object result) {  //returning的结果值要和 方法的参数名	同
  	 	 System.out.println("这时删除后的通知");
		 }

*环绕<aop:around/>在之前和之后都会执行
	* <aop:around method="around" pointcut-ref="pointcut3"/>
	* 
*异常 <aop:after-throwing> throwing中的指对应加强方法的参数ex
	*  <aop:after-throwing method="afterThrow" pointcut-ref="pointcut4" 	throwing="ex"/>
	*  
*最终通知 <aop:after/>
	*  <aop:after method=" after" pointcut-ref="pointcut4"/>-->

#spring的切入点表达式的写法
* 基于executin的函数完成的
* 语法
* 访问修饰符 返回类型 包名.类名.方法名(参数名)
* eg:public void com.echo.Dao.StudentDao.save(…)
* public 可以不写 ,* 可以代表任意的返回类型,参数名用…表示
* execution(* com.echo.daoimpl.StudentDaoImpl.add(…))
* com.echo.daoimpl.StudentDaoImpl+.add(…) //+代表当前和其子类中的add(…)

	![](https://i.imgur.com/dfmwD1O.png)

#Spring的注解AOP开发
* 切入点的注解(将切入点注解放在一个方法上,在调用具体的增强方法时用类.方法名引入 切入点value = “StudentAspect.Pointcout1()”)

	*//环绕增强
    @Around(value = "StudentAspect.Pointcout1()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕加强前");
        Object object = joinPoint.proceed();//执行upadate()方法
        System.out.println("环绕加强后");
        return object;
    } 

	*  // 切入点注解:
    @Pointcut(value ="execution(* com.echo.daoImpl.StudentDaoImpl.update(..))")
    public void Pointcout1(){}

#jdbc模板保存数据
* @Test
public void jdbcTemplate() {
//连接池
DriverManagerDataSource dataSource = new DriverManagerDataSource();
//加载驱动
dataSource.setDriverClassName(“com.mysql.jdbc.Driver”);
dataSource.setUrl(“jdbc:mysql:///mybatis”);
dataSource.setUsername(“root”);
dataSource.setPassword(“123456”);
//创建jdbc模板
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = “insert into course values(?,?,?,?)”;
jdbcTemplate.update(sql, “C007”, “java”, “c002”, 90);
}

* 将连接池和模板交给Spring管理
	* <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///mybatis"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    <!--jdbc的模板-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>
* 测试方法
	* @Resource(name = "jdbcTemplate")
    private JdbcTemplate jdbcTemplate;

    @Test
    public void test() {
        //String sql = "insert into course values(?,?,?,?)";
        String sql = "delete from course where Cno=?";
        jdbcTemplate.update(sql, "C009");
    }

#dbcp连接池(BasicDataSource)
*





*抽取配置到属性文件
*jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///mybatis
jdbc.username=root
jdbc.password=123456
*在spring的配置文件中配置
*
<context:property-placeholder location=“classpath:jdbc.properties”/>
* 引入属性文件的值
*





#事务管理
* 什么时事务:逻辑上的一组操作,组成这个操作的单元,要么都成功,要么都失败
*事务的特性
* 原子性:事务不可分给
* 一致性:事务执行前后的数据保持一致
* 隔离性:一个事务的执行不应该受到其它事务的干扰
* 持久性:一旦事务结束,数据就持久化到数据库
* 如果不考虑隔离性引发安全性问题
*读问题
*脏读:一个事务读到另一个事务未提交的数据
*不可重复读:一个事务读到另一个事务已经提交的update
的数据,导致一个事务中多次查询结果不一致
*虚读、幻读:一个事务读到另一个事务已经提交的insert的数据,导致一个事务中多次查询结果不一致。
*写问题
*丢失更新
* 解决读问题
*设置事务的隔离级别
*Read uncommitted:未提交读,任何读问题解决不了。
*Read committed :已提交读,解决脏读,但是不可重复读和虚读有可 能发生。
*Repeatable read:重复读,解决脏读和不可重复读,但是虚读有可能发生。
*Serializable:解决所有读问题。

#spring的事务管理的
# 声明式事务管理
* 声明事务管理器(要引入数据源datasource)



* 配置事务的通知,增强(对transfer()进行增强)

<tx:advice id=“txadvice” transaction-manager=“transaction”>

	        <tx:attributes>
	            <tx:method name="transfer" propagation="REQUIRED"/>
	        </tx:attributes>
	    </tx:advice>
*引入aop事务
	 <!--aop的配置-->

    <aop:config>
        <aop:pointcut id="poincut1" expression="execution(* com.echo.serviceImpl.AccountServiceImpl.transfer(..))"/>
        <aop:advisor advice-ref="txadvice" pointcut-ref="poincut1"/>
    </aop:config>
#注解式的事务管理
	* 声明事务管理器(引入数据源datasource)
	 <bean id="transaction" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
   	 <property name="dataSource" ref="dataSource"/>
	</bean>
   * 开启事务管理的注解开发
   	  <!--事务管理的注解-->
	<tx:annotation-driven transaction-manager="transaction"/>
   * 在要使用事务管理的类上加上注解
	   *@Transactional(isolation = Isolation.DEFAULT, propagation = 	Propagation.REQUIRED)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值