数据库驱动
所需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&&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() | 整个过程 |
-
所需jar包
aspectjweaver.jar
aopalliance-1.0.jar -
配置(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;
}
注解:
- 所需jar包相同
- 配置文件需添加 < aop:aspectj-autoproxy/ >
此话可扫描aop注解 - 代码展示:
/*
@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
- jar包同
- 配置同接口形式
- 代码展示
<!-- 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形式-后置通知----");
}
}