Spring事务和AOP

数据库驱动


所需jar包:
spring-tx-5.2.3.RELEASE
mysql-connector-java-8.0.11.jar
commons-dbcp.jar
commons-pool.jar
aopalliance-1.0.jar
spring-jdbc-5.2.3.RELEASE.jar


applicationContext:

<!-- 配置数据库相关 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName"  value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/123?8useSSL=FALSE&amp;&amp;serverTimezone=GMT"/>
    <property name="username"  value="root"/>
    <property name="password" value="932567"/>
</bean>

<!-- 配置事务管理器txManager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
<!-- 增加对事物的支持 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

头文件增加:
xmlns:tx = “http://www.springframework.org/schema/tx”

核心就是增加对事物的支持,其他为配置


将一个方法定义为事务:@Transactional
其中readOnly表示是否只可读


AOP:面向方面(切面)

切面:指要插入进去的方法(通知)
切入点,指插进去的位置,如在add()加方法,则add()为切入点
业务类、事务类:即切入点,需添加到bean容器
通知类:可继承接口,可注解

类-> 通知

通知类型 接口 方法 时机
前置 MethodBeforeAdvice before() 目标方法执行前
后置 AfterReturningAdvice afterReturning() 目标方法执行后
异常 ThrowsAdvice - 目标方法异常时
环绕 MethodInterceptor invoke() 整个过程
  1. 所需jar包
    aspectjweaver.jar
    aopalliance-1.0.jar

  2. 配置(applicationContext)

<!-- 线的另一头 -->
<bean id="logBefore" class="org.aop.LogBefore"/>
<!-- 将addStudent和通知连接 -->
<aop:config>
    <!-- 线的一头 -->
    <aop:pointcut id="pointcut"
                  expression="execution(public void org.service.impl.StudentServiceImpl.addStudent(org.entity.Student))"/>
    <!-- 连接线 -->
    <aop:advisor advice-ref="logBefore" pointcut-ref="pointcut"/>
</aop:config>

其中,execution括号内写法如下:

举例(两点间没空格) 含义(所有∗均为*)
public int add(org.man) 所有int,参为man的add()方法
public void org.service.manService.add(org.man) 只在org.service.manService类中
public * add(org.man) 任意返回类型
public void *(org.man) 任意方法名
public void add(. . ) 任意参数列表
∗org.service.*.∗ (. .) org.service包中所有类所有方法(不包含子包)
* org.service. .*.∗ (. .) org.service包中所有类所有方法(不包含子包)

若有多个,则分号内 or execution()

扫描二维码关注公众号,回复: 10606794 查看本文章

通知方法中的对象:
method:切入点方法
args:切入方法的参数
target:调用切入方法的对象
returnValue:返回值

异常通知:
在ThrowsAdvice中必须自己写以下方法(约定)
public void afterThrowing(Method method,Object[] args, Object target, Throwable ex)

环绕通知


拥有该方法一切控制权,类编写如下

/**
 * 1 可获得所有如target等对象
 * 2 invocation.proceed() = 执行add()方法 ,即切入点方法
 * 3 若不执行 2 语句,则add()方法不执行
 * 4 假如在该方法返回"abc" 则不管实际结果如何add()方法拿到"abc"
 */
public class LogAround implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object returnValue = null;
        try{
            Object target = invocation.getThis();
            Method method = invocation.getMethod();
            Object[] args = invocation.getArguments();
            System.out.println("环绕前置方法...");
            returnValue = invocation.proceed();
            System.out.println("环绕后置方法...");
        }catch(Exception e){
            System.out.println("环绕异常方法...");
            e.printStackTrace();
        }

        return returnValue;
    }


注解:

  1. 所需jar包相同
  2. 配置文件需添加 < aop:aspectj-autoproxy/ >
    此话可扫描aop注解
  3. 代码展示:
/*
@AfterThrowing("execution(public * addStudent(..))") 异常
@Before("execution(public * addStudent(..))")  前置
@After("execution(public * addStudent(..))") 最后
后置returning中为参数名
 */
 
@AfterReturning(pointcut = "execution(public * addStudent(..))" , returning = "returnValue")
public void myAfter(JoinPoint joinPoint, Object returnValue){
    System.out.println("---注解形式-后置通知----");
}

//环绕
@Around("execution(public * addStudent(..))")
public Object myAround(ProceedingJoinPoint jp){
    jp.getTarget();//目标对象
    jp.getArgs();//参数
    jp.getSignature();//方法
    Object returnValue = null;
    try{
        returnValue = jp.proceed();
    }catch (Throwable e){
        e.printStackTrace();
    }
    finally {
        System.out.println("!!最后....");
    }
    return returnValue;
}

不用再配置连接桥,可直接使用



配置形式Scheme

  1. jar包同
  2. 配置同接口形式
  3. 代码展示
<!-- Scheme形式 -->
<aop:config>
    <aop:pointcut id="pointcut5" expression="execution(public * addStudent(..)) )"/>
    <!-- 配置方法和所在类 -->
    <aop:aspect ref="logScheme">
        <!-- 连接线,连接 业务addStudent() 和 通知 -->
        <aop:after-returning method="myAfter"  returning="returnValue" pointcut-ref="pointcut5"/>
        <!-- 若异常,则有throwing="e" -->
    </aop:aspect>
</aop:config>
@Component("logScheme")
public class LogSchema {
    public void myAfter(JoinPoint joinPoint, Object returnValue){
        System.out.println("---Schema形式-后置通知----");
    }
}
发布了45 篇原创文章 · 获赞 1 · 访问量 560

猜你喜欢

转载自blog.csdn.net/BNMZY/article/details/104659158